我想找到硬幣的中間并找到半徑。半徑可以告訴我硬幣是 5 美分還是 50 美分。找到影像后,我必須能夠檢測到圓圈的中間,這樣我才能給它們一個顏色
我已經開始為 Hough 變換撰寫代碼
希望有人能幫我解決這個問題。
霍夫變換代碼:
image = img_as_ubyte(image)
edges = feature.canny(image, sigma=1.5, low_threshold=10, high_threshold=25)
# Detect two radii
hough_radii = np.arange(17, 35, 2)
hough_res = hough_circle(edges, hough_radii)
# Select the 11 coins
accums, cx, cy, radii = hough_circle_peaks(hough_res, hough_radii,total_num_peaks=11)
# Draw them
fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(10, 4))
image = color.gray2rgb(image)
count = 0
for center_y, center_x, radius in zip(cy, cx, radii):
circy, circx = circle_perimeter(center_y, center_x, radius,
shape=image.shape)
image[circy, circx] = (220, 20, 20)
count = 1
ax.imshow(image)
plt.figure(figsize=(25,25))
print("In this image we can detect", count, "coins")
plt.show()
uj5u.com熱心網友回復:
您有 2 個選擇來查找匹配的圈子。

第一個:滑動視窗
較小的視窗是您在輸入影像中尋找的模板,這里有兩個影像分別具有不同的半徑 19 和 21。首先,找到模板和輸入影像的邊緣,然后將影像的裁剪部分與模板相乘。每個靠近模板的區域都應該有更高的價值。
def correlation_coefficient(patch1, patch2):
product = np.mean((patch1 - patch1.mean()) * (patch2 - patch2.mean()))
stds = patch1.std() * patch2.std()
if stds == 0:
return 0
else:
product /= stds
return product
im1 = cv2.imread("Original.jpg")
im1 = cv2.cvtColor(np.float32(im1), cv2.COLOR_BGR2GRAY)
im2 = cv2.imread("bigger.png")
im2 = cv2.cvtColor(np.float32(im2), cv2.COLOR_BGR2GRAY)
sh_row, sh_col = im1.shape
correlation = np.zeros_like(im1)
for i in range(sh_row - im2.shape[1]):
for j in range(sh_col - im2.shape[0]):
temp1 = im1[i : i im2.shape[1], j : j im2.shape[0]]
if(temp1.shape != im2.shape):
correlation[i, j] = 0
continue
correlation[i, j] = correlation_coefficient(temp1, im2)
fig = plt.figure(figsize=(10, 7))
plt.imshow(correlation, cmap=plt.cm.gray)
plt.show()
這里的模板更小或更大。更大的輸出是


如您所見,一些點突出顯示為圓心。或者通過使用第二個匹配計算:
im1 = cv2.imread("Original.jpg")
im1 = cv2.cvtColor(np.float32(im1), cv2.COLOR_BGR2GRAY)
im1 = canny(im1, sigma=3, low_threshold=5, high_threshold=40)
im1 = im1.astype(np.uint8)
im2 = cv2.imread("bigger.png")
im2 = cv2.cvtColor(np.float32(im2), cv2.COLOR_BGR2GRAY)
im2 = canny(im2, sigma=3, low_threshold=5, high_threshold=40)
im2 = im2.astype(np.uint8)
sh_row, sh_col = im1.shape
d = 1
correlation = np.zeros_like(im1)
for i in range(sh_row - im2.shape[1]):
for j in range(sh_col - im2.shape[0]):
temp1 = im1[i : i im2.shape[1], j : j im2.shape[0]]
if(temp1.shape != im2.shape):
correlation[i, j] = 0
continue
correlation[i, j] = np.sum(np.multiply(temp1, im2))
io.imshow(correlation, cmap='gray')
io.show()
此外,我們有相同的結果:

