I'm using OpenCV on the iPhone. I want to find a Sudoku in a photo.
I started with some Gaussian Blur, Adaptive Threshold, Inverting the image and Dilate.
Then I did some findContour and drawContour to isolate the Sudoku grid.
Then I've used the Hough Transform to find lines and what I need to do now is find the corners of the grid. The Sudoku photo may be taken in an angle so I need to find the corners so I can crop and warp the image correctly.
This is how two different photos may look. One is pretty straight and one in an angle:
Probabilistic Hough
http://img96.imageshack.us/i/skrmavbild20110424kl101.png/
http://img846.imageshack.us/i/skrmavbild20110424kl101.png/
(Standard Hough comes in a comment. I can't post more than two links)
So, what would be the best approach to find those corners? And which of the two transform is easiest to use?
Best Regards
Linus
Why not use OpenCV's corner detection? Take a look at cvCornerHarris().
Alternatively, take a look at cvGoodFeaturesToTrack(). It's the Swiss Army Knife of feature detection and can be configured to use the Harris corner detector (among others).
I suggest the following approach. First, find all intersections of lines. It is helpful to sepparate lines into "horisontal" and "vertical" by angle (i.e. find two major directions of lines). Then find the convex hull of acquired points. Now you have corners and some points on the boundaries. You can remove the latter by analysing the angle between neighbour points in the convex hull. Corners will have the angle about 90 degrees and points on the boundaries - about 180 degrees.
Related
I am am currently working on a method to extract colors from a macbeth color chart. So far I have had moderate success by using thresholding and then extracting square contours. Sadly through, colors that are too close to each other either mix together or do no get detected.
The code in it's current form:
<script src="https://pastebin.com/embed_js/mNi0TcDE"></script>
The image before any processing
After thresholding, you can see that there are areas where lines are incomplete due to too small differences in color. I have tried to use dilation to midigate these issues and it does work to a degree. But not enough to detect all squares.
Image after thresholding
This results in the following contours being detected
Detected contours
I have tried using:
Hough lines, sadly no lines here detected.
Centroids of contours, but I was unable to find a way to use centroids to draw lines and detect the centers of the missing contours
Corner detection, corners where found. But I was unsuccessful in finding a real way to put them to use.
Can anyone point me in the right direction?
Thaks in advance,
Emil
Hum, if your goal is color calibration, you really do not need to detect the squares in their entirety. A 10x10 sample near the center of the image of each physical square will give you 100 color samples, which is plenty for any reasonable calibration procedure.
There are many ways to approach this problem. If you can guarantee that the chart will cover the image, you could even just do k-means clustering, since you know in advance the exact number of clusters you seek.
If you insist on using geometry, I'd do template matching in scale+angle space - it is reasonable to assume that the chart will be mostly facing, and only slightly rotated, so you only need to estimate scale and a small rotation about the axis orthogonal to the chart.
I've found other questions on the topic of detecting straight lines in images which I will read up on.
But I'm aware the in many photos the real life straight lines end up curved.
I don't have to de-curve fish-eye distortion or anything extreme.
But I would like to handle a "typical" amount of curve distortion as though they are still straight lines.
Are there some algorithms or techniques that can handle this in a "good enough" manner?
Here's an old photo of mine of a book showing the kind of curved straight lines I had in mind. It's a good example for the curvature and lens distortion. (It may not be a good example generally due to the other lines in the background, but that's beside the point of the current question.)
The curvature of the edges doesn't seem that severe, and at worst the Hough transform will just break the edges in a few segments.
I would be more worried by the lack of contrast of the edges (white on white) which can make the detection fail.
As it turns out, one of the most popular techniques used for straight line detection also exists in versions that work with curves.
It's called the "Hough Transform".
Wikipedia article
Stackoverflow tag
It was originally for detecting straight lines, but has been generalized to also work with curves and other arbitrary shapes. From the Wikipedia article:
The classical Hough transform was concerned with the identification of
lines in the image, but later the Hough transform has been extended to
identifying positions of arbitrary shapes, most commonly circles or
ellipses.
There are even papers on the specific topic of using Hough transforms to deal with lens distortion:
Automatic Lens Distortion Correction Using One-Parameter Division Models
A Hough transform-based method for radial lens distortion correction
Wide-Angle Lens Distortion Correction Using Division Models
Automatic curve selection for lens distortion correction using Hough transform energy
Blind radial distortion compensation from video using fast Hough transform
You can see the lanes are askew. I want to make the lanes perpendicular.
I used Photoshop's perspective transformation function, got the result:
Although the lanes are vertical now, the cars in the far end become large, the cars in the near end become so small. That is not what I want.
I tried Photoshop's warp function. Photoshop gave me 8 control points and I finally got my ideal result.
What is the name of that kind of transformation?
How to do the transformation programmatically? I'm using C# + EmguCV(OpenCV)
Thanks a lot.
It is called Radial Distortion. It is commonly fixed by Browns model. Here is a tutorial on how to fix it using Photoshop.
Be aware that in your case, you should first fix the radial distortion, and only then do a projective transformation (Homography), since radial distortion is a property of the lens, whereas the projective transformation is a property of the world you are taking a look at.
Apart from correcting for radial distortion, the perspective can be corrected by applying a homography transform (assuming the road is flat)
Im searching for radius and the center coordinates of circle in a image. have already tried 2D Hough transform. but my circle radius is also a unknown. Im still a beginner to Computer vision so need guild lines and help for implementing three dimensional hough space.
You implement it just like 2D Hough space, but with an additional parameter. Pseudo code would look like this:
for each (x,y) in image
for each test_radius in [min_radius .. max_radius]
for each point (tx,ty) in the circle with radius test_radius around (x,y)
HoughSpace(tx,ty,test_radius) += image(x,y)
Thiton gives you the correct approach to formalize the problem. But then, you will run in other problems inherent to the hough transform:
how do you visualize the parameter space? You may implement something with a library like VTK, but 3D visualization of data is always a difficult topic. The visualization is important for debugging your detection algorithm and is one of the nice thing with 2D hough transform
the local maximum detection is non trivial. The new dimension will mean that your parameter space will be more sparse. You will have more tuning to do in this area
If you are looking for a circle detection algorithm, you may have better options than the hough transform (google "Fast Circle Detection Using Gradient Pair Vectors" looks good to me)
I have been working with OpenCV for a fairly short time, and have performed Canny Edge Detection on an image, and also performed dilation after that to further separate the object (in my case a square) from the background.
My problem, now is to identify graspable regions in 2D using an algorithm that requires me to handle co-ordinates of the points in those edges. Is there any way I can use OpenCV to get the co-ordinates of the corners so I can find the equation of the lines forming the edge of the square? I know the size of the square. My problem involves 2D co-ordinate geometry, and hence the need for co-ordinates.
I can provide the image after edge detection and dilation if need be. Help would be appreciated a lot.
Just offering a second method - not guaranteed to work.
Step 1: extract connected component and their contours. This can be applied after the Canny Edge Detection step.
FindContours
Step 2: If the contours are fairly good approximation of a square, you can use their bounding box directly.
BoundingRect - if the rectangles are always upright (not rotated)
MinAreaRect - if the rectangles are rotated.
The reason for the disclaimer is that it only works on very clean results, without any broken edges or gaps in the Canny edges, etc. If you need a more robust way of finding rectangles, Hough transform will be necessary.
You could use the corner detectors provided in OpenCV like Harris or Corner Eigenvalues. Here's an example of that along with full-fledged code.
In case other features are also throwing up corners you may need to go in for connected component analysis.