根据上一篇博客可知,单纯的通过求取最大面积而进行定位的局限性,因此我们接下来将通过cv2.moments()和cv2.HuMoments()这两个方法来在更复杂的环境中去找到我们的目标区域。

cv2.moments():

参数:

  • array:表示输入图像的单通道数组。通常是灰度图像,可以是8位或浮点型。
  • binaryImage:一个可选参数,如果设置为 True,则将 array 视为二进制图像。默认为 False。

返回值:

  • moments:一个包含图像矩特征信息的字典对象。这些矩包括图像的原始矩、中心矩以及一些其他相关的信息。您可以使用这些矩特征来描述图像的几何形状和分布情况。

cv2.HuMoments():

参数:

  • moments:一个字典对象,包含通过 cv2.moments() 函数计算得到的图像矩特征。

返回值:

  • huMoments:一个包含7个不变矩特征值的一维数组。这些特征值对图像的形状、轮廓和几何特征进行了描述。通常用于图像识别和匹配。

  简易的介绍一下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()

参数:

  • contour1:第一个轮廓,通常是一个包含点集的 NumPy 数组。
  • contour2:第二个轮廓,也是一个包含点集的 NumPy 数组。
  • method:表示相似性度量方法的整数值。可以是 1、2 或 3,分别代表不同的计算方法。

返回值:

  • match:一个表示两个轮廓之间相似性的浮点数值。该值越小表示两个轮廓形状越相似。

至此,当我们所得到的图像源包含了其他复杂的图形时,我们则可以使用矩特性来进一步提高我们的检测能力,但是还有其他更为复杂的场景,所以还需要优化我们的解决思路。

使用cv2.matchShapes()方法找寻目标区域Code:(在上一篇博客的代码基础上修改)

  红框是添加和修改区域,绿框是注释掉了一些代码,值得注意的是,matchShapes方法中的第四个参数会要求传入值,但是通过查找OpenCV官方文档显示该参数没有对应方法,所以查找了其他相关信息后,填入0

或者0.0都是可以的,至于修改膨胀次数是因为需要减少多余轮廓的干扰,否则可能有些小轮廓出现返回值是0.0的情况。。

结果图:

通过拍摄不同角度的图片,得到的效果都是比较让人满意的

通过上述图片可以看到,针对不同程度的深度,都可以较为精准的绘制出目标区域,不过这个方法还是有两个问题点:

1、barcode线段需要尽量垂直于水平方向,否则就需要去修改sobel的卷积核。

2、需要有准备工作,要提前准备好待识别目标区域的Hu矩数据。

上述问题将再下一篇博客中进行改进。

