python+OpenCV检测条形码
? ? ? ? 今天看到一篇關(guān)于條形碼檢測的文章,還是存在一些問題的,昨天我陪朋友去取快遞的時候,看到了關(guān)于條形碼檢測在現(xiàn)實(shí)場景中的應(yīng)用,于是,便想著實(shí)現(xiàn)一波,并且對程序中的一些問題做了一些修改。
首先要確定調(diào)用的包/庫的版本,這是在我電腦上程序的運(yùn)行環(huán)境(在今后的文章中,我會特別注意版本問題,這個非常重要):
- python3.6 + win 10
- numpy 1.16.2
- imutils 0.5.2
- opencv 4.1.0
?
一、導(dǎo)入需要用到的包/庫
import numpy as np import imutils import cv2二、轉(zhuǎn)化為灰度圖
一般對圖像的處理操作都是在灰度圖的基礎(chǔ)上進(jìn)行的。
image = cv2.imread('D:\image.jpg') gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)?
三、使用Scharr算子進(jìn)行邊緣檢測
? ? ? ? 條形碼一般具有以下特點(diǎn):矩形形狀,條帶是黑色,背景為白色,而且黑白相間。這就導(dǎo)致條形碼區(qū)域光暗變化明顯,這對于Scharr算子非常合適,因為Scharr算子對于圖像梯度的變化更加敏感,更有利于獲取條形碼的特征。
想要了解更多的邊緣檢測算法,可以查看我的這篇博客:https://blog.csdn.net/qq_40962368/article/details/81416954
ddepth = cv2.CV_32F if imutils.is_cv2() else cv2.CV_32F gradX = cv2.Sobel(gray, ddepth=ddepth, dx=1, dy=0, ksize=-1) gradY = cv2.Sobel(gray, ddepth=ddepth, dx=0, dy=1, ksize=-1) gradient = cv2.subtract(gradX,gradY) gradient = cv2.convertScaleAbs(gradient)?
四、去除噪聲
? ? ? ? (1)模糊與閾值化處理
? ? ? ? ? ? 通過均值濾波對圖像進(jìn)行模糊處理,通過閾值化處理將圖像轉(zhuǎn)化為二值圖像。以此來去除圖像中的絕大部分噪聲。cv2.threshold函數(shù)的第二個參數(shù)是為閾值化處理所設(shè)置的閾值,為了盡可能的去除噪聲,所以,盡量將此值設(shè)置的大一些,但不能過大,以免影響條形碼特征本身。
關(guān)于更多的OpenCV中閾值分割的方法,可以查看我的這篇博客:https://blog.csdn.net/qq_40962368/article/details/80917250
blurred = cv2.blur(gradient,(9, 9)) (_, thresh) = cv2.threshold(blurred, 231, 255, cv2.THRESH_BINARY)?
? ? ? ? ?(2)形態(tài)學(xué)處理
? ? ? ? ? ? 通過形態(tài)學(xué)處理,去除圖像細(xì)小的噪聲斑點(diǎn)。使用cv2.getStructuringElement函數(shù)定義結(jié)構(gòu)元素,經(jīng)過一個開運(yùn)算,再經(jīng)過四次腐蝕與四次膨脹,更好的去除噪聲。
關(guān)于形態(tài)學(xué)的操作一些方法,可以查看我的這篇博客:https://blog.csdn.net/qq_40962368/article/details/81276820
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 7)) closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel) closed = cv2.erode(closed, None, iterations=4) closed = cv2.dilate(closed, None, iterations=4)?
五、確定檢測輪廓,畫出檢測框
? ? ? ? OpenCV中提供了識別圖像區(qū)域的函數(shù),非常好用,找相應(yīng)的區(qū)域,根據(jù)區(qū)域大小進(jìn)行排序,保留最大的區(qū)域,該區(qū)域就是我們要找的條形碼區(qū)域。計算該輪廓的旋轉(zhuǎn)邊界框,確定位置信息,畫出檢測框。
cnts = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours(cnts) c = sorted(cnts, key=cv2.contourArea, reverse=True)[0]rect = cv2.minAreaRect(c) box = cv2.boxPoints(rect) if imutils.is_cv2() else cv2.boxPoints(rect) box = np.int0(box)cv2.drawContours(image, [box], -1, (0, 255, 0), 3) cv2.imshow("Image", image) cv2.waitKey(0) cv2.destroyAllWindows()總結(jié):從檢測結(jié)果來看,在特定的應(yīng)用場景下,檢測效果還是挺好的,但不適合應(yīng)用于所有的應(yīng)用場景,但我們可以從條形碼的檢測過程可以看出解決這類問題的一般想法,為以后解決類似的問題提供一種比較可靠的思路。
?
參考網(wǎng)址:https://www.pyimagesearch.com/2014/11/24detecting-barcodes-images-python-opencv/
總結(jié)
以上是生活随笔為你收集整理的python+OpenCV检测条形码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ubuntu16.04安装JDK1.8
- 下一篇: C++编程(一):匈牙利命名法