Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find corner of papers

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

like image 986
QueueOverFlow Avatar asked Nov 23 '12 06:11

QueueOverFlow


1 Answers

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];
}
like image 55
karlphillip Avatar answered Nov 07 '22 23:11

karlphillip