第一種方法無法幫助我們找到指定的圓圈。因為您需要為這兩個模板設定一個閾值并解決越來越多的挑戰。讓我們研究另一種方法。
first one: Hough Transform
At first, run canny edge detector, then find all circles with radii range from 1 to 100. Then near circles(circles that centers are near to each others) are deleted:
import numpy as np
import matplotlib.pyplot as plt
import cv2
from skimage import data, color
from skimage.transform import hough_circle, hough_circle_peaks
from skimage.feature import canny
from skimage.draw import circle_perimeter
from skimage.util import img_as_ubyte
from skimage import io, feature
from scipy import ndimage
import imutils
from scipy import signal
from skimage import io, feature
image = cv2.imread("Original.jpg")
fig = plt.figure(figsize=(10, 7))
fig.add_subplot(1, 2, 1)
plt.imshow(image)
plt.axis('off')
plt.title("Original Image")
image = cv2.cvtColor(np.float32(image), cv2.COLOR_BGR2GRAY)
edges = canny(image, sigma=3, low_threshold=5, high_threshold=40)
fig.add_subplot(1, 2, 2)
plt.imshow(edges, cmap=plt.cm.gray)
plt.axis('off')
plt.title("After Run Canny Edge Detector")
# which raddii?
hough_radii = np.arange(1, 100)
hough_res = hough_circle(edges, hough_radii)
accums, cx, cy, radii = hough_circle_peaks(hough_res, hough_radii, total_num_peaks=100)
output = np.column_stack((cx, cy, radii))
output = output[(output[:,2] > 10)]
output = output[np.argsort(output[:, 1])]
output = output[np.argsort(output[:, 0])]
print(f"Circles Before Edit")
print(f"cx={output[:,0]}")
print(f"cy={output[:,1]}")
print(f"radii={output[:,2]}")
index = 0
flag = False
while (index < output.shape[0] - 1):
if(abs (output[index][0] - output[index 1][0]) < 5 ):
if(abs (output[index][1] - output[index 1][1]) < 5 ):
# print(f"del index {index 1}")
output = np.delete(output, (index 1), axis=0)
flag = True
else:
flag = False
else:
flag = False
if(flag is not True):
index = 1
print(f"Circles After Edit")
print(f"cx={output[:,0]}")
print(f"cy={output[:,1]}")
print(f"radii={output[:,2]}")
plt.show()
red = output[(output[:,2] <= 20)]
print(f"Red Circles")
print(f"cx={red[:,0]}")
print(f"cy={red[:,1]}")
print(f"radii={red[:,2]}")
green = output[(output[:,2] >= 20)]
print(f"Green Circles")
print(f"cx={green[:,0]}")
print(f"cy={green[:,1]}")
print(f"radii={green[:,2]}")
Check results:
Circles Before Edit
cx=[ 96 96 97 98 105 106 146 165 188 189 196 196 202 203 204 216 264 265]
cy=[137 138 136 138 232 232 356 229 102 102 166 166 222 221 286 322 116 116]
radii=[22 23 23 21 22 21 19 21 21 22 19 18 19 18 22 19 18 19]
Circles After Edit
cx=[ 96 105 146 165 188 196 202 204 216 264]
cy=[137 232 356 229 102 166 222 286 322 116]
radii=[22 22 19 21 21 19 19 22 19 18]
After do all necessary calculations:
Red Circles
cx=[146 196 202 216 264]
cy=[356 166 222 322 116]
radii=[19 19 19 19 18]
Green Circles
cx=[ 96 105 165 188 204]
cy=[137 232 229 102 286]
radii=[22 22 21 21 22]
As mentioned in results, 5 circles are proposed to red and 5 circles proposed to green.
Update#1
Be cautious before doing preprocessing in such problems. These processing likes erosion, dilation and median filters change radius of circles.
Drawing Circles:
Input radius are 19 and 21, so radius larger than 20 are belong to green color and radius smaller than 20 are belong to red color. For simplicity I set yellow color for radius = 20. In the last step you should delete abundance circles. Bellow I bring all of them together:
def remove_redundance(output):
print(f"output.shape={output.shape}")
index = 0
del_first = False
index_first = 0
while (index_first < output.shape[0]):
index_second = index_first 1
del_second = False
while (index_second < output.shape[0]):
if( (abs(output[index_first][0] - output[index_second][0]) < 10) and
(abs(output[index_first][1] - output[index_second][1]) < 10) ):
if(output[index_first][3] > output[index_second][3]):
output = np.delete(output, (index_second), axis=0)
del_second = True
else:
output = np.delete(output, (index_first), axis=0)
del_first = True
break
else:
del_second = False
del_first = False
if (del_second == False):
index_second = 1
if (del_first == False):
index_first = 1
else:
del_first = False
print(f"output.shape={output.shape}")
return output
def draw_circles(circle, coordinate, green = 0):
for cx, cy, radii in zip(coordinate[:,0], coordinate[:,1], coordinate[:,2]):
# Center coordinates
center_coordinates = (int(cx), int(cy))
# Radius of circle
radius = int(radii)
if(green == 1):
color = (0, 255, 0)
elif(green == 0):
color = (0, 0, 255)
elif(green == -1):
color = (0, 255, 255)
thickness = 1#-1
circle = cv2.circle(circle, center_coordinates, radius, color, thickness)
return circle
image = cv2.imread("Original.jpg")
# image = cv2.medianBlur(image, 3)
fig = plt.figure(figsize=(10, 7))
fig.add_subplot(1, 2, 1)
plt.imshow(image)
plt.axis('off')
plt.title("Original Image")
image = cv2.cvtColor(np.float32(image), cv2.COLOR_BGR2GRAY)
edges = canny(image, sigma=3, low_threshold=5, high_threshold=40)
fig.add_subplot(1, 2, 2)
plt.imshow(edges, cmap=plt.cm.gray)
plt.axis('off')
plt.title("After Run Canny Edge Detector")
# which raddii?
hough_radii = np.arange(1, 500)
hough_res = hough_circle(edges, hough_radii)
accums, cx, cy, radii = hough_circle_peaks(hough_res, hough_radii, total_num_peaks=500)
output = np.column_stack((cx, cy, radii, accums))#
output = output[(output[:,2] > 10)]
output = output[np.argsort(output[:, 1])]
output = output[np.argsort(output[:, 0])]
print(f"Circles Before Edit")
print(f"cx={output[:,0]}")
print(f"cy={output[:,1]}")
print(f"radii={output[:,2]}")
output = remove_redundance(output)
print(f"Circles After Edit")
print(f"cx={output[:,0]}")
print(f"cy={output[:,1]}")
print(f"radii={output[:,2]}")
plt.show()
red = output[(output[:,2] < 20)]
if(red.shape[0]>0):
print(f"Red Circles")
print(f"cx={red[:,0]}")
print(f"cy={red[:,1]}")
print(f"radii={red[:,2]}")
green = output[(output[:,2] > 20)]
if(green.shape[0]>0):
print(f"Green Circles")
print(f"cx={green[:,0]}")
print(f"cy={green[:,1]}")
print(f"radii={green[:,2]}")
yellow = output[(output[:,2] == 20)]
if(yellow.shape[0]>0):
print(f"yellow Circles")
print(f"cx={yellow[:,0]}")
print(f"cy={yellow[:,1]}")
print(f"radii={yellow[:,2]}")
circle = cv2.imread("Original.jpg")
if(red.shape[0]>0):
circle = draw_circles(circle, red, green = 0)
if(green.shape[0]>0):
circle = draw_circles(circle, green, green = 1)
if(yellow.shape[0]>0):
circle = draw_circles(circle, yellow, green = -1)
circle = cv2.cvtColor(circle, cv2.COLOR_BGR2RGB)
fig = plt.figure(figsize=(10, 7))
plt.imshow(circle)
plt.axis('off')
plt.title("Circles")
Results:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/454980.html
