使用Python和OpenCV检测图像中的条形码
生活随笔
收集整理的這篇文章主要介紹了
使用Python和OpenCV检测图像中的条形码
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
使用Python和OpenCV檢測圖像中的條形碼
- 1. 效果圖
- 2. 算法的步驟
- 3. 源碼
- 參考
這篇博客將介紹使用計算機視覺和圖像處理技術進行條形碼檢測的必要步驟,并演示使用Python編程語言和OpenCV庫實現檢測算法及其檢測效果。
1. 效果圖
原圖
灰度圖 VS 梯度漸變圖
x梯度減y梯度,梯度漸變獲取定位條形碼大致區域;
高斯模糊圖 VS 閾值化圖
高斯模糊去掉高頻噪音的干擾;
閾值化圖使得圖像的黑白區域更加明顯。閾值的值的設置很重要。該方法應用的是大于225的直接為255白色,不大于255的為0,黑色
閉合核圖 VS 腐蝕膨脹圖
閉合核作用:使得條形碼之間的細線差距更小;
腐蝕膨脹:去掉條形碼周圍的小斑點的干擾,要么消亡,要么生長成為條形碼區域;
最終效果圖:
2. 算法的步驟
該算法的步驟是:
- 計算x和y方向上的Scharr梯度幅度表示。
- 從x梯度中減去y梯度以顯示條形碼區域。
- 模糊和閾值圖像。
- 將封閉內核應用于閾值圖像。
- 執行一系列的膨脹和腐蝕。
- 找到圖像中最大的輪廓,就是條形碼。
該算法并不適用于所有條形碼。注意,由于此方法對圖像的漸變表示進行了假設,因此僅適用于水平條形碼。
優化:
如果要實施更強大的條形碼檢測算法,則需要考慮圖像的方向,或者更好的方法是應用機器學習技術(例如Haar級聯或HOG +線性SVM)“掃描”圖像以進行條形碼區域掃描。
3. 源碼
# USAGE
# python detect_barcode.py --image images/barcode_02.jpgimport argparseimport cv2
import imutils
# 導入必要的包
import numpy as np# 構建命令行參數及解析
# --image 包含條形碼的輸入圖像路徑
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,help="path to the image file")
args = vars(ap.parse_args())# 加載圖像,轉換為灰度圖
image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow("origin", image)
cv2.waitKey(0)# 使用Scharr運算符(指定ksize = -1)構造水平和垂直方向上灰度圖像的梯度幅度表示。
ddepth = cv2.cv.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)# 用Scharr運算符的x梯度中減去Scharr運算符的y梯度,剩下的圖像區域具有較高的水平梯度和較低的垂直梯度。
gradient = cv2.subtract(gradX, gradY)
gradient = cv2.convertScaleAbs(gradient)
cv2.imshow("gray VS gradient", np.hstack([gray, gradient]))
cv2.waitKey(0)# 以上可得到條碼圖像的梯度表示
# 請注意,漸變操作是如何檢測圖像的條形碼區域的。下一步將濾除圖像中的噪點,并僅關注條形碼區域。
# 高斯平滑以及閾值化圖像
# 使用9 x 9內核將平均模糊應用于漸變圖像,用以消除圖像梯度表示的高頻噪聲。
blurred = cv2.blur(gradient, (9, 9))
# 對模糊圖像進行閾值處理。漸變圖像中任何不大于225的像素都將設為0(黑色)。否則,像素設置為255(白色)。
(_, thresh) = cv2.threshold(blurred, 225, 255, cv2.THRESH_BINARY)
cv2.imshow("blurred VS thresh", np.hstack([blurred, thresh]))
cv2.waitKey(0)# 條形碼的豎線之間存在間隙。為了彌合這些差距,并使算法更容易檢測條形碼的“斑點”狀區域,我們需要執行一些基本的形態學操作:
# 構造一個閉合核并將其應用于閾值圖像
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 7))
closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)# 執行完成后,縫隙實際上更加封閉:
# 圖像中出現了小的斑點,這些斑點不是實際條形碼的一部分,但可能會干擾輪廓檢測。
# 繼續嘗試刪除這些小斑點:
# 執行4次腐蝕迭代,然后進行4次膨脹迭代。腐蝕將“侵蝕”圖像中的白色像素,從而消除小斑點,而膨脹將“膨脹”剩余的白色像素并使白色區域重新生長。
eroded = cv2.erode(closed, None, iterations=4)
dilated = cv2.dilate(eroded, None, iterations=4)
cv2.imshow("closede VS eroded and dilated", np.hstack([closed, dilated]))
cv2.waitKey(0)# 只要在侵蝕過程中去除了小斑點,它們就不會在擴張過程中重新出現。
# 經過一系列侵蝕和膨脹后,可以看到小斑點已被成功去除,并且剩下條形碼區域:# 在閾值化的圖像中尋找輪廓,輪廓面積排序,只保留最大的一個
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.cv.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)
參考
- https://www.pyimagesearch.com/2014/11/24/detecting-barcodes-images-python-opencv/
總結
以上是生活随笔為你收集整理的使用Python和OpenCV检测图像中的条形码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: “气变风凛冽”上一句是什么
- 下一篇: 求一个好听的青春小说名字。