# Getting picture contours

I'm trying to extract the following image, and do perspective correction but its not working as expected.

here is my full code

#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>

using namespace cv;
using namespace std;
double angle(cv::Point pt1, cv::Point pt2, cv::Point pt0) {
double dx1 = pt1.x - pt0.x;
double dy1 = pt1.y - pt0.y;
double dx2 = pt2.x - pt0.x;
double dy2 = pt2.y - pt0.y;
return (dx1*dx2 + dy1*dy2) / sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
}

void find_squares(Mat& image, vector<vector<Point> >& squares)
{
// blur will enhance edge detection
Mat blurred(image);
Mat dst;
medianBlur(image, dst, 9);

Mat gray0(dst.size(), CV_8U), gray;
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(&dst, 1, &gray0, 1, ch, 1);

// try several threshold levels
const int threshold_level = 2;
for (int l = 0; l < threshold_level; l++)
{
// Use Canny instead of zero threshold level!
// Canny helps to catch squares with gradient shading
if (l == 0)
{
Canny(gray0, gray, 10, 20, 3); //

// Dilate helps to remove potential holes between edge segments
dilate(gray, gray, Mat(), Point(-1, -1));
}
else
{
gray = gray0 >= (l + 1) * 255 / threshold_level;
}

// Find contours and store them in a list
findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

// Test contours
vector<Point> approx;
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);

// Note: absolute value of an area is used because
// area may be positive or negative - in accordance with the
// contour orientation
if (approx.size() == 4 &&
fabs(contourArea(Mat(approx))) > 1000 &&
isContourConvex(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::Mat debugSquares(std::vector<std::vector<cv::Point> > squares, cv::Mat image)
{
for (int i = 0; i< squares.size(); i++) {
// draw contour
cv::drawContours(image, squares, i, cv::Scalar(255, 0, 0), 1, 8, std::vector<cv::Vec4i>(), 0, cv::Point());

// draw bounding rect
cv::Rect rect = boundingRect(cv::Mat(squares[i]));
cv::rectangle(image, rect.tl(), rect.br(), cv::Scalar(0, 255, 0), 2, 8, 0);

// draw rotated rect
cv::RotatedRect minRect = minAreaRect(cv::Mat(squares[i]));
cv::Point2f rect_points[4];
minRect.points(rect_points);
for (int j = 0; j < 4; j++) {
cv::line(image, rect_points[j], rect_points[(j + 1) % 4], cv::Scalar(0, 0, 255), 1, 8); // blue
}
}

return image;
}

static std::vector<cv::Point> extremePoints(std::vector<cv::Point>pts)
{
int  xmin = 0, ymin = 0, xmax = -1, ymax = -1, i;
Point ptxmin, ptymin, ptxmax, ptymax;

Point pt = pts[0];

ptxmin = ptymin = ptxmax = ptymax = pt;
xmin = xmax = pt.x;
ymin = ymax = pt.y;

for (size_t i = 1; i < pts.size(); i++)
{
pt = pts[i];

if (xmin > pt.x)
{
xmin ...
edit retag close merge delete

are you trying to achieve proposed solution in http://answers.opencv.org/question/17....

( 2017-08-02 10:56:14 -0500 )edit

yes I'm trying to achieve it

( 2017-08-02 10:59:56 -0500 )edit

OK. it seems you did not interested with my answer. It was worth trying.

to answer this question i say there is plenty of samples to achieve this in this forum and stackoverlow. please delete this answer and do some search.

( 2017-08-02 11:07:22 -0500 )edit

can you give me some keypoints to search for ?

( 2017-08-02 11:17:15 -0500 )edit

I insist on trying the following demo program https://github.com/takmin/OpenCV-Mark...

( 2017-08-02 11:23:36 -0500 )edit

later if you still want to find contours i will help you

( 2017-08-02 11:24:28 -0500 )edit

I'm interested to find contours because I got some results

( 2017-08-02 12:06:35 -0500 )edit

Sort by ยป oldest newest most voted

you can find my trial C++ source code on github for getting some result images below

------------>

---------------->

used referencess:

more

Thanks so much. but it needs alot of work so that it can be adapted to general paper detection

( 2017-08-02 15:39:33 -0500 )edit

http://imgur.com/a/GQhIX

for example an image like this, it won't work :(

( 2017-08-02 15:44:33 -0500 )edit
( 2017-08-02 15:45:17 -0500 )edit

Thanks I managed to do it. How would I unwarp the image to be a rectuangluar quad ? should I make a new question

( 2017-08-02 16:33:20 -0500 )edit

see my answer in this post. it has perspective transformation

lines

    RotatedRect minRect = minAreaRect( Mat(contours[i]) );
.
.
.
warpPerspective( thresh, quad, transmtx, img.size());


try to adopt it

( 2017-08-02 16:52:19 -0500 )edit

I tried to adop it, but stil very hard to get it done. If you have some time, later, I would be happy if you do it

( 2017-08-02 17:57:41 -0500 )edit
1

post your code somewhere let me do it

( 2017-08-02 18:12:14 -0500 )edit

https://pastebin.com/0wYM2666 Here is the code, many thanks

( 2017-08-03 02:16:17 -0500 )edit

( 2017-08-03 07:24:02 -0500 )edit

i edited your question. see the code

( 2017-08-03 08:16:06 -0500 )edit

Official site

GitHub

Wiki

Documentation

## Stats

Asked: 2017-08-02 10:47:46 -0500

Seen: 2,837 times

Last updated: Aug 14 '17