OpenCV代码不适用于特定图像

时间:2019-08-19 16:08:18

标签: c++ opencv image-processing

我正在尝试在图像上运行以下代码(基于this page),但是不起作用:

Mat src=imread("img.jpg",1);
Mat tmp,thr;
cvtColor(src,tmp,CV_BGR2GRAY);
threshold(tmp,thr,200,255,THRESH_BINARY_INV);

vector< vector <Point> > contours;
vector< Vec4i > hierarchy;
Mat dst(src.rows,src.cols,CV_8UC1,Scalar::all(0));//Ceate Mat to draw contour

int box_w=10; // Define box width here
int box_h=10; // Define box height here
int threshold_perc=25; //perceantage value for eliminating the box according to pixel count inside the box
int threshold=(box_w*box_h*threshold_perc)/100; 

findContours( thr, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE ); //Find contour

for( int i = 0; i< contours.size(); i++ ){ 
 drawContours( dst,contours, i, Scalar(255,255,255),CV_FILLED, 8, hierarchy ); // Draw contour with  thickness = filled 
 Rect r= boundingRect(contours[i]); // Find bounding rect

// Scan the image with in bounding box  
for(int j=r.x;j<r.x+r.width;j=j+box_w){
  for(int k=r.y;k<r.y+r.height;k=k+box_h){
    Rect roi_rect(j,k,box_w,box_h);
    Mat roi = dst(roi_rect);
    int count = countNonZero(roi);
    if(count > threshold)
      rectangle(src, roi_rect, Scalar(255,0,0),1,8,0 );         
    }
  }
 }
imshow("src",src);
waitKey();

它对于任何普通图像都可以正常工作,但是对于下面的图像,它要么断裂要么找不到轮廓,并在整个图像上绘制框。

enter image description here enter image description here

它说:

  

test2.exe中0x00007FF9A72DA388处未处理的异常:Microsoft C ++异常:内存位置0x000000FECC9DEAC0处的cv :: Exception。

它中断并指向此处:

inline
Mat Mat::operator()( const Rect& roi ) const
{
    return Mat(*this, roi);
}

mat.inl.hpp 中。

我的图片怎么了?我已将其从“灰度”更改为RGB,但没有帮助。

在以下图像上,它可以正常工作: enter image description here

2 个答案:

答案 0 :(得分:1)

问题在于,在最初的图像中,轮廓接近图像的边界,而在程序的底部for loop中,轮廓超过了坐标。固定此:

// Scan the image with in bounding box  
        for (int j = r.x;j<r.x + r.width;j = j + box_w) {
            for (int k = r.y;k<r.y + r.height;k = k + box_h) {
                Rect roi_rect(j, k, box_w, box_h);
                if (j + box_w < dst.cols && k + box_h < dst.rows)
                {
                    Mat roi = dst(roi_rect);
                    int count = countNonZero(roi);
                    if (count > threshold)
                        rectangle(src, roi_rect, Scalar(0,0,255), 1, 8, 0);
                }
            }
        }

enter image description here

答案 1 :(得分:1)

正如我评论的那样,您正在尝试使用固定大小的矩形来访问不存在的图像区域。

通过将roi与矩形相交,可以避免此问题:

ONBUILD