I am having problems detecting circle areas. I tried it with the HoughCircles function from opencv. However even though the images are pretty similar the parameters for the funtion have to be different in order to detect the cirles.
Another approach I tried was to iterate over every pixel and check if the current pixel is white. If this is the case then check if there is a blob object in the area (distance to blob center smaller than a threshold). If there is, append the pixel to the blob, if not then create a new blob. This also didn't work properly.
Has anyone a idea how I can make this work (90% detection) ? I attached a example image and another image where I marked the cirles. Thanks!
UPDATE: Thank you for the help so far! This is the code where I acquire the contours and filter them by area:
im = cv2.imread('extract_blue.jpg') imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) im_gauss = cv2.GaussianBlur(imgray, (5, 5), 0) ret, thresh = cv2.threshold(im_gauss, 127, 255, 0) # get contours contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) contours_area = [] # calculate area and filter into new array for con in contours: area = cv2.contourArea(con) if 1000 < area < 10000: contours_area.append(con)
This works pretty neat. I drew them on the image:
This is the part where I filtered by circularity, it goes straight below the code where I filter by area:
contours_cirles = [] # check if contour is of circular shape for con in contours_area: perimeter = cv2.arcLength(con, True) area = cv2.contourArea(con) if perimeter == 0: break circularity = 4*math.pi*(area/perimeter*perimeter) print circularity if 0.8 < circularity < 1.2: contours_cirles.append(con)
However, the new list 'contours_cirles' is empty. I printed 'circularity' in the loop and the values are all between 10 000 and 100 000.
UPDATE #2: After correcting the missing brackets it is working now!
contours_cirles = [] # check if contour is of circular shape for con in contours_area: perimeter = cv2.arcLength(con, True) area = cv2.contourArea(con) if perimeter == 0: break circularity = 4*math.pi*(area/(perimeter*perimeter)) print circularity if 0.7 < circularity < 1.2: contours_cirles.append(con)
Thanks a lot guys! :)
Blob stands for Binary Large Object and refers to the connected pixel in the binary image. The term "Large" focuses on the object of a specific size, and that other "small" binary objects are usually noise.
In computer vision, blob detection methods are aimed at detecting regions in a digital image that differ in properties, such as brightness or color, compared to surrounding regions.
Basically, the Haar cascade technique is an approach based on machine learning where we use a lot of positive and negative images to train the classifier to classify between the images. Haar cascade classifiers are considered as the effective way to do object detection with the OpenCV library.
cv2. HoughCircles(image, method, dp, minDist) Where Image is the image file converted to grey scale Method is the algorithm used to detct the circles. Dp is the inverse ratio of the accumulator resolution to the image resolution. minDist is the Minimum distance between the center coordinates of detected circles.
As a starting point you may start with:
- Find all the contours in the given image using
cv2.findContours()
- Iterate over each contour:
- calculate the area, if the area of contour is in a given range say
70 < area < 150
. This will filter out some extremely smaller and large contours.- After filtering the contours with the area threshold, you need to check the number of edges of contour, which can be done using:
cv2.approxPolyDP()
, for a circle len(approx) must be > 8 but < 23. Or you may apply some more sophisticated operations to detect circles here.
You should try to implement this approach and update the question with the code that you will write henceforth.
EDIT: As suggested by @Miki, there is a better and cleaner way of detecting if a geometrical shape is of circular shape using circularity = 4pi(area/perimeter^2), and decide a threshold such as 0.9, to check if the shape is circular. For perfect circle circularity == 1
. You may fine tune this threshold as per your needs.
You may consult arcLength to find the perimeter of the contour and contourArea to get the area of the contour which are required to calculate the circularity.
We could try Hough Transformation
too to detect the circles in the image and play with the thresholds to get the desired result (detected circles in green boundary lines with red dots as centers):
import cv2 import numpy as np img = cv2.imread('rbv2g.jpg',0) img = cv2.medianBlur(img,5) cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR) circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,10, param1=50,param2=12,minRadius=0,maxRadius=20) circles = np.uint16(np.around(circles)) for i in circles[0,:]: # draw the outer circle cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2) # draw the center of the circle cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3) cv2.imshow('detected circles',cimg) cv2.waitKey(0) cv2.destroyAllWindows()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With