Question

I am working in C++ and opencv

I am detecting the big contour in an image because I have a black area in it.My image

In this case, the area is only horizontally, but it can be in any place.

Mat resultGray;
 cvtColor(result,resultGray, COLOR_BGR2GRAY);
 medianBlur(resultGray,resultGray,3);
 Mat resultTh;
 Mat canny_output;
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
 Canny( resultGray, canny_output, 100, 100*2, 3 );

    findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
    Vector<Point> best= contours[0];
    int max_area = -1;
    for( int i = 0; i < contours.size(); i++ ) {
            Scalar color = Scalar( 0, 0, 0 );

            if(contourArea(contours[i])> max_area)
            {
                max_area=contourArea(contours[i]);
                best=contours[i];
            }
    }
    Mat approxCurve;
    approxPolyDP(Mat(best),approxCurve,0.01*arcLength(Mat(best),true),true);

Wiht this, i have the big contour and it approximation (in approxCurve). Now, I want to obtain the corners of this approximation and get the image inside this contour, but I dont know how can I do it.

I am using this How to remove black part from the image? But the last part I dont understad very well.

Anyone knows how can I obtain the corners? It is another way more simple that this?

Thanks for your time,

Was it helpful?

Solution

One much simpler way you could do that is to check the image pixels and find the minimum/maximum coordinates of non-black pixels.

Something like this:

int maxx,maxy,minx,miny;
maxx=maxy=-std::numeric_limits<int>::max();
minx=miny=std::numeric_limits<int>::min();
for(int y=0; y<img.rows; ++y)
{
    for(int x=0; x<img.cols; ++x)
    {
        const cv::Vec3b &px = img.at<cv::Vec3b>(y,x);
        if(px(0)==0 && px(1)==0 && px(2)==0)
            continue;
        if(x<minx) minx=x;
        if(x>maxx) maxx=x;
        if(y<miny) miny=y;
        if(y>maxy) maxy=y;
    }
}
cv::Mat subimg;
img(cv::Rect(cv::Point(minx,miny),cv::Point(maxx,maxy))).copyTo(subimg);

In my opinion, this approach is more reliable since you don't have to detect any contour, which could lead to false detections depending on the input image.

OTHER TIPS

In a very efficient way, you can sample the original image until you find a pixel on, and from there move along a row and along a column to find the first (0,0,0) pixel. It will work, unless in the good part of the image you can have (0,0,0) pixels. If this is the case (e.g.: dead pixel), you can add a double check checking the neighbourhood of this (0,0,0) pixel (it should contain other (0,0,0) pixels.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top