1
votes

working on square detection. the problem is on the radiant floor. as you can see pictures. any idea for solve this problem ?

thank you.

source image :

output :

source code:

void EdgeDetection::find_squares(const cv::Mat& image, vector >& squares,cv::Mat& outputFrame) {

unsigned long imageSize = (long) (image.rows * image.cols) / 1000;
if  (imageSize > 1200) RESIZE = 9;
else if  (imageSize > 600) RESIZE = 5;
else if  (imageSize > 300) RESIZE = 3;
else RESIZE = 1;


Mat src(Size(image.cols / RESIZE, image.rows / RESIZE),CV_YUV420sp2BGR);
// Resize src to img size
resize(image, src, src.size() ,0.5, 0.5, INTER_LINEAR);

Mat imgeorj=image; const int N = 10;//11; Mat pyr, timg, gray0(src.size(), CV_8U), gray;

// down-scale and upscale the image to filter out the noise
pyrDown(src, pyr, Size(src.cols / 2, src.rows / 2));
pyrUp(pyr, timg, src.size());

#ifdef blured

Mat blurred(src);
medianBlur(src, blurred, 15);

#endif

vector<vector<Point> > contours;

// find squares in every color plane of the image
for ( int c = 0; c < 3; ++c) {
    int ch[] = {c, 0};
    mixChannels(&timg, 1, &gray0, 1, ch, 1);

    // try several threshold levels
    for ( int l = 0; l < N; ++l) {
        // hack: use Canny instead of zero threshold level.
        // Canny helps to catch squares with gradient shading
        if (l == 0) {
            // apply Canny. Take the upper threshold from slider
            // and set the lower to 0 (which forces edges merging)
            // Canny(gray0, gray, 0, thresh, 5);
            // Canny(gray0, gray, (10+l), (10+l)*3, 3);
            Canny(gray0, gray,50, 200, 3 );
            // dilate canny output to remove potential
            // holes between edge segments
            dilate(gray, gray, Mat(), Point(-1, -1));
            //erode(gray, gray, Mat(), Point(-1, -1), 1);
        } else {
            // apply threshold if l!=0:
            // tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0
            gray = gray0 >= (l + 1) * 255 / N;
        }


        // find contours and store them all as a list
        findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

        vector<Point> approx;

        // test each contour
        for (size_t i = 0; i < contours.size(); ++i) {
            // approximate contour with accuracy proportional
            // to the contour perimeter

            approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true) * 0.02, true);


            if (approx.size() == 4 &&
                fabs(contourArea(Mat(approx))) > 5000 &&
                isContourConvex(Mat(approx))) {
                float maxCosine = 0;

                for (register int j = 2; j < 5; ++j) {
                    // find the maximum cosine of the angle between joint edges
                    float cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
                    maxCosine = MAX(maxCosine, cosine);
                }

                // if cosines of all angles are small
                // (all angles are ~90 degree) then write quandrange
                // vertices to resultant sequence
                if (maxCosine < 0.3) {
                    squares.push_back(approx);
                }

            }
        }

    }
}

debugSquares(squares, imgeorj,outputFrame);
}
1

1 Answers

0
votes

You can try using Hough transform for detecting straight edges and use the those for constructing the square.