根据上一篇博客可知,单纯的通过求取最大面积而进行定位的局限性,因此我们接下来将通过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. VB快速上手文档教程

    前言 本来我想可能不会接触到这个语言, 不过在用excel时需要用到VBA. 这就不得不专门去学习一番. 入了个门, 专门写个文档留着. 万一以后用得到呢- 论VB, 我还是初学者. 如有弄错了的地方 ...

  2. React仿大众点评外卖app

    主要使用技术: react react-router4 redux: action.reducer.store管理数据 fetch: 进行数据交互 prismjs : 页面嵌入代码,高亮显示插件 bu ...

  3. Ds100p -「数据结构百题」51~60

    纪念 数据结构一百题50题了呢,该过半周年啦~~~~ LYC和WGY半年的努力让这个几乎玩笑一般的系列到了现在. 今后也请多多关照啦. 祝愿dp100p早日过半 51.CF1000F One Occu ...

  4. java数组的定义和使用规范

    java数组 三种定义方式 1.数组类型[] 数组名字 = new 数组类型[数组长度] String[] str = new String[n]; //这里n代表数组的长度可变 //另外上面这种写法 ...

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

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

  6. 7.28 EOI

    #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef double db; const i ...

  7. django admin字段设置大全

    # 在列表页显示的字段,默认会显示所有字段,有对应的方法可以重写 list_display = ('__str__',) # 在列表页显示的字段中,可以链接到change_form页面的字段 list ...

  8. 【pwn】ez_pz_hackover_2016 --pwngdb和pwntools的结合,动态调试

    首先checksec 没开nx,说明堆栈可执行,初步考虑需要shellcode,然后拖进ida看主函数逻辑 看chall函数   printf("Yippie, lets crash: %p ...

  9. go 中的循环依赖

    什么是循环依赖 Go 中的循环依赖是指两个或多个包之间相互引用,形成了一个循环依赖关系.这种情况下,包 A 依赖包 B,同时包 B 也依赖包 A,导致两个包之间无法明确地确定编译顺序,从而可能引发编译 ...

  10. 2021北京智源大会SNN部分

    神经形态视觉计算 当前问题: spikes vs bits (脉冲 vs 位) meurons vs memory (神经元 vs 计算单元)(真空管vacuum tube,晶体管transistor ...