第一次写关于水果识别的博客
在水果识别中发现:由于在复杂的背景下,由于机器人摄像头的位置以及角度都未固定,无论是天空还是其他背景都会照成较为大的干扰,但是最终在识别过程中发现最大的影响因素在于光照的影响,这会影响背景分割以及最后的通过分水岭分割的效果,如果仅仅是对单个水果受到光照影响那么对最后的结果影响不会很大,但是在复杂的水果重叠遮挡过程中出现光照的影响那么对于最后的检测会照成巨大的误差。
首先是对获取的样本照片的去噪方式
论文上使用较多的方式是双边滤波或者中值滤波
img_bilater = cv2.bilateralFilter(img, 9, 75, 75) # 双边滤波
双边滤波是一种非线性滤波器,它可以达到保持边缘、降噪平滑的效果。和其他滤波原理一样,双边滤波也是采用加权平均的方法,用周边像素亮度值的加权平均代表某个像素的强度,所用的加权平均基于高斯分布。
双边滤波的核函数是空间域核与像素范围域核的综合结果:在图像的平坦区域,像素值变化很小,对应的像素范围域权重接近于1,此时空间域权重起主要作用,相当于进行高斯模糊;在图像的边缘区域,像素值变化很大,像素范围域权重变大,从而保持了边缘的信息。
参考一
参考二
img_median = cv2.medianBlur(img, 5) # 中值滤波
中值滤波采用非线性的方法,它在平滑脉冲噪声方面非常有效,同时它可以保护图像尖锐的边缘,选择适当的点来替代污染点的值,所以处理效果好,对椒盐噪声表现较好,对高斯噪声表现较差
在对图片样本去噪之后我们发现由于后期需要对图像进行空洞填充,若是某些情况则会造成全部填充的效果,所以在外边加上一个矩形黑色边界。
img = cv2.copyMakeBorder(img, 10, 10, 10, 10, cv2.BORDER_CONSTANT, (0, 0, 0)) # 在原图外边加上矩形框
对于复杂的带有噪声的图像而言,对其进行了一定的去噪处理之后,就要在复杂的背景中提取我们所需要的目标物体。
目前我所使用的有三种方式:归一化色差,KMeans聚类算法,FCM算法。其中还是归一化色差方法简单并且效果最好,以下依次描述并且随时更新,改进方法。
归一化色差
归一化色差表达式如下:S=2(R+G+B))255(2R+B))
根据这一表达式遍历图像中没一点,得到的S值,做阈值处理,一般设置以130~160均可,可以将果实从背景中分割出来。
代码如下:
import cv2
import numpy as np
'''
此函数通过归一化色差实现图像分割
输入:原图像
输出:分割背景后的彩色橘子图像
'''
def orange_detect(pic):
# 由于边缘检测很容易受到噪声影响,所以第一步是使用5x5 的高斯滤波器去除噪声
pic = cv2.GaussianBlur(pic, (5, 5), 0)
s = np.int8(0)
# cv2.imshow("Pic", pic)
# pic = cv2.pyrDown(pic) # 缩小点图片的尺寸
# print(pic)
# gray = cv2.cvtColor(pic, cv2.COLOR_BGR2GRAY)
# blur = cv2.GaussianBlur(gray, (5, 5), 0)
for row in range(pic.shape[0]):
for col in range(pic.shape[1]):
b = int(pic[row, col, 0])
# print(b)
g = int(pic[row, col, 1])
# print(g)
r = int(pic[row, col, 2])
# print(r)
if r + g + b != 0:
s = (255 * (2 * r + b)) / (2 * (r + g + b))
# s = int(s)
# print(s)
if s < 130:
pic[row, col, :] = -0.0
return pic
在此设置的阈值为130,若是把阈值加大则会减少得到的前景目标也就是得到的目标更加苛刻,在测试过程中发现其实130的效果较为好,分割的效果如下: