【问题标题】:Drawing Rectangle around difference area在差异区域周围绘制矩形
【发布时间】:2016-03-11 21:21:31
【问题描述】:

我有一个无法解决的问题。我正在使用 OpenCV 对两张图像进行区分。我在单独的Mat 中获得输出。使用的差异方法是AbsDiff 方法。这是代码。

char imgName[15];

Mat img1 = imread(image_path1, COLOR_BGR2GRAY); 
Mat img2 = imread(image_path2, COLOR_BGR2GRAY);

/*cvtColor(img1, img1, CV_BGR2GRAY);
cvtColor(img2, img2, CV_BGR2GRAY);*/
cv::Mat diffImage;
cv::absdiff(img2, img1, diffImage);

cv::Mat foregroundMask = cv::Mat::zeros(diffImage.rows, diffImage.cols, CV_8UC3);

float threshold = 30.0f;
float dist;

for(int j=0; j<diffImage.rows; ++j)
{
    for(int i=0; i<diffImage.cols; ++i)
    {
        cv::Vec3b pix = diffImage.at<cv::Vec3b>(j,i);

        dist = (pix[0]*pix[0] + pix[1]*pix[1] + pix[2]*pix[2]);
        dist = sqrt(dist);

        if(dist>threshold)
        {
            foregroundMask.at<unsigned char>(j,i) = 255;
        }
    }
}

sprintf(imgName,"D:/outputer/d.jpg");
imwrite(imgName, diffImage);

我想将差异部分限制在一个矩形中。 findContours 正在绘制太多轮廓。但我只需要一个特定的部分。我的差异图像是

我想在所有五个表盘周围画一个矩形。

请指点我正确的方向。

问候,

【问题讨论】:

    标签: c++ opencv visual-studio-2012


    【解决方案1】:

    我会搜索 i 索引的最大值,给出非黑色像素;那是正确的边界。

    最低的非黑色 i 是左边框。 j 类似。

    【讨论】:

      【解决方案2】:

      你可以:

      1. 使用阈值对图像进行二值化。背景将为 0。
      2. 使用 findNonZero 检索所有非 0 点,即所有前景点。
      3. 在检索到的点上使用boundingRect

      结果:

      代码:

      #include <opencv2/opencv.hpp>
      using namespace cv;
      
      int main()
      {
          // Load image (grayscale)
          Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);
      
          // Binarize image
          Mat1b bin = img > 70;
      
          // Find non-black points
          vector<Point> points;
          findNonZero(bin, points);
      
          // Get bounding rect
          Rect box = boundingRect(points);
      
          // Draw (in color)
          Mat3b out;
          cvtColor(img, out, COLOR_GRAY2BGR);
          rectangle(out, box, Scalar(0,255,0), 3);
      
          // Show
          imshow("Result", out);
          waitKey();
      
          return 0;
      }
      

      【讨论】:

        【解决方案3】:

        找到轮廓,它会输出一组轮廓为std::vector&lt;std::vector&lt;cv::Point&gt;让我们称之为contours

        std::vector<cv::Point> all_points;
        size_t points_count{0};
        for(const auto& contour:contours){
            points_count+=contour.size();
            all_points.reserve(all_points);
            std::copy(contour.begin(), contour.end(),
                      std::back_inserter(all_points));
        }
        auto bounding_rectnagle=cv::boundingRect(all_points);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-07-06
          • 2022-01-09
          • 2021-12-17
          • 1970-01-01
          • 1970-01-01
          • 2023-01-30
          • 1970-01-01
          • 2018-02-12
          相关资源
          最近更新 更多