实操教程|基于OpenCV的条形码区域分割

2022 年 2 月 7 日 极市平台
↑ 点击 蓝字  关注极市平台

来源丨小白学视觉
编辑丨极市平台

极市导读

 

本文在Anaconda中采用Python 2.7 完成从图像中提取出含有条形码的区域。 >>加入极市CV技术交流群,走在计算机视觉的最前沿

我们将一起学习如何从图像中提取出含有条形码的区域。下面的代码,我们将在Anaconda中采用Python 2.7 完成,当然OpenCV中的图像处理库也是必不可少的。

分割是识别图像内一个或多个对象的位置的过程。我们要介绍的技术其实非常简单,它利用了形态算子的扩张和侵蚀,以及诸如开运算,闭运算和黑帽算子的组合。

简介

安装Anaconda后,让我们从Anaconda的提示符下使用以下命令转到OpenCV安装:conda install -c https://conda.anaconda.org/menpo opencv现在,让我们从Anaconda启动器启动Spyder IDE。

Anaconda启动器一旦运行了Spyder,建议验证OpenCV安装是否成功。在Python控制台的右下角,我们进行以下测试:

import cv2

代码讲解

我们已经创建了一个启动GitHub存储库。小伙伴可以使用以下方法直接克隆它:

git clone --branch step1
https://github.com/lucapiccinelli/BarcodesTutorial.git

现在,我们将要下载测试图像,并对他们进行读取和显示。

测试图片
import cv2
import matplotlib.pyplot as plt

im = cv2.imread(r’img\barcodes.jpg’, cv2.IMREAD_GRAYSCALE)
plt.imshow(im, cmap=’Greys_r’)

接下来,我们将对图像进行二值化处理,这样可以通过阈值的设定来提取出我们感兴趣的部分。使用黑帽运算符,我们可以增加较暗的图像元素。我们可以首先使用简单的全局阈值安全地对图像进行二值化处理。黑帽运算符使我们可以使用非常低的阈值,而不必过多地关注噪声。

在应用blackhat时,我们使用的内核会更加重视垂直图像元素。内核具有固定的大小,因此可以缩放图像,这也可以提高性能(并支持某种输入归一化)。

黑帽+阈值处理它遵循其他形态运算符的采用,顺序地将它们组合在一起以获得条形码位置中的连接组件。

#riscalatura dell'immagine
scale = 800.0 / im.shape[1]
im = cv2.resize(im, (int(im.shape[1] * scale), int(im.shape[0] * scale)))

#blackhat
kernel = np.ones((1, 3), np.uint8)
im = cv2.morphologyEx(im, cv2.MORPH_BLACKHAT, kernel, anchor=(1, 0))

#sogliatura
thresh, im = cv2.threshold(im, 10, 255, cv2.THRESH_BINARY)

膨胀和闭合的这种组合在测试图像上效果很好,但可能无法在其他图像上达到相同的效果。这没有关系,大家可以尝试改变参数和运算符的组合,直到对结果满意为止。

膨胀+闭运算最后的预处理步骤是应用具有很大内核的开运算符,以删除太少而无法适合条形码形状的元素。

kernel = np.ones((21, 35), np.uint8)
im = cv2.morphologyEx(im, cv2.MORPH_OPEN, kernel, iterations=1)

这是我们希望得到的最终结果:

使用35x21内核打开现在,我们可以运行连接的组件的检测算法,并检索带有坐标和尺寸的条形码矩形。如大家在上一张图像中所看到的那样,最后的形态学步骤并未滤除全部的噪声。但是,在这种情况下,将它们过滤掉非常简单,以矩形区域值作为阈值就可以了。

#rilettura dell'immagine, stavolta a colori
im_out = cv2.imread(r'img\barcodes.jpg')

