<< Chapter < Page Chapter >> Page >

angle.

Code

def detect_edge(img, thresh, blursize): """Detects edges in an image :param img: image to detect edges in:param thresh: minimum magnitude of gradient before it's considered an edge :param blursize: size of Gaussian blur filter:return: boolean matrix of edges in image """# ============================= # "Generate Sobel kernel"# ============================= img = blur(img, blursize)sobelx = np.array([[-1, 0, 1],[-2, 0, 2],[-1, 0, 1]])sobely = np.array([[-1, -2, -1],[0, 0, 0],[1, 2, 1]])# find partial derivatives of image by convolving with Sobel kernels gradImgx = np.copy(img)gradImgy = np.copy(img) gradImgy = signal.convolve2d(gradImgy, sobely, mode = "same")/4.0gradImgx = signal.convolve2d(gradImgx, sobelx, mode = "same")/4.0# ============================= # "Calculate gradient angle and magnitude at each pixel"# ============================= angleGrad = np.arctan2(gradImgy, gradImgx)magGrad = np.sqrt(np.square(gradImgy) + np.square(gradImgx)) isEdge = np.greater_equal(magGrad, thresh)return isEdge, angleGrad

2.2.3 applying the hough circle transform

A circle can be represented as a center and a radius, and the Hough circle transform transforms a image from (x, y) points to (radius, center) as shown in equation 2.6 and 2.7 and figure (Fig #).

A dog sitting on a couch.

Fig 2.5 Visual of the Hough transform

A dog sitting on a couch.

Since the center and radius are both unknowns, the Hough transform tests r = from a minimum radius radMin to maximum radius radMax.

  1. In an image with imgHeight rows and imgWidth columns, let V be an accumulator matrix of size (radMax, imgHeight, imgWidth).
  2. For each edge point (x, y) and each possible radius r, we use equation 2.6 to calculate the center.
  3. Give the resulting V(r, a, b) a vote.
  4. find the local maximums in V to determine circle locations.
def hough_circle(colorImg, img, isEdge, angleGrad, radMin, radMax, distMin, votesMin): """Uses the Hough circle transform to detect circles in image :param img: Image to be operated on. size rows x cols. cv2 image format:param isEdge: rows x col size boolean matrix. True if pixel is edge pixel. :param angleGrad: rows x col size float matrix. gradient direction at each pixel.:param radMin: int, minimum radius of circles detected :param radMax: int, maximum radius of circles detected:param distMin: int, minimum distance between circles detected :param votesMin: int, minimum threshold for accumulator value. The higher this value is,the less false circles detected :return: numpy array of circles detected. Stored as a = [[radii], [rows], [cols]]where a[0][i] is the radius of the ith circlea[1][i]is the row where the center of the ith circle is located a[2][i] is the col where the center of the ith circle is located""" rows, cols = img.shape# Initialize accumulator matrix param_votes = np.zeros((radMax, rows, cols), dtype = int)# Initialize accumulator matrix of local maximums param_maxes = np.zeros((radMax, rows, cols), dtype = int)# Perform Hough transform on each edge point with radii ranging from radMin to radMax for r in range(0, rows):for c in range(0, cols): # Get gradient angle at pixel (r,c)# (r, c) is the proposed center for the circle theta = angleGrad[r][c] if isEdge[r][c]:for rad in range(radMin, radMax): # For each proposed, center,# Test each possible radius and give a vote to the resulting (rad, center) coordinates xstar = round(c - rad * math.cos(theta))ystar = round(r - rad * math.sin(theta)) if xstar>=0 and xstar<cols and ystar>=0 and ystar<rows: param_votes[rad][ystar][xstar]+= 1 # Add pi to the gradient angle so the angle also points in the other direction because# who knows is the gradient is pointing towards or away from the center of the circle. theta = theta + math.pixstar = round(c - rad * math.cos(theta)) ystar = round(r - rad * math.sin(theta))# Add a vote to (rad, center) if the center is within the bounds of the image if xstar>=0 and xstar<cols and ystar>=0 and ystar<rows: param_votes[rad][ystar][xstar]+= 1 # Find local maximums in the accumulator matrix.param_votes[param_votes<votesMin] = 0param_max = filter.maximum_filter(param_votes, size = (distMin, distMin, distMin)) param_max = np.logical_and(param_votes, param_max)# Find indices of maximums circle_indices = np.where(param_max)# Will most likely find too many circles, so use helper function to average clusters of circles # Also removes false positivescircle_indices = reduce_circles(circle_indices, distMin, param_votes) total_circles = len(circle_indices[0]) # draw detected circles onto imgfor i in range(0, total_circles): rad = circle_indices[0][i] r = circle_indices[1][i] c = circle_indices[2][i] cv2.circle(colorImg, (c, r), rad, (0,255,0), thickness = 3)cv2.circle(colorImg, (c, r), 1, (0, 255, 0), thickness = 2) return colorImg, circle_indices

Get Jobilize Job Search Mobile App in your pocket Now!

Get it on Google Play Download on the App Store Now




Source:  OpenStax, Hough transform object detection. OpenStax CNX. Dec 16, 2015 Download for free at http://legacy.cnx.org/content/col11937/1.1
Google Play and the Google Play logo are trademarks of Google Inc.

Notification Switch

Would you like to follow the 'Hough transform object detection' conversation and receive update notifications?

Ask