霍夫圆检测python代码实现,不调用opencv
时间: 2023-10-31 10:05:37 浏览: 76
以下是一个基于霍夫变换的圆检测的 Python 代码实现,不使用 OpenCV:
```python
import numpy as np
import matplotlib.pyplot as plt
def hough_transform(img, rmin, rmax):
# 将图像转换为灰度图像
gray = img.copy()
if len(img.shape) == 3:
gray = np.mean(img, axis=2)
# 定义霍夫变换的参数
rows, cols = gray.shape
theta = np.arange(0, 360, 1)
radii = np.arange(rmin, rmax+1, 1)
# 计算 sin 和 cos 值,以加速计算过程
sin_theta = np.sin(np.deg2rad(theta))
cos_theta = np.cos(np.deg2rad(theta))
# 初始化空的霍夫累加矩阵
hough_acc = np.zeros((len(radii), len(theta)))
# 遍历所有像素,查找可能的圆心
for r_idx, r in enumerate(radii):
for y in range(rows):
for x in range(cols):
if gray[y, x] > 0:
# 对于每个可能的圆心,计算半径
for t_idx, _ in enumerate(theta):
a = int(x - r * cos_theta[t_idx])
b = int(y - r * sin_theta[t_idx])
if a >= 0 and b >= 0 and a < cols and b < rows:
hough_acc[r_idx, t_idx] += 1
return hough_acc, radii, theta
def find_circles(img, num_circles, rmin, rmax):
# 使用霍夫变换查找圆形
hough_acc, radii, theta = hough_transform(img, rmin, rmax)
# 找到最可能的圆形
best_circles = []
for i in range(num_circles):
r_idx, t_idx = np.unravel_index(np.argmax(hough_acc), hough_acc.shape)
r = radii[r_idx]
t = theta[t_idx]
best_circles.append((r, t))
# 将该圆形从累加器中删除,以便找到下一个最可能的圆形
for y in range(img.shape[0]):
for x in range(img.shape[1]):
if img[y, x] > 0:
a = int(x - r * np.cos(np.deg2rad(t)))
b = int(y - r * np.sin(np.deg2rad(t)))
if a >= 0 and b >= 0 and a < img.shape[1] and b < img.shape[0]:
hough_acc[r_idx, t_idx] -= 1
return best_circles
# 测试代码
img = np.zeros((100, 100))
img[50, 50] = 1
img[40, 60] = 1
img[60, 60] = 1
circles = find_circles(img, 1, 10, 30)
for r, t in circles:
a = int(50 - r * np.cos(np.deg2rad(t)))
b = int(50 - r * np.sin(np.deg2rad(t)))
img[a-2:a+2, b-2:b+2] = 1
plt.imshow(img)
plt.show()
```
这个实现基于霍夫变换来检测圆形,它计算每个像素对于所有可能的圆心和半径的贡献,并在累加器中计算每个组合的得分。最后,它找到最可能的圆形并从累加器中删除,以便找到下一个最可能的圆形。
阅读全文