Domanda

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,

È stato utile?

Soluzione

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.

Altri suggerimenti

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top