liangwl1751 2022-02-14 21:55 采纳率: 100%
浏览 98
已结题

如何用Python+opencv检测此图像中的所有圆?

我用了cv.HoughCircles函数,但不会选择合适的参数,效果不好。
原图:

img


结果:

img

{

```

```import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

def show(img):
if img.ndim == 2:
plt.imshow(img,cmap='gray')
else:
plt.imshow(cv.cvtColor(img,cv.COLOR_BGR2RGB))
plt.show()

img=cv.imread('C:/Users/1/Desktop/img/test.jpg')
gray=cv.cvtColor(img, cv.COLOR_BGR2GRAY)

dst = cv.equalizeHist(gray)#应用直方图均衡化
gaussian = cv.GaussianBlur(dst,(9,9),0)
#利用Canny进行边缘检测
GrayImage = cv.Canny(gaussian, 20,180, apertureSize=3)
ret, th1 = cv.threshold(GrayImage, 127, 255, cv.THRESH_TOZERO) # 固定阈值二值化
th2 = cv.adaptiveThreshold(th1, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 3, 5)
th3 = cv.adaptiveThreshold(th2, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 3, 5)
kernel = np.ones((6, 9), np.uint8)
erosion = cv.erode(th3, kernel, iterations=1) # 腐蚀处理
dilation = cv.dilate(erosion, kernel, iterations=1) # 膨胀处理
imgray = cv.Canny(erosion, 3, 8) # Canny算子边缘检测

circles = cv.HoughCircles(imgray, cv.HOUGH_GRADIENT, 1, 40, param1=100, param2=6, minRadius=8,maxRadius=10)

circles = np.uint16(np.around(circles))
P = circles[0] # 去掉circles数组一层外括号
for i in P:
cv.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 5)
cv.circle(img, (i[0], i[1]), 5, (0, 0, 255), 3)

show(img)
}

我参考了一些博主的文章,链接:https://blog.csdn.net/SouthWooden/article/details/98741985

  • 写回答

3条回答 默认 最新

  • 默执_ 2022-02-15 10:41
    关注

    废话不多说,直接上代码

    img

    import cv2
    import numpy as np
    
    
    def cv_show(neme, img):
        cv2.imshow(neme, img)  
        cv2.waitKey(0)  
        cv2.destroyAllWindows()  
    
    
    image = cv2.imread('1.jpg')
    img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    # Canny 边缘检测(图像、min值、max值)
    edges = cv2.Canny(img, 7, 12)
    ret, thresh1 = cv2.threshold(edges, 127, 255, cv2.THRESH_BINARY)
    
    # 膨胀操作
    kernel1 = np.ones((5, 5), np.uint8)
    # 换个封装函数,膨胀      当前载入 腐蚀后--膨胀
    erosion = cv2.dilate(thresh1, kernel1, iterations=1)
    
    kernel = np.ones((3, 3))
    # 腐蚀操作
    sb = cv2.erode(erosion, kernel, iterations=1)
    
    cv_show("s", thresh1)
    cv_show("name", erosion)
    cv_show('sda', sb)
    
    # 轮廓查询
    contours, hierarchy = cv2.findContours(sb, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    
    for i in range(len(contours)):
        # 轮廓外接圆
        (x, y), radius = cv2.minEnclosingCircle(contours[i])
        center = (int(x), int(y))
        radius = int(radius)
    
        # 轮廓区域
        # 轮廓面积
        area = cv2.contourArea(contours[i])
        if 300 <= area < 2000:
            image = cv2.circle(image, center, radius, (0, 0, 255), 1)
    
    cv_show('sad', image)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 2月16日
  • 已采纳回答 2月15日
  • 修改了问题 2月15日
  • 赞助了问题酬金5元 2月14日
  • 展开全部

悬赏问题

  • ¥15 求高通平台Softsim调试经验
  • ¥15 canal如何实现将mysql多张表(月表)采集入库到目标表中(一张表)?
  • ¥15 wpf ScrollViewer实现冻结左侧宽度w范围内的视图
  • ¥15 栅极驱动低侧烧毁MOSFET
  • ¥30 写segy数据时出错3
  • ¥100 linux下qt运行QCefView demo报错
  • ¥50 F1C100S下的红外解码IR_RX驱动问题
  • ¥20 基于matlab的航迹融合 航迹关联 航迹插补
  • ¥15 用Matlab实现图中的光线追迹
  • ¥15 联想笔记本开机出现系统更新界面