opencv图像处理与霍夫找圆

该文使用OpenCV库进行图像处理,包括灰度化、阈值处理、中值滤波、边缘检测和霍夫圆变换来寻找图像中的圆。通过霍夫圆变换找到圆心坐标和半径,进一步计算圆的面积和圆度。最后,提取并显示最大轮廓的圆度信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

要求:求出下图中心拟合圆的圆心坐标与半径,以及轮廓圆的面积与圆度。

在这里插入图片描述

import cv2
import numpy as np
import math
#读图
img=cv2.imread('jpg/3.jpg')

#图太大,方便观看,缩小为原来的0.4倍
resize = cv2.resize(img,dsize=None,fx=0.4,fy=0.4,interpolation=cv2.INTER_LINEAR)
cv2.imshow('ori',resize)
#灰度化
gray = cv2.cvtColor(resize, cv2.COLOR_BGR2GRAY)
#阈值
ret, img = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 中值滤波 效果好
img_median = cv2.medianBlur(img, 5)
#膨胀一下,方便观看
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 1))
dst = cv2.dilate(img_median, kernel)
#边缘检测
canny = cv2.Canny(dst, 50, 150)
#霍夫找圆
circles = cv2.HoughCircles(canny,cv2.HOUGH_GRADIENT,1,700,param1=100,param2=20,minRadius=20,maxRadius=800)#霍夫圆变换
#第3参数默认为1
#第4参数表示圆心与圆心之间的距离(太大的话,会很多圆被认为是一个圆)
#第5参数默认为100
#第6参数根据圆大小设置(圆越小设置越小,检测的圆越多,但检测大圆会有噪点)
#第7圆最小半径
#第8圆最大半径
circles = np.uint16(np.around(circles))
#np.uint16数组转换为16位,0-65535
#np.around返回四舍五入后的值

 #遍历找到圆形
P=circles[0]#去掉circles数组一层外括号
for i in P:
    # 画出外圆
    cv2.circle(resize,(i[0],i[1]),(i[2]),(0,255,0),2)#第二参数()内是圆心坐标,第三参数是半径,第四参数()内是颜色,第五参数是线条粗细
    # 画出圆心
    cv2.circle(resize,(i[0],i[1]),2,(0,0,255),3)
    #roi的掩码
    roi = np.zeros(img_median.shape[:2], np.uint8)
    #加上3的话,方便看圆度
    roi = cv2.circle(roi, (i[0],i[1]),(i[2]+3), 255, cv2.FILLED)

#根据找出的圆来进行Roi合成
mask = np.ones_like(img_median) * 255
mask = cv2.bitwise_and(mask, img_median, mask=roi)  + cv2.bitwise_and(mask, mask, mask=~roi)
#霍夫找圆的结果
print("圆的个数是:")
print(len(P))
for i in P:
    r=int(i[2])
    x=int(i[0])
    y=int(i[1])
    print("圆心坐标为:",(x,y))
    print("圆的半径是:",r)
cv2.imshow('detected circles',resize)#第一参数为窗口名称

#roi区域进行处理
gaussian = cv2.GaussianBlur(mask, (3, 3), 0)
canny1 = cv2.Canny(gaussian, 50, 150)
cv2.imshow('canny1',canny1)

#对roi区域进行找轮廓,现在是实际圆形的轮廓
contours1, hierarchy = cv2.findContours(canny1,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
IMG_OUT = cv2.cvtColor(mask, cv2.COLOR_GRAY2RGB)
cv2.drawContours(IMG_OUT,contours1,-1,(0,0,255),1)
cv2.imshow('mask after operation', IMG_OUT)


#根据找出的轮廓找出最大的一个轮廓,就是那个圆
img_contours = []
for i in range(len(contours1)):
    area = cv2.contourArea(contours1[i], False)
    if area > 10000:
        print("轮廓%d的面积是: %d" % (i, area))
        cv2.drawContours(resize, contours1, i, (0, 0, 255), 1)
        cv2.imshow("contours %d" % i, resize)

# 圆度计算公式:
# 4*PI*A/P^2
# 其中PI表示Π,A表示区域面积,P表示区域周长
        a = cv2.contourArea(contours1[i]) * 4 * math.pi
        b = math.pow(cv2.arcLength(contours1[i], True), 2)
        circulation= a / b
        print("圆度",circulation)
cv2.waitKey(0)



 

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值