本次识别的目标是识别图片中的圆形和椭圆,由于霍夫变换可以识别圆形但是无法直接识别椭圆,所以直接使用了识别轮廓的方法。
具体步骤:
1、读取图像并进行灰度值转化
2、对转化灰度值后的图像进行二值化处理
3、进行轮廓检测
4、对所有轮廓进行遍历
5、求出所有轮廓的周长,筛选我们需要的周长范围
6、获取轮廓中心存入列表
7、对轮廓中心列表进行遍历,通过我们所需识别形状的位置对列表进行切片操作
8、对选出来的轮廓进行绘制即可
示例代码:
import cv2
import math
import numpy as np
def oval(img):
# 进行灰度图转化
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Canny边缘检测,参数可更改
# imgray = cv2.Canny(img, 0, 210, 3)
# cv2.imwrite('1.png', imgray)
# 图像阈值处理(二值化处理)
ret, thresh = cv2.threshold(imgray, 0, 255, cv2.THRESH_BINARY)
# cv2.imwrite('1.png', thresh)
# 轮廓检测
image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_CCOMP,
cv2.CHAIN_APPROX_NONE) # contours为轮廓集,可以计算轮廓的长度、面积等
# 创建轮廓中心列表
center_list = []
# 对所有轮廓进行遍历
for i, cnt in enumerate(contours):
# 计算轮廓周长
perimeter = cv2.arcLength(cnt, True)
# 确定我们想要的轮廓周长范围(根据自己需要识别的轮廓大致周长进行更改)
if 0 < perimeter < 100:
# 计算轮廓中心
center, radius = cv2.minEnclosingCircle(contours[i])
# 将轮廓中心和轮廓存入列表
center_list.append((int(center[0]), int(center[1]), cnt))
# 判断存了多少个轮廓,如果大于6就取列表两边(根据自己需要识别的形状进行更改)
if len(center_list) >= 6:
center_list = sorted(center_list)
if center_list[0][0] <= 200:
center_list = center_list[0: 4] + center_list[-3:]
else:
center_list = center_list[0: 3] + center_list[-3:]
# 遍历列表,进行轮廓绘制及添加坐标
for i in center_list:
# 绘制轮廓中心
cv2.circle(img, (i[0], i[1]), 2, (0, 0, 255), 3)
# 绘制坐标
cv2.putText(img, f'({i[0]}, {i[1]})', (i[0] - 20, i[1] - 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)
# 绘制轮廓
cv2.drawContours(img, i[2], -1, (0, 255, 0), 2)
cv2.imwrite('output.png', img)
# cv2.imshow('output', img)
# 读取图像(根据自己的路径进行更改)
img = cv2.imread("./image/test.png", 3)
# 识别轮廓
img = oval(img)
cv2.waitKey(0)
cv2.destroyAllWindows()