步骤
1. 转为灰度图像
2. 预处理(滤波降噪/直方图均衡化/傅里叶变换等)
3. canny边缘提取(二值图像)
4. 开操作或膨胀(去除毛刺)
5. 检测外轮廓
6. 轮廓最小外接矩形/圆
7. 通过轮廓长宽比,宽高范围,找到有价值的区域
提取边缘
用模板扩大差异,如果是边缘,则幅度比较大
1. sobel算子:cv2.Sobel
gx = [[-1,0,1],[-2,0,2],[-1,0,1]] (比较左右像素的差异,其实是右边值-左边值,取差异(需要取绝对值 cv2.convertScaleAbs))
gy = [[-1,-2,-1],[0,0,0],[1,2,1]] (比较上下像素的差异)
总梯度 = sqrt(gx^2 + gy^2)
2. scharr算子:cv2.Scharr 比sobel敏感,扩大了差异
gx = [[-3,0,3],[-10,0,10],[-3,0,3]]
gy = [[3,10,3],[0,0,0],[-3,-10,-3]]
3. 拉普拉斯:cv2.Laplacian
g = [[0,1,0],[1,-4,1],[0,1,0]] (二阶导,比较周围和中间点)
4. Canny边缘检测:cv2.Canny
a. 高斯滤波(过滤噪音)
b. 计算图像中每个像素点的梯度强度和方向
c. 应用极大值抑制,去除小的梯度值,保留大的梯度值(显示明显的边缘)
d. 应用双阈值检测确定真实的边缘
i. 小于minValue则舍弃
ii. 大于maxValue则认为是边界保留
iii. 其它的, 连有边界保留
iv. minValue/maxValue的范围越大,要求越低,获取的边缘越多
e. 抑制孤立的弱边沿
5. 梯度运算:膨胀-腐蚀,获取边缘
形态学
1. 二值化:cv2.threshold
2. 腐蚀:cv2.erode 满足模板的点留下,不满足舍弃
3. 膨胀:cv2.dilate 按模板扩展
4. 开运算:cv2.morphologyEx 先腐蚀再膨胀(去掉毛刺,再恢复大小)
5. 闭运算:cv2.morphologyEx 先膨胀再腐蚀
6. 顶帽:原始-开运算(得到毛刺)
7. 黑帽:闭运算-原始
二值图像轮廓
1. 查找轮廓
cv2.findContours(img, mode)
a. 检测轮廓
cv2.RETR_EXTERNAL 只检索最外面的轮廓
cv2.RETR_LIST 所有轮廓,保存到链表中
cv2.RETR_CCOMP 所有轮廓,保存外部边界,内部边界
cv2.RETR_TREE 嵌套轮廓的层次
b. 轮廓逼近方法
cv2.CHAIN_APPROX_NONE 多变形
cv2.CHAIN_APPROX_SIMPLE 压缩,水平、垂直、斜线,只保留起止点
2. 绘制轮廓
cv2.drawContours() 轮廓 轮廓索引 颜色 宽度
3. 轮廓面积
cv2.contourArea()
4. 周长 闭合
cv2.arcLength()
5. 轮廓近似
cv2.approxPolyDP()
6. 边界矩形
x,y,w,h=cv2.boundingRect()