• Opencv ROI<8>


    一、ROI 介绍

    1. ROI (Region of Interest) 感兴趣区域,就是从图像中选择一个图像区域,这个区域就是图像分析所关注的焦点。圈定这个区域,那么要处理的图像就从大图像变为一个小图像区域了,这样以便进行进一步处理,可以大大减小处理时间。

    2. 定义ROI方法:

    • 使用表示矩阵区域的Rect。

              它指定矩阵的左上角坐标(构造函数的前两个参数)和矩阵的长宽(构造函数的后两个参数)以定义一个矩阵区域。

               Mat imageROI;

               imageROI = image(Rect(200,200,500,500);//Rect四个形参分别是:x坐标,y坐标,长,高;注意(x,y)指的是矩形的左上角

    • 指定感兴趣行或列的范围(Range)。

              Range是指从起索引到终止索引(不包括终止索引)的一连串连续序列。cRange可以用来定义Range。如果使用Range来定义ROI,那么前例中定义ROI 的代码可以重写为:

               imageROI = image( Range(250, 250+logoImage.rows), Range(200, 200+logoImage.cols));//Range两个形参分别是:起始行或列,起始行或列+偏移量

    二、鼠标事件标注ROI区域并选择出来

             直接上程序,下面的程序,经历了一下午,跳进了大坑,始终没有发现,直至现在,感觉很搞笑有时很想往自己脸上打几下,看来代码还是的多写,学会调适。

            

             #include<opencv2/opencv.hpp>
             #include<opencv2/highgui/highgui.hpp>
             #include<iostream>
             #define WINDOW_MAIN "LOGO"
             #define WINDOW_NEW "ROI"
     using namespace cv;
    using namespace std;
    Mat srcLogo, ROIRegion,SelectLogo;
    Rect g_rectangle;
    bool g_bDrawingBox = false;
    bool g_bDrawFinished = false;
    void on_MouseHandle(int event, int x, int y, int flags, void* param);
    void DrawRectangle(Mat& img, Rect box);
    Mat srcImage(600, 800, CV_8UC3), Temp;

    void main()
    {
     srcLogo = imread("E:\欣奕华\项目\OPENCV\ROI\2.jpg", 1);
     if (srcLogo.data == NULL)
     {
      cout << "srcLogo 读取失败" << endl;
     }

     srcLogo.copyTo(Temp);
     //g_rectangle = Rect(-1, -1, 0, 0);
     //srcImage = Scalar::all(0);
     namedWindow(WINDOW_MAIN,1);
     setMouseCallback(WINDOW_MAIN, on_MouseHandle, &SelectLogo);
     while (1)
     {
      srcLogo.copyTo(SelectLogo);
      imshow(WINDOW_MAIN, SelectLogo);
      if (g_bDrawFinished == true)
      {
       DrawRectangle(SelectLogo, g_rectangle);
       ROIRegion = SelectLogo(Rect(g_rectangle.x, g_rectangle.y, g_rectangle.width, g_rectangle.height));
       imshow(WINDOW_NEW, ROIRegion);
      }
      //下面的这句话真是他妈的该死!!!!!
      int key = waitKey();
      while ((char)key == 'Q' || (char)key == 'q')
      {
       return;
      }
     }
    }
    void on_MouseHandle(int event, int x, int y, int flags, void* param)
    {
     Mat& image = *(Mat*)param;
     image = Scalar::all(0);
     switch (event)
     {
     case EVENT_LBUTTONDOWN:
     {
      g_bDrawingBox = true;
      g_bDrawFinished = false;
      g_rectangle = Rect(x, y, 0, 0);
      break;
     }
     case EVENT_MOUSEMOVE:
     {
      if (g_bDrawingBox == true)
      {
       g_rectangle.width = x - g_rectangle.x;
       g_rectangle.height = y - g_rectangle.y;
      }
      break;
     }
     case EVENT_LBUTTONUP:
     {
      g_bDrawingBox = false;
      g_bDrawFinished = true;
      if (g_rectangle.width < 0)
      {
       g_rectangle.x += g_rectangle.width;
       g_rectangle.width *= -1;
      }
      if (g_rectangle.height < 0)
      {
       g_rectangle.y += g_rectangle.height;
       g_rectangle.height *= -1;
      }
      DrawRectangle(image, g_rectangle);
      break;
     }
     default:
      break;
     }
    }
    void DrawRectangle(Mat& img, Rect box)
    {
     rectangle(img, box.tl(), box.br(), Scalar(255, 200, 55), 2);
    }

    三、掩码(mask)

           

    四、不规则ROI提取

    原理:先滤波-->>灰度化-->>二值化-->>边缘提取-->>寻找图像轮廓-->>轮廓画在一张空图像-->>水漫填充图像轮廓区域-->>两个图像与操作
     
     #include<iostream>
     #include <opencv2/opencv.hpp>
     #include <math.h>
     using namespace cv;
     using namespace std;
    #define WINDOWS_INPUT "输入原图"
    #define WINDOWS_BLUR  "滤波图"
    #define WINDOWS_GRAY  "灰度图"
    #define WINDOWS_THRESHOLD  "二值化图"
    #define WINDOWS_CONTOURS  "轮廓图"
     RNG rng = theRNG();
     Mat inputImage, outputImage, thresholdImage,blurImage,grayImage;
     int thredholdValue = 50;
     const int Threshold_Max_value = 255;
     const int Threshold_type_value = 3;
     double g_Area = 0;
     int MaxareaCount = 0;
     void Threshold_Image_Bar(int, void *);
     void main()
     {
      inputImage = imread("E:\欣奕华\项目\OPENCV\ROI\NonRegionRIO\1.jpg", 1);
      if (inputImage.data == NULL)
      {
       cout << "inputImage 读取错误" << endl;
      }
      namedWindow(WINDOWS_INPUT, 1);
      imshow(WINDOWS_INPUT, inputImage);
      //1. 滤波
      blur(inputImage, blurImage, Size(3, 3), Point(-1, -1),4);
      namedWindow(WINDOWS_BLUR, 1);
      imshow(WINDOWS_BLUR, blurImage);
      //2. 灰度图
      cvtColor(blurImage, grayImage, COLOR_BGR2GRAY);
      namedWindow(WINDOWS_GRAY, 1);
      imshow(WINDOWS_GRAY, grayImage);
      //3.二值化
      namedWindow(WINDOWS_THRESHOLD, 1);
      createTrackbar("阈值调整", WINDOWS_THRESHOLD, &thredholdValue, Threshold_Max_value, Threshold_Image_Bar);
      Threshold_Image_Bar(0, 0);
      //namedWindow(WINDOWS_THRESHOLD, 1);
     // imshow(WINDOWS_THRESHOLD, thresholdImage);
      waitKey(0);
     }
     void Threshold_Image_Bar(int, void *)
     {
      //二值化处理,支持就地处理
      threshold(grayImage, thresholdImage, 90, 255,THRESH_TOZERO);
      //边缘检测,支持就地处理
      Canny(thresholdImage, thresholdImage, thredholdValue, thredholdValue * 3, Threshold_type_value);
      namedWindow(WINDOWS_THRESHOLD, 1);
      imshow(WINDOWS_THRESHOLD, thresholdImage);
      //寻找,绘制轮廓
      vector<vector<Point>> contours;
      vector<Vec4i> hireachy;
      findContours(thresholdImage, contours, hireachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(-1, -1));
      Mat Show_threImage = Mat::zeros(thresholdImage.size(), CV_8UC3);
      RotatedRect rotateRect;
      for (int i = 0; i < contours.size(); i++)
      {
       Scalar Color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255));
       drawContours(Show_threImage, contours, i, Color, 1, 8, hireachy, 0, Point());
       //利用面积寻找最大区域
       double area = contourArea(contours[i]);
       g_Area = g_Area > area ? g_Area : area;
       MaxareaCount = (g_Area == area) ? i : MaxareaCount;
      }
      namedWindow(WINDOWS_CONTOURS, 1);
      imshow(WINDOWS_CONTOURS, Show_threImage);
      //空白图像画轮廓:
      Mat gray, Change_image = Mat::zeros(inputImage.size(), inputImage.type());
      gray.create(inputImage.size(), inputImage.type());
      drawContours(gray, contours, MaxareaCount, Scalar(255, 255, 255), 2, 8, hireachy, 0, Point());
      Rect s = boundingRect(contours[MaxareaCount]);//为了找内部的一个种子点,自己随便定义也可以
      //水漫之后的图像:
      floodFill(gray, Point(s.x + s.width / 2, s.y + s.height / 2), Scalar(255, 255, 255));//黑色区域变成白色,遇到白色区域停止
      imshow("123", gray);
      bitwise_and(inputImage, gray, gray);
       //  imshow("wjy", gray);
     
     }
  • 相关阅读:
    [Nowcoder] 寻找子串
    [LeetCode] Generate Parentheses
    [Nowcoder] 字符串是否由字串拼接
    ananconda3中QTDesigner无法输入中文
    [Paddle学习笔记][13][基于YOLOv3的昆虫检测-测试模型]
    [Paddle学习笔记][12][基于YOLOv3的昆虫检测-模型预测]
    [Paddle学习笔记][11][基于YOLOv3的昆虫检测-训练模型]
    [Paddle学习笔记][10][基于YOLOv3的昆虫检测-损失函数]
    [Paddle学习笔记][09][基于YOLOv3的昆虫检测-模型设计]
    [Paddle学习笔记][08][基于YOLOv3的昆虫检测-数据处理]
  • 原文地址:https://www.cnblogs.com/xingyuanzier/p/11632821.html
Copyright © 2020-2023  润新知