I have no background in computer vision, but I was curious to know how I could use OpenCV library to achieve the following:
I have a jar of spare buttons, assorted in colour, style and diameter. For the most part they are circular. I evenly scatter them on a piece of white paper, and under good lighting, take a fairly high resolution picture with your average digital camera. How would I got about slicing this image to grab each button individually as a separate object/image?
Thanks in advance.
Two possible ways:
1) Using the circle hough transform
You run some edge detector (canny/sobel) and then the circle hough transform. You'll get the circles.
2) Using contours
Seperate the button and background using thresholding. Detect contours in this thresholded image and you have the buttons!
Articles that might help:
Contours: http://aishack.in/tutorials/an-introduction-to-contours/
Thresholding: http://aishack.in/tutorials/thresholding/
Hough circles: http://aishack.in/tutorials/hough-circles-in-opencv/
Disclaimer: Those are links to my website.
I think the simplest thing you could try is: run the Canny edge detector and apply a Hough transform to detect circles and generate a separate image from each of the circles.
I've been doing some dish recognition and it worked pretty good. do this:
Do some thresholding (buttons should be shiner than background) to leave only the buttons,
then cvFindContours
for each contour:
run cvFitEllipse, it will return you both axis (a,b) of the fitted ellipse.
check that the area of an ellipse PIab is similar to the Area of the contour using cvContourArea and also that both axis are similar a = b. (this will leave only circles)
then you can do whatever you need.
printContour, using cvPrintContour, use cvMinAreaRect2 to get button bounding box, etc
Hough transform is also possible but it is quite more expensive.
Related
I am trying to do some image processing for which I need to remove the facial features like eyes, nose, lips etc.
I have the following contour points
I am doing inpainting on this image::
Now I have to remove the facial features namely eyes, nose, lips and have the skin in place or that. The thing is that I don't have to do just for this image but for a general image that the user uploads.
I am trying using inpainting but it does create some problem, especially around lips where its having beards in neighbouring pixels and it gives a blackish output like this ::
I tried different contour points and shapes but somewhere or the other its causing problem mainly because of hair or beards. So how to achieve what I am trying to?
Code ::
Photo.inpaint(finalImage,imageROIGRAY,imageROIDest,8,Photo.INPAINT_NS);
I have done dilation also on the mask, but doesn't work.
Showing mask for one of the shape formed using the contour points ::
I am trying to detect the regions of traffic signs. Using OpenCV, my approach is as follows:
The color image:
Using the TanTriggs Preprocessing get rid of the illumination variances:
Equalize histogram:
And binarize (Cv2.Threshold(blobs, blobs, 127, 255, ThresholdTypes.BinaryInv):
Iterate each blob using ConnectedComponents and get the mean color value using the blob as mask. If it is a red color then it may be a red sign.
Then get contours of this blob using FindContours.
Simplify the contours using ApproxPolyDP and check the points of each contour:
If 3 points then triangle shape is acceptable --> candidate for triangle sign
If 4 points then shape is acceptable --> candidate
If more than 4 points, BBox dimensions are acceptable and most of the points are on the ellipse fitted (FitEllipse) --> candidate
This approach works for the separated blobs in the binary image, like the circular 100km sign in my example. However if there is a connection to the outside objects, like the triangle left bottom part in the binary image, it fails.
Because, the mean value of this blob is far from red!
Using Erosion helps in some cases, however makes it worse in many of the other images.
Using different threshold values for the binarization also works for some, but fails on many; like the erosion.
Using HoughCircle is just very slow and I couldn't manage to get good results playing with the parameters.
I have tried using matchShapes but couldn't get good results.
Can anybody show me another way the achieve what I want (with a reasonable computational time)?
Any information, or code in any language is wellcome.
Edit:
Using circularity measure (C=P^2/4πA) or the approach I have described above, triangle and ellips shapes can be found when they are separated. However when the contour is like this for example:
I could not find a robust way to extract the triangle piece. If I could, I would check the mean color, and decide if its a red sign candidate.
Sorry, I don't have the kudos to comment, but can't you use the red colour?
import common
myshow = common.myshow
img = cv2.imread("ms0QB.png")
grey = np.zeros(img.shape[:2],np.uint8)
hsv = cv2.cvtColor(img,cv2.COLOR_mask = np.logical_or(hsv[:,:,0]>160,hsv[:,:,0]<10 )
grey[mask] = 255
cv2.imshow("160<hue<182",grey)
cv2.waitKey()
I am trying to detect ROI for a fixed repetitive pattern in an image using opencv C++.
The ROI which I am trying to find - is shown with red boundary as shown in the pic:
I tried canny edge detection after blurring but it detects edge of the vertical/horizontal black and white lines. This is not something I am trying to detect.
What is the best approach to my problem?
Since you're starting with a binary image you could use
findContours()
to get the contours for the individual strips. Since there are a couple of solitary pixels from noise you should then filter for size using
contourArea(contour)
and merge the points of all contours meeting your size criteria into a combined contour. Then get the bounding box for the combined contour:
boundingRect(combinedContour)
I'm trying to create app for applying Affine transform only for some part of image(non rectangular).
http://s29.postimg.org/k45fwbmsn/Untitled.png
Is there exist any way, to transform only selected(visible) part of the image?
I'm certain the overall transformation you described (only on part of an image) is not affine. So it isn't as easy as applying a matrix multiplication to some vectors.
But of course, there are ways to define algorithms that detect black rectangles and apply an affine transformation to the coordinates of detected rectangles. With the transformed coordinates you can draw a new quadrangle. Note: After an affine transformation it does not need to be a rectangle anymore.
Btw. you're contradicting yourself:
transform only for some part of image(non rectangular).
vs
to transform only black rectangle
I'd propose you clarify the following points about your input and expected output:
Which of the contradicting transformations do you want: Only rectangles or everything but rectangles?
Is it binary black-and-white, gray-level or colour image? This is a question of simple to complex input with quite some impact on the algorithm.
Is the image noiseless, i.e. is it true black or all sorts of really dark colours? For true black you might be able to apply a simple heuristic to detect the rectangles. If it's a noisy image you need to think about image filters/improvements and colour space transitions.
Are the rectangles the only "black" areas in your image?
Are the rectangles in parallel to x and y axis? Again this is simple heuristic vs pattern recognition.
Is the number of rectangles known? Are multiple rectangles related (in size, proportions, parallel) to each other?
What is to happen on borders or with image parts revealed by moving/shrinking the rectangles?
I'll edit the answer, when you provide the required information in your question.
I have several binary images and my task is to segment circle-like shape. The circles are not perfect rounded circle, but all of them will look like circle. Here are some example images and what I need:
As you can see from above, the left images are original images, and the right images are what I need to do. The circles intersect with other shapes, but I only want the circle, as indicated in red. The imaginary lines to close the circle will be required. What can I do in this case in Image Processing?
EDIT: in case, the image above is broken, here: http://imageshack.us/photo/my-images/835/circleonly.jpg/
Do you know the radii of the disks you are looking for?
If yes, morphological openings (erosion then dilation) would be straightforward, and very fast. The result using Mathematica:
Opening[img, DiskMatrix[15]]
If not, as other proposed, computing the contour image and then using the Hough transform would be a method worth pursuing. The image just above shows the contour image.
You can use hough transform, first you need is the edge image then you use a hough transform like you can see in this papers
http://www.cis.rit.edu/class/simg782/lectures/lecture_10/lec782_05_10.pdf
http://www.sci.utah.edu/~gerig/CS6640-F2010/FINALPROJECT/Ballard-GHT-1981.pdf
http://www.sciencedirect.com/science/article/pii/003132039290064P
http://www.markschulze.net/java/hough/