识别图片中的圆形并求所有圆形的平均半径
思路:</br> 1)对图片进行预处理;</br> 2)利用opencv,借助霍夫梯度法识别图像中的圆形;</br> 3)在原图像中标记出识别到的圆形,并计算识别到的圆的平均半径。</br>
实现过程:</br>
待识别图像:</br>
一、图像预处理
思路:</br> 对图像进行epf边缘滤波,减小圆形识别的干扰;将图像转换成灰度图像。</br>
具体实现:</br> epf边缘滤波:
temp = cv.pyrMeanShiftFiltering(img, 2, 30)
灰度处理:
cimg = cv.cvtColor(temp, cv.COLOR_RGB2GRAY)
二、圆形识别
思路:</br> 利用opencv的霍夫梯度法识别图像中的圆形。</br>
具体实现:</br>
circles = cv.HoughCircles(cimg,
cv.HOUGH_GRADIENT,
1,
20,
param1=50,
param2=30,
minRadius=20,
maxRadius=50)
circles = np.uint16(np.around(circles))
for i in circles[0, :]:
cv.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2) # 圆
cv.circle(img, (i[0], i[1]), 2, (255, 255, 0), 2) # 圆心
识别结果:</br>
三、平均半径计算
思路:</br> 根据比例尺计算出每个像素对应的、长度,再依次得到每个识别到的圆的半径,最后得到平均半径。</br>
具体实现:</br> 比例尺的计算:
# ruler计算
ruler_img = cv.imread(图像中比例尺的单独截图路径)
ruler_size = np.shape(ruler_img)
length = 0
for i in range(len(ruler_size)):
if length < ruler_size[i]:
length = ruler_size[i]
l_cons = 78
delta_pixle = l_cons / length
平均半径的计算:
# 平均半径计算
cnt = 0
sum_r = 0
x = []
y = []
radius = []
for circle in circles:
cnt += 1
sum_r += circle[2]
x.append(circle[0])
y.append(circle[1])
radius.append(circle[2])
ava_radius = sum_r / cnt
ava_radius *= delta_pixle
# 圆心坐标
for i in range(len(x)):
x[i] *= delta_pixle
for i in range(len(y)):
y[i] *= delta_pixle
完整代码:</br>
为方便代码的修改,把各个单独的功能的代码放在了独立的文件中,文件结构如下图:</br>
文件结构:</br>
./main.py
import sys
sys.path.append(
"/home/taot/Python/Useful_tools/circle_analyse_1/assistant_func")
import read_preprocess as rp
import circle_detection as cd
import cal_ava_radius as car
import cv2 as cv
pic = rp.pre_pro("/home/taot/Python/Useful_tools/circle_analyse_1/data.jpg")
img = pic[0]
cimg = pic[1]
ans = cd.cir_dec(img, cimg)
res = ans[0]
cv.imwrite("/home/taot/Python/Useful_tools/circle_analyse_1/res.png", res)
circles = ans[1][0]
ava_radius = car.ava_r(circles)
print("The avarage radius is: {}微米".format(ava_radius))
./read_preprocess.py
import cv2 as cv
import numpy as np
def pre_pro(pic_name):
img = cv.imread(pic_name)
cv.imshow("input img", img)
cv.waitKey(0)
cv.destroyAllWindows()
# epf边缘滤波
temp = cv.pyrMeanShiftFiltering(img, 2, 30)
cv.imshow("epf", temp)
cv.waitKey(0)
cv.destroyAllWindows()
# 灰度处理
cimg = cv.cvtColor(temp, cv.COLOR_RGB2GRAY)
cv.imshow("gray", cimg)
cv.waitKey(0)
cv.destroyAllWindows()
return (img, cimg)
./circle_detection.py
import sys
sys.path.append(
"/home/taot/Python/Useful_tools/circle_analyse_1/assistant_func")
import read_preprocess as rp
import cv2 as cv
import numpy as np
def cir_dec(img, cimg):
circles = cv.HoughCircles(cimg,
cv.HOUGH_GRADIENT,
1,
20,
param1=50,
param2=30,
minRadius=20,
maxRadius=50)
circles = np.uint16(np.around(circles))
for i in circles[0, :]:
cv.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2) # 圆
cv.circle(img, (i[0], i[1]), 2, (255, 255, 0), 2) # 圆心
cv.imshow("res", img)
cv.waitKey(0)
cv.destroyAllWindows()
return (img, circles)
./cal_ava_radius.py
import numpy as np
import cv2 as cv
def ava_r(circles):
# ruler计算
ruler_img = cv.imread(
"/home/taot/Python/Useful_tools/circle_analyse_1/ruler.png")
ruler_size = np.shape(ruler_img)
length = 0
for i in range(len(ruler_size)):
if length < ruler_size[i]:
length = ruler_size[i]
l_cons = 78
delta_pixle = l_cons / length
# 平均半径计算
cnt = 0
sum_r = 0
x = []
y = []
radius = []
for circle in circles:
cnt += 1
sum_r += circle[2]
x.append(circle[0])
y.append(circle[1])
radius.append(circle[2])
ava_radius = sum_r / cnt
ava_radius *= delta_pixle
for i in range(len(x)):
x[i] *= delta_pixle
for i in range(len(y)):
y[i] *= delta_pixle
np.savetxt("/home/taot/Python/Useful_tools/circle_analyse_1/x.txt", x)
np.savetxt("/home/taot/Python/Useful_tools/circle_analyse_1/y.txt", y)
np.savetxt("/home/taot/Python/Useful_tools/circle_analyse_1/radius.txt",
radius)
return ava_radius