cv2.moments():
参数:
返回值:
cv2.HuMoments():
参数:
cv2.moments()
函数计算得到的图像矩特征。返回值:
简易的介绍一下moments(矩)这个东西,它是用来描述一个形状的特性,比如说正方形,我们能分辨出来是因为知道其四个边是相等的,这便是在我们的认知中所知的正方形的轮廓特性,而在计算机中呈现的就是一组数据,通过和这组数据进行比对,我们就可以较为准确的去寻找我们的目标区域。
但是相较于上一篇博客的直接在输入图像中查找,使用矩我们需要事先获取目标的完整轮廓,并保存其矩特性数据。
图像准备,一张没有完整的只有barcode的图像
Code:
1 import cv2 2 import numpy 3 4 img = cv2.imread('../images/barcode.jpg') 5 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 6 kernel_x = numpy.array( 7 [ 8 [-1, 0, 1], 9 [-2, 0, 2], 10 [-1, 0, 1] 11 ] 12 ) 13 sobel_x = cv2.filter2D(gray, -1, kernel_x) 14 _, thresh = cv2.threshold(sobel_x, 127, 255, cv2.THRESH_BINARY) 15 kernel_ed = numpy.ones((3, 3), dtype=numpy.uint8) 16 img_d = cv2.dilate(thresh, kernel_ed, iterations=6) 17 contours, hir = cv2.findContours(img_d, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 18 print(cv2.HuMoments(cv2.moments(contours[0]))) 19 cv2.drawContours(img, contours, -1, (0, 255, 0), 3) 20 cv2.imshow('', img) 21 cv2.waitKey() 22 cv2.destroyAllWindows()
Result:
我就直接和上一篇博客的barcode的轮廓矩特性进行对比:
只有barcode图 包含其他图形的barcode图
通过对比数据我们可以发现,在第1不变矩中,数据是最接近的,这个时候就可以利用这个特性数据来进行轮廓特征比对寻找目标区域。
如果觉得麻烦的话,OpenCV还提供了一个方法为我们减免了比较的操作cv2.matchShapes()方法。
cv2.matchShapes()
参数:
返回值:
至此,当我们所得到的图像源包含了其他复杂的图形时,我们则可以使用矩特性来进一步提高我们的检测能力,但是还有其他更为复杂的场景,所以还需要优化我们的解决思路。
使用cv2.matchShapes()方法找寻目标区域Code:(在上一篇博客的代码基础上修改)
红框是添加和修改区域,绿框是注释掉了一些代码,值得注意的是,matchShapes方法中的第四个参数会要求传入值,但是通过查找OpenCV官方文档显示该参数没有对应方法,所以查找了其他相关信息后,填入0
或者0.0都是可以的,至于修改膨胀次数是因为需要减少多余轮廓的干扰,否则可能有些小轮廓出现返回值是0.0的情况。。
结果图:
通过拍摄不同角度的图片,得到的效果都是比较让人满意的
通过上述图片可以看到,针对不同程度的深度,都可以较为精准的绘制出目标区域,不过这个方法还是有两个问题点:
1、barcode线段需要尽量垂直于水平方向,否则就需要去修改sobel的卷积核。
2、需要有准备工作,要提前准备好待识别目标区域的Hu矩数据。
如果您发现该资源为电子书等存在侵权的资源或对该资源描述不正确等,可点击“私信”按钮向作者进行反馈;如作者无回复可进行平台仲裁,我们会在第一时间进行处理!
加入交流群
请使用微信扫一扫!