2016-03-11 127 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);