Reputation: 854
I want to detect circles in black-white images without morphology or hough transform.
Example if images:
They represent irices. In order to do that I want to use convolution with a kernel. Currently I am using the kernel of the following type:
radius = 2
element = np.zeros((2 * radius + 1, 2 * radius + 1))
cv2.circle(element, (radius, radius), radius, 1, 1)
cv2.circle(element, (radius, radius), radius+1, 1, 1)
cv2.circle(element, (radius, radius), radius+2, 1, 1)
So it is several concentric circles with different values. And example of kernel
But I want to employ the following effect:
if the non-zero elements of the kernel lie on the same line from center to biggest radius, I want them to have indicator feature : if more then one pixel from one line responds to image then only one effect is added to result.
For example, let's say we have the following kernel
where 2
represent such indicator values. If both pixels on image, which correspond to that elements in kernel have the value '255' then 255 is added to result of convolution, not 500. If only one have the value 255' then 255 is added to result also. If both pixels are 0 then 0 added to result. In other words I want to incorporate thick circle as a kernel, every unit of length works as one element of kernel and give response equal to respond of one pixel.
So how can I implement such convolution?
How can I check if pixels on the same line?
Upvotes: 0
Views: 312
Reputation: 854
I managed to do it with the following methods:
def get_response(img, center, radius, angle):
line_img = np.zeros_like(img)
end_point_x = int(center[0] + radius * 2 * np.cos(angle))
end_point_y = int(center[1] + radius * 2 * np.sin(angle))
kernel = np.zeros_like(img)
cv2.circle(kernel, center, radius, 1, 3)
end_point = (end_point_x, end_point_y)
cv2.line(line_img, center, end_point, 1, 1)
active_pixels = np.multiply(img, np.multiply(line_img, kernel))
return 1 if np.sum(active_pixels) > 0 else 0
def get_kernel_res(eye_img, angle_freq=10):
radius = int(min(eye_img.shape) // 1.2)
dst = eye_img.copy()
result = np.zeros_like(eye_img)
for x in range(dst.shape[1]):
for y in range(dst.shape[0]):
response = 0
for angle in range(0, 360, angle_freq):
response += get_response(dst, (x,y), radius, angle * np.pi / 180)
result[y][x] = response
rows, cols = np.where(result > np.max(result) - 2)
center = np.array((rows, cols)).mean(axis=1).astype(int)[::-1] #- (radius, radius)
return center
However it is slow and there are problems with presize choice of angle_freq
Upvotes: 0