Classify hand drawn shapes with opencv - opencv

I have been coding with OpenCV lately,
I have drawn on a paper few shapes (circle, triangle , rectangle, square, Parallelogram),
and would like to classify the shapes according to their characteristics.
I have searched for contours and drew them, and moreover drew the minAreaRect for each shape.
I tried using the function matchShapes but it didn't give me the result I had expected,
I have tried using Polygon Approximations but it seems it to fail here too.
(I went through all questions here before posting this question)
Original image
After some processing
What should be the correct approach for classifying hand-drawn shapes?
Any tips/suggestions would be great, I'm stuck :/.

Related

Refining edge and contour detection

I am struggling to get good results detecting objects with a series of images I have. The issue is that they are similar objects with a bit of real world noise (in this case bunches of bananas). Having them overlapping is probably not helping.
My approach has been this tried and tested classic:
- Convert to grayscale
- Blur the image slightly
- Apply Canny edge detection
- Dilate the image
- Find the contours
Right now I have been trying to do a Canny edge detection but the edges aren't quite right and so when I find the contours I get all sorts of funny shapes (and only sometimes the bananas).
I have also tried Sobel edge detection with even poorer results.
example pic before contour detection:
example pic after contour detection:
Can somebody please give me some suggestions on how I can refine this?

Detect missing squares in color calibration chart opencv python

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.

Are there other methods to detect circles apart from HoughCircles

I am trying to detect circular road signs and I have some issues.
The HoughCircles function detects circles in a gray image, however with the same parameters but the image binarized (the circle is still perfectly visible) it does not detect any circle. I do not why it fails a lot with a binarized image. Any ideas why I have this issue with binary images?
To try to correct that I set the dp parameter to 2 and changed the threshold. In the binary image I now detect circles, but it also gives me a lot of false positives. I do not understand what the dp parameter is, or how to use it.
If there is no way to make it work, I would like to know if there is any other way of detecting circles in an image.
Hough generally works well with bad data - partial or obscured circles and noise.
But it is sensitive to the tuning parameters (max, min diameter, number of votes for a result).
Typically you could run hough to find all possible circles and then examine each possible circle by eg checking distance from center to points on the circumference. Or you could look at found circle diameters and then refine your diameter/vote bins, especially if this is a video stream and you expect the circles to be similar in the future.

Image processing - Match curves from one image to another

I am doing something similar to this problem:
Matching a curve pattern to the edges of an image
Basically, I have the same curve in two images, but with some affine transform between the two. Here is an example of two images:
Image1
Image2
So in order to get to Image2, you can apply some translation, rotation, scale, etc. to Image1.
Does anyone know how to solve for this transform?
Phase correlation doesn't work because it's not a translation only. Optical flow doesn't work since there's not enough detail to resolve translation, rotation, scale (It's pretty much a binary image). I'm not sure if Hough Transforms will give me good data.
I think some sort of keypoint matching algorithm like sift or surf would work with this kind of data as well.
The basic idea would be to find a limited number of "interesting" keypoints in each image, then match these keypoints pairwise.
Here is a quick test of your image with an online ASIFT demo:
http://demo.ipol.im/demo/my_affine_sift/result?key=BF9F4E4E006AB5168497709836C39C74#
It is probably more suited for normal greyscale images, but nevertheless it seems to work for this data. It looks like the lines connect roughly the same points around both of the curves; plugging all these pairs into something like the FindHomography function in OpenCv, the small discrepancies should even themselves out and you get the affine transformation matrix between the two images.
For your particular data you might be able to come up with better keypoint descriptors; perhaps something to detect the line ends, line crossings and sharp corners.
Or how about this: It is a little more work, but if you can vectorize your paths into a bezier or b-spline, you can get some natural keypoints from the spline descriptors.
I do not know any vectorisation library, but Inkscape has a basic implementation with which you could test the approach.
Once you have a small set of descriptors instead of a large 2d bitmap, you only need to match these descriptors between the two images, as per FindHomography.
answer to comment:
The points of interest are merely small areas that have certain properties. So the center of those areas might be black or white; the algorithm does not specifically look for white pixels or large-scale shapes such as the curve. What matter is that the lines connect roughly the same points on both curves, at least at first glance.

Finding a grid in an image

Having a match-3 game screenshot (for example http://www.gameplay3.com/images/games/jewel-quest-ii-01S.jpg), what would be the correct way to find the bound box for the grid (table with tiles)? The board doesn't have to be a perfect rectangle (as can be seen in the screenshot), but each cell is completely square.
I've tried several games, and found that there are some per-game image transformations that can be done to enhance the tiles inside the grid (for example in this game it's enough to take the V channel out of HSV color space). Then I can enlarge the tiles so that they overlap, find the largest contour of the image and get the bound box from it.
The problem with above approach is that every game (or even level inside the same game) may need a different transformation to get hold of the tiles. So the question is - is there a standard way to enhance either tiles inside the grid or grid's lines (I've tried finding lines with Hough transform, but, although the grid seems pretty visible to the eye, Hough doesn't find it)?
Also, what if the screenshot is obtained using the phone camera instead of taking a screenshot of a desktop? From my experience, captured images have less defined colors (which depends on lighting), and also can be distorted a little, as there is no way to hold the phone exactly in front of the screen.
I would go with the following approach for a screenshot:
Find corners in the image using for example a canny like edge detector.
Perform a hough line transform. This should work quite nicely on the edge image.
If you have some information about size of the tiles you could eliminate false positive lines using some sort of spatial model of the grid (eg. lines only having a small angle to x/y axis of the image and/or distance/angle of tile borders.
Identifiy tile borders under the found hough lines by looking for edges found by canny under/next to the lines.
Which implementation of the hough transform did you use? How did you preprocess the image?
Another approach would be to use some sort of machine learning approach. As you are working in OpenCV you could use either a Haar like feature detector. An example for face detection using Haar like features can be found here:
OpenCV Haar Face Detector example
Another machine learning approach would be to follow a Histogram of Oriented Gradients (Hog) approach in combination with a Support Vector Machine (SVM). An example is located here:
HOG example
You can find general information about HoG detection at:
Hog detection

Resources