11

I am new in openCV so struggling from last 3 to 4 days, I already detect paper sheet boundary, Now I wants to draw 4 circles on the corners.

I draw boundary from this code

const cv::Point* p = &squares[i][0];

int n = (int)squares[i].size();

polylines(image, &p,&n, 1, true, Scalar(255,255,0), 5, CV_AA);

I am new in openCV, So In my opinion I have upper left corner points p->x and p->y, But how I get the others corners, I am also confused in parameter &n in this polylines method, how this polylines method draw complete rectangle?

When I use bounding rect, It's not perfect it give's little space on side of paper sheet.

Any help is really appreciated

code is :

- (cv::Mat)finshWork:(cv::Mat &)image
{
// read in the apple (change path to the file)
Mat img0 =image;// imread("/home/philipp/img/apple.jpg", 1);

Mat img1;
cvtColor(img0, img1, CV_RGB2GRAY);

// apply your filter
Canny(img1, img1, 100, 200);

// find the contours
vector< vector<cv::Point> > contours;
findContours(img1, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);

/////for SQUARE CODE
std::vector<std::vector<cv::Point> > squares;
std::vector<cv::Point> approx;
for( size_t i = 0; i < contours.size(); i++ )
{
    cv::approxPolyDP(cv::Mat(contours[i]), approx, arcLength(cv::Mat(contours[i]), true)*0.02, true);
    if( approx.size() == 4 && fabs(contourArea(cv::Mat(approx))) > 1000 && cv::isContourConvex(cv::Mat(approx))) {
        double maxCosine = 0;

        for( int j = 2; j < 5; j++ )
        {
            double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
            maxCosine = MAX(maxCosine, cosine);
        }

        if( maxCosine < 0.3 ) {
            squares.push_back(approx);
            cv::Point newPoint = approx[0]; 

            NSLog(@"x is %d and  y is %d",newPoint.x,newPoint.y);
        }
    }
}

const cv::Point* p = &squares[0][0];


int n = (int)squares[0].size();

NSLog(@"%d",n);


//THIS IS WORKING CODE              

    polylines(image, &p,&n, 1, true, Scalar(0,0,255), 10, CV_AA);
    //polylines(image, &p,&n, 1, true, Scalar(255,255,0), 5, CV_AA);
////////////
}

Thanks

karlphillip
  • 87,606
  • 33
  • 227
  • 395
QueueOverFlow
  • 1,316
  • 4
  • 27
  • 46
  • Can you clarify how you find the paper? Optimally you should add more code. – dom Nov 23 '12 at 09:46
  • @moosgummi please check my edit, I think here i use some part of your coding from your question, thanks for share that part. – QueueOverFlow Nov 23 '12 at 10:56

1 Answers1

20

Take for reference my original code, which simply detects squares on an image.

That means that in the main method of the application you would write something like the following pseudo-code to call find_squares():

Mat image = imread("test.jpg", 1);

// Detect all regions in the image that are similar to a rectangle
vector<vector<Point> > squares;
find_squares(image, squares);

// The largest of them probably represents the paper
vector<Point> largest_square;
find_largest_square(squares, largest_square);

// Print the x,y coordinates of the square
cout << "Point 1: " << largest_square[0] << endl;
cout << "Point 2: " << largest_square[1] << endl;
cout << "Point 3: " << largest_square[2] << endl;
cout << "Point 4: " << largest_square[3] << endl;

The trick relies on find_largest_square() presented below:

void find_largest_square(const vector<vector<Point> >& squares, vector<Point>& biggest_square)
{
    if (!squares.size())
    {
            // no squares detected
            return;
    }

    int max_width = 0;
    int max_height = 0;
    int max_square_idx = 0;
    const int n_points = 4;

    for (size_t i = 0; i < squares.size(); i++)
    {
            // Convert a set of 4 unordered Points into a meaningful cv::Rect structure.
            Rect rectangle = boundingRect(Mat(squares[i]));

    //        cout << "find_largest_square: #" << i << " rectangle x:" << rectangle.x << " y:" << rectangle.y << " " << rectangle.width << "x" << rectangle.height << endl;

            // Store the index position of the biggest square found
            if ((rectangle.width >= max_width) && (rectangle.height >= max_height))
            {
                    max_width = rectangle.width;
                    max_height = rectangle.height;
                    max_square_idx = i;
            }
    }

    biggest_square = squares[max_square_idx];
}
Community
  • 1
  • 1
karlphillip
  • 87,606
  • 33
  • 227
  • 395
  • Hi how to can i detect white paper if its on white desk ?... i tried with changing gray scale & canny conversion bt m nt able find tht rectngle .... thnks :) – user1140237 Sep 17 '13 at 06:51
  • How to find corners of a rotated Rectangle(the rectangle whose sides are not parallel to coordinate axis) ? – Ankur Gautam Jan 13 '14 at 05:11
  • hello guys,I NSLog the largest_square Points ,but they are out of bounds of device .(2400,1500) are the values coming.Is there any formula to convert these cv::Point to device cordinates – Mukesh Jun 03 '15 at 10:09
  • Yes, its called Rule of Three. – karlphillip Jun 03 '15 at 12:07