【Python】【OpenCV】定位条形码(二)moments和HuMoments的更多相关文章

  1. Python+OpenCV图像处理(二)——打印图片属性、设置图片存储路径、电脑摄像头的调取和显示

    一. 打印图片属性.设置图片存储路径 代码如下: #打印图片的属性.保存图片位置 import cv2 as cv import numpy as np #numpy是一个开源的Python科学计算库 ...

  2. python笔记 利用python 自动生成条形码 二维码

    1. ean13标准条形码 from pystrich.ean13 import EAN13Encoder encode = EAN13Encoder(') encode.save('d:/barco ...

  3. Python+opencv打开修图的正确方式get

    先逼逼两句: 图像是 Web 应用中除文字外最普遍的媒体格式. 流行的 Web 静态图片有 JPEG.PNG.ICO.BMP 等.动态图片主要是 GIF 格式.为了节省图片传输流量,大型互联网公司还会 ...

  4. Python zxing 库解析(条形码二维码识别)

    各种扫码软件 最近要做个二维码识别的项目,查到二维码识别有好多开源的不开源的软件 http://www.oschina.net/project/tag/238/ Zbar 首先试了一下Zbar,pyt ...

  5. Opencv+Zbar二维码识别(标准条形码/二维码识别)

    使用Opencv+Zbar组合可以很容易的识别图片中的二维码,特别是标准的二维码,这里标准指的是二维码成像清晰,图片中二维码的空间占比在40%~100%之间,这样标准的图片,Zbar识别起来很容易,不 ...

  6. python appium笔记(二):元素定位

    #这里的示例是用android来说明的,xpath应该是通用的,resource-id不太清楚,没配过IOS的环境 #环境配置和一些参数的意思不清楚可以看我上一篇python appium笔记(一) ...

  7. python+opencv实现车牌定位

    写在前面 HIT大三上学期视听觉信号处理课程中视觉部分的实验三,经过和学长们实验的对比发现每一级实验要求都不一样,因此这里标明了是2019年秋季学期的视觉实验三. 由于时间紧张,代码没有进行任何优化, ...

  8. python opencv识别蓝牌车牌号 之 取出车牌号 (1/3)

    概述 车牌识别是计算机视频图像识别技术在车辆牌照识别中的一种应用,通常来讲如果结合opencv进行车牌识别主要分为四个大步骤,分别为: 图像采集 车牌定位 分割车牌字符 字符识别 当然,如果结合了机器 ...

  9. .NET + OpenCV & Python + OpenCV 配置

    最近需要做一个图像识别的GUI应用,权衡了Opencv+ 1)QT,2)Python GUI,3).NET后选择了.NET... 本文给出C#+Opencv和Python+Opencv的相应参考,节省 ...

  10. RPi 2B python opencv camera demo example

    /************************************************************************************** * RPi 2B pyt ...

随机推荐

  1. 【译】IntelliJ IDEA 2023.2 最新变化——JetBrains IDE 中的 AI 助手

    前言 本周所有基于 IntelliJ 的 IDE 和 .NET 工具的 EAP 版本都包含一个主要新功能:AI Assistant.本博文重点介绍我们基于 IntelliJ 的 IDE,并且即将推出专 ...

  2. CSP-J/S 初赛冲刺

    CSP-J/S 初赛冲刺 对于咱们信奥选手来说,会做的题要坚决不丢分,不会做的题要学会尽量多拿分,这样你的竞赛之路才能一路亨通! Linux 基础操作 文件(文件夹)操作 列出文件:ls 列出隐藏文件 ...

  3. C++的动态分派在HotSpot VM中的重要应用

    众所周知,多态是面向对象编程语言的重要特性,它允许基类的指针或引用指向派生类的对象,而在具体访问时实现方法的动态绑定.C++ 和 Java 作为当前最为流行的两种面向对象编程语言,其内部对于多态的支持 ...

  4. WPF中以MVVM方式,实现RTSP视频播放

    前言视频播放在上位机开发中经常会遇到,基本上是两种常见的解决方案 1.采用厂家提供的sdk和前端控件进行展示,常见的海康/大华都提供了相关sdk及文档 2.开启相机onvif协议,捅过rtsp视频流进 ...

  5. 解决软件安装无法自定义文件夹,自动安装在C盘 (Windows系统)

    其实就是软链接的简单应用 1.软件已经自动安装 2.完全退出当前软件 3.通过软件图标的属性找到其实际的安装目录 4.进入该软件的安装目录 5.将该软件整个剪切(你没有看错)到指定文件夹(自定义的安装 ...

  6. os --- 多种操作系统接口¶

    os.path --- 常用路径操作 源代码: Lib/posixpath.py (用于 POSIX) 和 Lib/ntpath.py (用于 Windows). 此模块实现了一些有用的路径名称相关函 ...

  7. MySQL PXC集群新增一个高版本节点

    已有的一个 MySQL PXC 集群环境,因为种种原因仅剩一个节点 node1,需要新增一个集群节点 node2. node1 版本:donor version (8.0.21) node2 版本:l ...

  8. Java面向对象编程的三大特性:封装、继承、多态。

    一.封装 封装的核心在于私有化(private),大部分情况下,来封装对象的属性,很少有封装方法的.通过将对象的属性封装,提供对外的公共方法来访问属性是最常见的方式. public static cl ...

  9. Java代码审计之目录穿越(任意文件下载/读取)

    一.目录穿越漏洞 1.什么是目录穿越 所谓的目录穿越指利用操作系统中的文件系统对目录的表示.在文件系统路径中,".."表示上一级目录,当你使用"../"时,你正 ...

  10. easyxor

    怎么都写不出脚本,看了题解还是蒙蒙的,不过以后遇到这种题也可以根据提示了解他到底怎么出题的,题目明面说了xor 那就主要关注xor以后的结果和xor的对象.方法就好了,其他的就不要去管了 然后对于汇编 ...