元器件图像识别计数

最近接触到了关于小物体图像计数方面的问题,从网上搜索出来的大部分都是基于分水岭算法的项目实践。尝试学习了解,在此回顾一下自身理解:

首先自己找了一些元器件进行实验,原图为:

识别效果图为:

代码基于opencv实现,实现过程为:

1.图像二值化:根据设置阈值分割将图像前景背景分离;

2.数学形态学操作(开操作,腐蚀):去除噪声并且消除二值化带来的孔洞;

3.距离变换:计算图像中每个非零像素点与其最近的零像素点之间的距离,输出的是保存每个非零点的距离信息;

4.根据距离变换得到的结果进行二值化操作;

5.根据二值化图勾画轮廓;

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

img = cv2.imread('C:/Users/wang/Pictures/picture/10.jpg') # 读取图片
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度图转化

ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # 图像二值化,cv2.THRESH_BINARY+cv2.THRESH_OTSU作用是自适应阈值,cv2.THRESH_BINARY与cv2.THRESH_BINARY_INV二值化效果相反

kernel = np.ones((5, 5), np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2) # 开操作:去除噪声,去除孔洞
sure_bg = cv2.dilate(opening, kernel, iterations=3) # 腐蚀操作:减小前景物体,初步分离前景中的粘连物体

dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5) # 距离变换:得到每个非零像素点与其最近的零像素点之间的距离,输出为距离
print(dist_transform.max())
_, sure_fg = cv2.threshold(dist_transform, 0.53*dist_transform.max(), 255, 0) # 二值化操作,阈值为距离变换得到的距离,从而缩小前景物体,主要为了分离前景中的粘连物体
sure_fg = np.uint8(sure_fg) # 转化数据类型,连通域函数接收8位单通道二值图像

_, labels, stats, centroids = cv2.connectedComponentsWithStats(sure_fg) # 连通域函数:label与原图大小一致,对应为当前像素为第几个轮廓;stats对应轮廓信息,每行有五个值,分别为x,y,width,height,area;centroids对应每个连通区域的质心点
for i in range(1, len(centroids)):
    cv2.circle(img, (int(centroids[i, 0]), int(centroids[i, 1])), 6, [0, 0, 255], -1) # 勾画质心点,实心圆
    cv2.putText(img, str(i), (int(centroids[i, 0]), int(centroids[i, 1])), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255)) # 标记对应质心点的编号,最大值为个数-1
print('计数个数:', len(centroids)-1)
cv2.imshow('img', img)
cv2.imwrite('img.jpg', img)

cv2.waitKey()
cv2.destroyAllWindows()

1.识别结果错误一个,图像中为粘连物体,没有分割成功,精度已经很高。这只是分水岭算法的一种实现方式,处理方式多样化。有些实现方式是将图片进行边缘检测,根据检测到的结果与二值化分割出的前景特征结合,生成markers标记图像,使用watershed函数勾画轮廓。本篇代码中没有用到markers标记,个人理解为markers目前用于watershed函数,得到的结果是分离出来的前景的轮廓。但是精度相对比较低,分割的前景区域对于分割粘连物体貌似没什么太大的作用,而且对于本身不想连的物体分割结果也是在同一个区域中。可尝试的思路或许是使用markers与原图结合初步勾画轮廓,然后在此基础上进行分割。没有常识过不知效果如何,感觉第一次勾画出来的轮廓,可能特征比较明显会相对影响第二次分割的效果。

2.边缘检测中算子的运算不是很难理解,可以尝试底层的运算。

猜你喜欢

转载自www.cnblogs.com/aprilspring-emotion/p/11103338.html