Ask Your Question
1

Detect rectangular using Hough Transform

asked 2013-11-06 03:33:37 -0600

andrei.cacio gravatar image

I am trying to detect the biggest rectangulare shape in the image (TV screen detection) but first I want to detect all rectangular shapes using Hough Lines (findCounturs didn't work so well for my case). I've managed to extract HoughLines and all of the corners, but how can I extract rectangulars from this? (I'm new to OpenCV and I want to learn)

here is my code:

        Mat src = imread("image.jpg"):
        cv::Mat bw;
        src.copyTo(bw);
        cv::cvtColor(src, bw, CV_BGR2GRAY);
        cv::blur(bw, bw, cv::Size(3, 3));
        cv::Canny(bw, bw, 100, 100, 3);

        std::vector<cv::Vec4i> lines;
        cv::HoughLinesP(bw, lines, 1, CV_PI/180, 70, 30, 10);

        // Expand the lines
        for (int i = 0; i < lines.size(); i++)
        {
                cv::Vec4i v = lines[i];
                lines[i][0] = 0;
                lines[i][1] = ((float)v[1] - v[3]) / (v[0] - v[2]) * -v[0] + v[1]; 
                lines[i][2] = src.cols; 
                lines[i][3] = ((float)v[1] - v[3]) / (v[0] - v[2]) * (src.cols - v[2]) + v[3];
        }

        std::vector<cv::Point2f> corners;
        for (int i = 0; i < lines.size(); i++)
        {
                for (int j = i+1; j < lines.size(); j++)
                {
                        cv::Point2f pt = computeIntersect(lines[i], lines[j]);
                        if (pt.x >= 0 && pt.y >= 0)
                                corners.push_back(pt);
                }
        }

and the used function above:

Point2f computeIntersect(cv::Vec4i a, 
                             cv::Vec4i b)
{
        int x1 = a[0], y1 = a[1], x2 = a[2], y2 = a[3], x3 = b[0], y3 = b[1], x4 = b[2], y4 = b[3];
        float denom;

        if (float d = ((float)(x1 - x2) * (y3 - y4)) - ((y1 - y2) * (x3 - x4)))
        {
                cv::Point2f pt;
                pt.x = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / d;
                pt.y = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / d;
                return pt;
        }
        else
                return cv::Point2f(-1, -1);
}
edit retag flag offensive close merge delete

Comments

I don't know how to detect rectangle by houghLines, but I know how to detect retangle b findContour--http://opencv-code.com/tutorials/detecting-simple-shapes-in-an-image/ . hope this link could help you

stereomatching gravatar imagestereomatching ( 2013-11-06 06:26:32 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
2

answered 2013-11-06 13:25:37 -0600

Guanta gravatar image

I guess you followed the tutorial from http://opencv-code.com/tutorials/automatic-perspective-correction-for-quadrilateral-objects/ . So now, the vertex-points define your rectangular. However, I guess you don't need to apply any perspective transformation (or do you?), thus, you can use the points to get your region of interest, i.e. determine the top left and bottom right vertices from the four ones and use it to define your region of interest (either via cv::Rect or cv::Range).

Or did I misunderstand you and you just want to draw it? Then you can use the cv::rectangle() function (see http://docs.opencv.org/modules/core/doc/drawing_functions.html?highlight=cv2.rectangle#rectangle)

edit flag offensive delete link more

Comments

practically I want to detect a TV screen which is basically a rectangular. The problem is that I don't know how to pick the right points that describe the region I want. In theory should I verify every point with every point to get the biggest rectangular? (I guess that should be the TV screen). and yeah I just want to draw it so I can see if it works, and then I will use that region of interest for further processing.

andrei.cacio gravatar imageandrei.cacio ( 2013-11-07 02:00:46 -0600 )edit

Ah, I see. Yes, if you get more than the 4 lines from your screen you need to prune the results to the ones you are interested int. You can play around with the thresholds of HoughLinesP, e.g. to get only the longest/strongest lines or you filter the intersection points in the way you suggested by taking the most extreme ones.

Guanta gravatar imageGuanta ( 2013-11-07 03:36:33 -0600 )edit

Question Tools

Stats

Asked: 2013-11-06 03:33:37 -0600

Seen: 28,018 times

Last updated: Nov 06 '13