I need to detect shapes and their colours on a taken image. These shapes are: a heart, a rectangle, a star and a circle. Each shape has one of 5 predefined colours. Colour recognition works fine, but shape recognition is a real problem.
After hours and hours of googling, trying and tweaking code, the best I have come up with is the following procedure:
First, read the image and convert it to grayscale.
Then, apply blur to reduce the noise from the background.
Medianblur seems to work best here. Normal blur has little effect, and Gaussian blur rounds the edges of the shapes which gives trouble.
Next, apply threshhold.
AdaptiveThreshold doesn't give the results I expected; the result vary widely with each image. I now apply two thresholds: One uses Otsu's algorithm to filter the light shapes, and the other uses the Binary Inverted value for the darker shapes.
Finally, find contours on the two threshholds and merge them in one list.
By the amount of points found in each contour, I decide which shape is found.
I have tried adding Canny, sharpening the image, different threshholds, Convex Hull, Houghes, etc. I probably tried every possible value for each method as well. For now, I can get things working with the above procedure on a few images, but then it fails again on a new image. Either it detects too much points in a contour, or it doesn't detect the shape at all.
I am really stuck and dont know what else to try. One thing I still have to work out is using masks, but I can't find much information on that and don't know if it would make any difference at all.
Any advice is more than welcome. If you would like to see my code, please ask. You can find sample images here: http://tinypic.com/a/34tbr/1
Related
I have a photo of a paper that I hold up to my webcam, and want to minimize the area of the photo to just the paper. This way, my OCR program will potentially be more accurate, as well as conceivably faster.
I have taken a couple steps thus far to isolate the paper from the background.
First, I use Canny Edge detection, set with high thresholds. This provides a two-color representation of the edges of my image. On it, I can see a rounded rectangle among some other artifacts that happen to have sharp edges in the background.
Next, I use a Hough transformation, to draw vectors with over 100 point hits in polar coordinates on a black background. The resulting image is as shown:
See that large (the largest), almost-rectangular figure right in the middle? That's the paper I'm holding. I need to isolate that trapezoid as a polygon, or somehow otherwise get the coordinates of its vertices.
I can use these coordinates on the original image to isolate a PNG of the paper and nothing else.
I would also highly appreciate if you could provide answers to any of these three sub-questions.
-How do you find the locations of the intersections of these lines on the image?
-How would I get rid of any lines that don't form the center trapezoidal polygon?
-With these points, is there anything better than convex hull that would allow me only to get the trapezoidal/rectangular shaped region of the image?
Here is another example, in which my program produced a better image:
I was searching for an anti-aliasing algorithm for my OpenGL program (so I searched for a good shader). The thing is, all shaders want to do something with the textures, but I dont use textures, only colors. I looked at FXAA most of the time, so is there a anti-aliasing algorithm that just works with colors? My game, what this is for looks blocky like minecraft, but only works with colors and cubes of different size.
I hope someone can help me.
Greetings
Anti-aliasing has nothing specifically to do with either textures or colors.
Proper anti-aliasing is about sample rate, which while highly technical can be thought of as doing extra work to make a better educated guess at some value that cannot be directly looked up (e.g. a pixel that is only partially covered by a triangle).
Multisample Anti-Aliasing (MSAA) will work nicely for you, it will only anti-alias polygon edges and does nothing for texture aliasing on the interior of a polygon. Since you are not using textures you do not need to worry about aliasing inside a polygon.
Incidentally, FXAA is not proper anti-aliasing. FXAA is basically a shader-based edge detection and blur image processing filter. FXAA will blur any part of the scene with sharp edges, whether it is a polygon edge or an edge due to a mapped texture. It indiscriminately blurs anything it thinks is an aliased edge and gets this wrong often, resulting in blurry textures.
To use MSAA, you need:
A framebuffer with at least 2 samples
Enable multisample rasterization
Satisfying (1) is going to depend on what you used to create your window (in this case LWJGL). Most frameworks let you select the sample count as one of the parameters at the time of creation.
Framebuffer Objects can also be used to do this without messing with your window's parameters, but they are more complicated than need be for this discussion.
(2) is as simple as calling glEnable (GL_MULTISAMPLE).
I am currently using OpenCV in Java, but if need be I can switch to something else.
I have a set of known points in world coordinates as well as known in image coordinates. These points are not obtained with a calibration target. They are probably quite inaccurate. I can assume that they are close to coplanar.
I am trying to obtain a homography and lens correction from this. The camera is cheap(ish) and so there are lens issues.
I have been struggling to get the OpenCV functions to help me here without a calibration target. There are a lot of similar questions asked (the most similar I found was this one: Correct lens distortion using single calibration image in Matlab), but none quite fit the bill.
I was thinking I could iteratively find the homography, correct, find the lens distortion, correct and repeat until I got an OK result. Even so, I can't seem to do these separately in OpenCV.
I am quite new to OpenCV, so please be gentle.
openCV have this functionality
Camera calibration
Function "calibrateCamera" take as input world coordinates and corresponding image coordinates, and return camera intrinsic (also distortion)
At a minimum you need to "see" features that are known to be collinear, regardless of whether they are the images of coplanar points. That is because the error signal that you need to minimize in order to estimate (and remove) the lens's radial distortion is, by definition, the deviation of collinear points from straight lines.
See also this answer.
I would like to detect ellipses with OpenCV for Android, using the Tutorial 2-Basic included with OpenCV 2.4.1 package as a starting point. Note that my ellipse would be a perfect-photoshop one.
From what I understand, using the "HoughCircles" will only find perfect (or so) circles, thus leaving ellipses out.
Any help would be much appreciated as I am a total beginner at OpenCV
This is what I've tried so far
case Sample2NativeCamera.VIEW_MODE_CANNY: (ignore the Canny mode...)
capture.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME);
Imgproc.HoughCircles(mGray, mCircles, Imgproc.CV_HOUGH_GRADIENT, 1, 20);
Log.d("Ellipse Points", " X " + mCircles.get(1,1)[0] + mCircles.get(1, 1)[1]);
break;
If you think any more info could be useful, please let me know.
One possible solution to your problem is similar to this thread Detection of coins (and fit ellipses) on an image .
You should take a look a opencv's function fitEllipse.
The parameters used in HoughCircles play a fundamental role. HoughCircles will detect not just perfect, but also near-perfect circles (ellipses). I suggest you check this examples:
How to detect circles (coins) in a photo
Simple object detection using OpenCV
OpenCV dot target detection
Reshaping noisy coin into a circle form
And this answer has a decent collection of references.
If you already have an idea of the sizes of the ellipses that you're looking for, then try the following steps:
Find Canny edges in the image
Use a sliding window, the size of which is the maximum length of the major axis of ellipses you're looking for.
Within the window, collect all edge pixels, pick 6 pixels randomly and use linear least squares to fit an ellipse in the general form.
Repeat the above step in a RANSAC like procedure.
If there are enough inliers, you have an ellipse.
I've got this BufferedImage object that's guaranteed to contain only one color. I'm using it to display a sample image to show size, shape & hardness of a brush in a painting tool. I've tried several different blur implementations for hardness... the latest, that seems to work fairly well is this Stack Filter written by Romain Guy.
I've got 2 problems.
Faster on 1 channel than 4?: None of the blur filters I've tried seem to be quite fast enough... I realize this question has been asked before (and I'm not quite ready to try pulling in FFTW from C), but I'm wondering if there's a way to perform the blur using ONLY the alpha channel bits? The image only contains one color, so none of the other bits will change across points anyway and my thought is that this would cut the number of calculations for the blur to about 25% of the whole blur operation and I figure that's likely to result in a noticeable improvement in performance? I've not been able to find any information about this being tried via web search.
Eliminating the Dark Halo: Every time I try a different blur algorithm I end up having to rewrite it to get rid of the dark shadow around the shape caused by blurring in "black" from colorless pixels where nothing has been painted in yet. I've read about this and I'm using (as far as I know) INT_ARGB_PRE image types, which I remember reading as a solution to this problem. Am I missing something in that solution? Do I need to preformat the image in some way to make it interpret all the empty pixels as white instead of black?
Thanks!
You may find this interesting:
http://www.jhlabs.com/ip/blurring.html
The dark halo issue is discussed, all source code is available as as far as I can recall, it only uses standard Java SE stuff.