Find distorted rectangle in image (OpenCV) - image-processing

I am looking for the right set of algorithms to solve this image processing problem:
I have a distorted binary image containing a distorted rectangle
I need to find a good approximation of the 4 corner points of this rectangle
I can calculate the contour using OpenCV, but as the image is distorted it will often contain more than 4 corner points.
Is there a good approximation algorithm (preferably using OpenCV operations) to find the rectangle corner points using the binary image or the contour description?
The image looks like this:
Thanks!
Dennis

Use cvApproxPoly function to eliminate number of nodes of your contour, then filter out those contours that have too many nodes or have angles which much differ from 90 degrees. See also similar answer

little different answer, see
http://opencv.willowgarage.com/documentation/cpp/camera_calibration_and_3d_reconstruction.html

Look at the opencv function ApproxPoly. It approximates a polygon from a contour.

Try Harris Corner Detector. There is example in OpenCV package. You need to play with params for your image.
And see other OpenCV algorithms: http://www.comp.leeds.ac.uk/vision/opencv/opencvref_cv.html#cv_imgproc_features

I would try generalised Hough Transform it is a bit slow but deals well with distorted/incomplete shapes.
http://en.wikipedia.org/wiki/Hough_transform

This will work even if you start with some defects, i.e. your approxPolly call returns pent/hexagons. It will reduce any contour, transContours in example, to a quad, or whatever poly you wish.
vector<Point> cardPoly;// Quad storage
int PolyLines = 0;//PolyPoly counter ;)
double simplicity = 0.5;//Increment of adjustment, lower numbers may be more precise vs. high numbers being faster to cycle.
while(PolyLines != 4)//Adjust this
{
approxPolyDP(transContours, Poly, simplicity, true);
PolyLines = Poly.size();
simplicity += 0.5;
}

Related

image density of foreground

