Get notified about new tutorials
RECEIVE NEW TUTORIALS

Ray Phan

Feb 02, 2015

<p>Think of each circle as being bounded inside a square of dimensions <code>2r x 2r</code> where <code>r</code> is the radius of the circle. Also, the centre of this box is located at <code>(x,y)</code> which also corresponds to where the centre of the circle is located in the image. To see if the circle is within the image boundaries, you simply need to make sure that the box that contains the circle does not go outside of the image. Mathematically speaking, you would need to ensure that:</p>
<pre><code>r <= x <= cols-1-r
r <= y <= rows-1-r # Assuming 0-indexing
</code></pre>
<p><code>rows</code> and <code>cols</code> are the rows and columns of your image. All you really have to do now is cycle through every circle in the detected result and filter out those circles that go outside of the image boundaries by checking if the centre of each circle is within the two inequalities specified above. If the circle is within the two inequalities, you would save this circle. Any circles that don't satisfy the inequalities, you don't include this in the final result.</p>
<p>To put this logic to code, do something like this:</p>
<pre><code>import cv # Load in relevant packages
import cv2
import numpy as np
img = cv2.imread(...,0) # Load in image here - Ensure 8-bit grayscale
final_circles = [] # Stores the final circles that don't go out of bounds
circles = cv2.HoughCircles(img,cv.CV_HOUGH_GRADIENT,1,20,param1=50,param2=30,minRadius=0,maxRadius=0) # Your code
rows = img.shape[0] # Obtain rows and columns
cols = img.shape[1]
circles = np.round(circles[0, :]).astype("int") # Convert to integer
for (x, y, r) in circles: # For each circle we have detected...
if (r <= x <= cols-1-r) and (r <= y <= rows-1-r): # Check if circle is within boundary
final_circles.append([x, y, r]) # If it is, add this to our final list
final_circles = np.asarray(final_circles).astype("int") # Convert to numpy array for compatability
</code></pre>
<p>The peculiar thing about <code>cv2.HoughCircles</code> is that it returns a 3D matrix where the first dimension is a singleton dimension. To eliminate this singleton dimension, I did <code>circles[0, :]</code> which will result in a 2D matrix. Each row of this new 2D matrix contains a tuple of <code>(x, y, r)</code> and characterizes where a circle is located in your image as well as its radius. I also converted the centres and radii to integers so that if you decide to draw them later on, you will be able to do it with <code>cv2.circle</code>.</p>
<p>This tip was originally posted on <a href="http://stackoverflow.com/questions/26636449/OpenCV%20Python%20HoughCircles:%20Circles%20detected%20outside%20of%20image%20boundary/26636750">Stack Overflow</a>.</p>