#estrazione dei componenti connessi
contours, hierarchy = cv2.findContours(im, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

unscale = 1.0 / scale
if contours != None:
    for contour in contours:
        
        # se l'area non è grande a sufficienza la salto 
        if cv2.contourArea(contour) <= 2000:
            continue
        
        #estraggo il rettangolo di area minima (in formato (centro_x, centro_y), (width, height), angolo)
        rect = cv2.minAreaRect(contour)
        #l'effetto della riscalatura iniziale deve essere eliminato dalle coordinate rilevate
        rect = \
            ((int(rect[0][0] * unscale), int(rect[0][1] * unscale)), \
             (int(rect[1][0] * unscale), int(rect[1][1] * unscale)), \
             rect[2])
        
        #disegno il tutto sull'immagine originale
        box = np.int0(cv2.cv.BoxPoints(rect))
        cv2.drawContours(im_out, [box], 0, (02550), thickness = 2)
        
plt.imshow(im_out)
#scrittura dell' immagine finale
cv2.imwrite(r'img\out.png', im_out)

最后,在上面的代码中,我使用提取的矩形绘制它们,并将其覆盖在原始图像上。

最终结果,条形码以绿色框突出显示。

结论

提出的技术非常简单有效,但存在一些缺点:

  • 它对条形码偏斜非常敏感;它可以很好地工作到大约45度,然后必须执行第二遍,修改内核的方向。
  • 它只能在固定尺寸范围内找到条形码。
  • 尽管对矩形区域施加了过滤,但仍有可能无法清除某些非条形码。第一个和第二个可能不是真正的问题,但是最后一个可能会花费大家大量时间来尝试解码非条形码的内容。一个很好的解决方案是将条形码特征(图像梯度,傅立叶变换)输入给神经网络(或一些其他一些分类器),并在第二时刻过滤掉噪声。下面给出完整的示例代码。
import cv2
import matplotlib.pyplot as plt
import numpy as np

im = cv2.imread(r'img\barcodes.jpg', cv2.IMREAD_GRAYSCALE)
im_out = cv2.imread(r'img\barcodes.jpg')

#riscalatura dell'immagine
scale = 800.0 / im.shape[1]
im = cv2.resize(im, (int(im.shape[1] * scale), int(im.shape[0] * scale)))

#blackhat
kernel = np.ones((13), np.uint8)
im = cv2.morphologyEx(im, cv2.MORPH_BLACKHAT, kernel, anchor=(10))

#sogliatura
thresh, im = cv2.threshold(im, 10255, cv2.THRESH_BINARY)

#operazioni  morfologiche
kernel = np.ones((15), np.uint8)
im = cv2.morphologyEx(im, cv2.MORPH_DILATE, kernel, anchor=(20), iterations=2#dilatazione
im = cv2.morphologyEx(im, cv2.MORPH_CLOSE, kernel, anchor=(20), iterations=2)  #chiusura

kernel = np.ones((2135), np.uint8)
im = cv2.morphologyEx(im, cv2.MORPH_OPEN, kernel, iterations=1)

#estrazione dei componenti connessi
contours, hierarchy = cv2.findContours(im, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

unscale = 1.0 / scale
if contours != None:
    for contour in contours:
        
        # se l'area non è grande a sufficienza la salto 
        if cv2.contourArea(contour) <= 2000:
            continue
        
        #estraggo il rettangolo di area minima (in formato (centro_x, centro_y), (width, height), angolo)
        rect = cv2.minAreaRect(contour)
        #l'effetto della riscalatura iniziale deve essere eliminato dalle coordinate rilevate
        rect = \
            ((int(rect[0][0] * unscale), int(rect[0][1] * unscale)), \
             (int(rect[1][0] * unscale), int(rect[1][1] * unscale)), \
             rect[2])
        
        
        #disegno il tutto sull'immagine originale
        box = np.int0(cv2.cv.BoxPoints(rect))
        cv2.drawContours(im_out, [box], 0, (02550), thickness = 2)
        
plt.imshow(im_out)
#scrittura dell' immagine finale
cv2.imwrite(r'img\out.png', im_out)


如果觉得有用,就请分享到朋友圈吧!

△点击卡片关注极市平台,获取 最新CV干货

公众号后台回复“数据集”获取深度学习数据集分类下载~


极市干货
课程/比赛: 珠港澳人工智能算法大赛 保姆级零基础人工智能教程
算法trick 目标检测比赛中的tricks集锦 从39个kaggle竞赛中总结出来的图像分割的Tips和Tricks
技术综述: 一文弄懂各种loss function 工业图像异常检测最新研究总结(2019-2020)


CV技术社群邀请函 #

△长按添加极市小助手
添加极市小助手微信(ID : cvmart4)

备注:姓名-学校/公司-研究方向-城市(如:小极-北大-目标检测-深圳)


即可申请加入极市目标检测/图像分割/工业检测/人脸/医学影像/3D/SLAM/自动驾驶/超分辨率/姿态估计/ReID/GAN/图像增强/OCR/视频理解等技术交流群


每月大咖直播分享、真实项目需求对接、求职内推、算法竞赛、干货资讯汇总、与 10000+来自港科大、北大、清华、中科院、CMU、腾讯、百度等名校名企视觉开发者互动交流~


觉得有用麻烦给个在看啦~   
登录查看更多
3

相关内容

IM:IFIP/IEEE International Symposium on Integrated Network Management。 Explanation:综合网络管理国际研讨会。 Publisher:IFIP/IEEE SIT: http://dblp.uni-trier.de/db/conf/im/index.html
【AAAI2022】基于图神经网络的统一离群点异常检测方法
专知会员服务
25+阅读 · 2022年2月12日
专知会员服务
64+阅读 · 2021年3月23日
专知会员服务
90+阅读 · 2020年12月26日
专知会员服务
19+阅读 · 2020年12月11日
实践教程|使用 OpenCV 进行虚拟缩放
极市平台
0+阅读 · 2022年2月28日
基于OpenCV的图像阴影去除
极市平台
1+阅读 · 2022年2月27日
实操教程|怎样制作目标检测的训练样本图像?
极市平台
1+阅读 · 2022年2月20日
实践教程|最简单的代码实现语义分割!
极市平台
0+阅读 · 2022年2月18日
实操教程|OpenCV中保存不同深度图像的技巧
极市平台
0+阅读 · 2022年2月14日
实践教程 | 使用OpenCV实现道路车辆计数
极市平台
0+阅读 · 2021年12月26日
实践教程|基于OpenCV提取特定区域方法汇总
极市平台
1+阅读 · 2021年12月5日
OpenCV 4 系统化学习路线图与教程
计算机视觉life
20+阅读 · 2019年3月24日
国家自然科学基金
2+阅读 · 2015年12月31日
国家自然科学基金
0+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2011年12月31日
国家自然科学基金
0+阅读 · 2009年12月31日
国家自然科学基金
0+阅读 · 2008年12月31日
Arxiv
0+阅读 · 2022年4月20日
Arxiv
0+阅读 · 2022年4月19日
Arxiv
0+阅读 · 2022年4月17日
Arxiv
16+阅读 · 2021年3月2日
VIP会员
相关资讯
实践教程|使用 OpenCV 进行虚拟缩放
极市平台
0+阅读 · 2022年2月28日
基于OpenCV的图像阴影去除
极市平台
1+阅读 · 2022年2月27日
实操教程|怎样制作目标检测的训练样本图像?
极市平台
1+阅读 · 2022年2月20日
实践教程|最简单的代码实现语义分割!
极市平台
0+阅读 · 2022年2月18日
实操教程|OpenCV中保存不同深度图像的技巧
极市平台
0+阅读 · 2022年2月14日
实践教程 | 使用OpenCV实现道路车辆计数
极市平台
0+阅读 · 2021年12月26日
实践教程|基于OpenCV提取特定区域方法汇总
极市平台
1+阅读 · 2021年12月5日
OpenCV 4 系统化学习路线图与教程
计算机视觉life
20+阅读 · 2019年3月24日
相关基金
国家自然科学基金
2+阅读 · 2015年12月31日
国家自然科学基金
0+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2011年12月31日
国家自然科学基金
0+阅读 · 2009年12月31日
国家自然科学基金
0+阅读 · 2008年12月31日
Top
微信扫码咨询专知VIP会员