I want to get the density of the foreground.To be specific,first I need to to get the region of the foreground,inside the blue curve.Then use pixels inside the region to compute density.Obviously it cannot be solved by threshold or contour methods.It is a part of a Chinese character,so OCR may be useful,I don't know.Any advice?Thanks.
Now I have some idea.Randomly select 100 dots or more,than compute the average pixels around these dots,say radius is 100 or other.Hope this would be a estimate of the density.Is there some algorithm to achieve this?
Original Image
Result expected
Dilation works really well for your application like #Mark Setchell already pointed out in the comments.
First, use the dilate function to fill the gap in between your components. I used a quadratic kernel of size 35:
Next, use the threshold function to obtain a binary image:
[
Finally, use the findContours function to calculate the image contours and draw them using drawContours. The result will look very similar to your desired output:
You may have to change some parameters (mainly the dilation kernel size) depending on your input, but this should generally be the best approach to your problem.

How do I change the default checkerboard blocksize in OpenCV

I'm currently experimenting with OpenCV's calibration toolbox and I'm using a default checkerboard pattern to calibrate a camera. I want to use larger checkerboard blocks so that I can stand farther away from the camera without affecting OpenCV's ability to detect the corners.
As I understand it, OpenCV is pre-programmed with default block-size values. My question is: is there a way to change this default block-size value in the code? And where would I change this? TIA
OpenCV does not make any assumption on the physical size or the pattern size of your pattern.
That is, you can have any pattern with R rows and C columns.
It also doesn't matter if each block is 1 cm or 1 m.
The only thing you give to the calibrateCamera function is the objectPoints and imagePoints.
The array-dimensions (sizes) of these parameters corresponds to the number of corners of your pattern.
objectPoints should contain 3D coordinates (well, planar coordinates in your case, by setting Z=0) of your checkboard corners. These corners should be scaled to the physical size of your checkerboard. That is, if a corner has row-column index (3,1) and each block side is 3 cm then the 3D coordinate would be (0.09, 0.03, 0.00).

How does cv::ContourArea() deal with non-closed curves?

After using cv::Canny(), it seems that there are some non-closed curves in the image. So my question is, what will cv::ContourArea() deal with them? Counting the area by close the curve first or just ignore them?
From ContourArea reference:
Calculates the contour area
So it just calculates area (number of pixels if image is discontinuous) of contour.

What's the use of Canny before HoughLines (opencv)?

I'm new to image processing and I'm working on detecting lines in a document image. I read the theory of Hough line transform but I can't see why I must use Canny before calling that function in opencv like being said in many tutorials. What's the point of finding edges in this case? The fact is that if I don't use Canny or threshold before HoughLines() the results will be very messy. I hope someone will explain for me the reason why.
2 of the tutorials I've read:
Imgproc Feature Detection
Hough Line Transform
Short Answer
cvCanny is used to detect Edges, as well as increase contrast and remove image noise.
HoughLines which uses the Hough Transform is used to determine whether those edges are lines or not. Hough Transform requires edges to be detected well in order to be efficient and provide meaning results.
Long Answer
The Limitations of the Hough Transform are described in more detail on Wikipedia.
The efficiency of the Hough Transform relies of the bin of acculumated pixel being distinct, e.g. a direct contrast between a pixel and its surrounding neighbours or if using a mask region a pixel region and its surrounds regions. If all pixels had similar acculumated values nothing would stand out as a line or circle. This leads to the reduction of colour (colour to grayscale, grayscale to black and white) in order to increase contract.
The number of parameters to the Hough Transform also increase the spread of votes in the pixel bins and increase the complexity of the transform, which mean that normally only lines or circles are reliably detected using it as they have less than 3 parameters.
The edges need to be detected well before running the Hough Transform otherwise its efficiency suffers further. Also noisy images don't work well with Hough transform unless the noise is removed before hand.
First of all, to detect lines you need to work on a boolean matrix image (or binary), I mean: the color is black or white, there's no grayscale.
HoughLines()'s requirement to work properly is to have this kind of image as input. That's the reason you have to use Canny or Treshold, to convert the colored image matrix into a boolean one.
Hough transformation
A line in one picture is actually an edge. Hough transform scans the whole image and using a transformation that converts all white pixel cartesian coordinates in polar coordinates; the black pixels are left out. So you won't be able to get a line if you first don't detect edges, because HoughLines() don't know how to behave when there's a grayscale.
Theoretically, you are correct. Finding edges is not absolutely required for the Hough Line algorithm to work.
The way the Hough works is basically it takes every point and connects it to every other point, and whatever points have the most lines going through them, those lines stay. For this, we need points. The Canny creates those points. Theoretically you could use any sort of filter - isolate all blue or purple points and connect them, whatever - but edges works well.
The Hough also does not weight its lines or points. To the Hough, an image is binary - made up of either 1s or 0, points or not points. There is no need for greyscale, and the canny conveniently returns binary images.
Thus is the Canny always part of the Hough.
all is about processing binary data,
complex data -> (a binary data, b binary data, c binary data, ..) (using canny(),sobel(), etc)
a binary data -> function1() (using houghlines())
b binary data -> function2()
c binary data -> function3() ..
a binary data -X-> function2() ..
complex data -X-> function1() ..
HTH

Image processing-Shape Recognition

I want algorithm for recognizing multiple no of shapes(Specially rectangle and squares) in a picture.Preferably I am using C# so, I am looking forward for solutions in C#.
check aforgenet....
http://www.aforgenet.com/forum/
If you are looking for a library that does a lot of image processing for you there is always OpenCV. I think it is is c++ though.
You can use the Circularity algorithm as a first approach, which is very easy to compute:
C = p2/a where p is the perimeter (border area) and a is shape area.
To know how to read/write pixels quickly, take a look here
Alternatively look for shape signature algorithm available at Rafael Gonzales book. In this algorithm you compute the center of the object using central momentum, the you compute the distance between the center and each border pixel. You'll end up with a 1D signal where peaks represent bigger distance from the center. In a square, you have 4 symmetric peaks while in a rectangle 2 big peaks and 2 smaller ones.

Resources