2016-03-11 88 views
2

我有一个问题,我无法解决。我正在使用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正在绘制太多的轮廓。但我只需要一个特定的部分。我的差异图像是here

我想绘制一个矩形围绕所有五个拨号。

请指点我正确的方向。

Regards,

回答

2

您可以:

  1. 值化利用阈值的图像。背景将为0.
  2. 使用findNonZero检索所有不是0的点,即所有前景点。
  3. 在检索到的点上使用boundingRect

结果:

enter image description here

代码:

#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

我会搜索i索引的最高值给非黑色像素;这是正确的边界。

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

1

查找轮廓,它将输出一组轮廓为std::vector<std::vector<cv::Point>的暂且称之为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);