使用Python,OpenCV在视频中进行实时条形码检测
生活随笔
收集整理的這篇文章主要介紹了
使用Python,OpenCV在视频中进行实时条形码检测
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
使用Python,OpenCV在視頻中進(jìn)行實(shí)時(shí)條形碼檢測
- 1. 步驟
- 2. 適用場景及優(yōu)化
- 3. 總結(jié)
- 4. 源碼
- 參考
上一篇博客介紹了如何檢測和查找圖像中的條形碼。這篇博客將進(jìn)行一些優(yōu)化以檢測實(shí)時(shí)視頻中的條形碼。
1. 步驟
- 圖像/視頻幀中進(jìn)行條形碼檢測
- 驅(qū)動(dòng)程序以訪問視頻流,并調(diào)用條形碼檢測程序
計(jì)算x梯度與y梯度的差值(由于是x減y的,故只能檢測橫向的條形碼,算法并不通用)
2. 適用場景及優(yōu)化
適用場景:
- 靜態(tài)攝像頭,以90度角“向下”看條形碼。這將確保程序可以找到條形碼圖像的梯度區(qū)域。
- 視頻帶有條形碼的正視角的特寫,即智能手機(jī)直接放在條形碼的上方,而不是將條形碼遠(yuǎn)離鏡頭。將條形碼移離相機(jī)的距離越遠(yuǎn),簡單條形碼檢測器的成功就越少。
該方法并不適用于所有的條形碼檢測,僅在最佳條件下有效,并且是橫向條形碼;
當(dāng)條形碼離相機(jī)太遠(yuǎn),圖像中有太多的“干擾”和“噪音”時(shí),都不會奏效。
優(yōu)化:
如果要實(shí)施更強(qiáng)大的條形碼檢測算法,則需要考慮圖像的方向,或者更好的方法是應(yīng)用機(jī)器學(xué)習(xí)技術(shù)(例如Haar級聯(lián)或HOG +線性SVM)“掃描”圖像以進(jìn)行條形碼區(qū)域掃描。
3. 總結(jié)
這篇博客拓展了上一篇檢測圖像中的條形碼,主要分為倆部分:
- 用于檢測視頻各個(gè)幀中的條形碼的方法;
- “驅(qū)動(dòng)程序”,用于訪問攝像機(jī)或視頻文件的方法;
當(dāng)將其應(yīng)用于檢測視頻中的條形碼時(shí),并不通用。僅在:
- 有一個(gè)靜態(tài)相機(jī)視圖,它以90度角在條形碼上“向下看”。
- 擁有較清晰的,近的條形碼的“特寫”視圖,并且框架視圖中沒有其他干擾對象或噪聲。
下效果比較好。
優(yōu)化可以通過使用機(jī)器學(xué)習(xí)來訓(xùn)練更強(qiáng)壯的條形碼檢測器。
4. 源碼
# USAGE
# python detect_real_barcode.py --video video/video_games.mov
# python detect_real_barcode.py# 導(dǎo)入必要的包
import argparse
import timeimport cv2
import imutils
import numpy as np
from imutils.video import VideoStream# 檢測圖像中的條形碼
def detect(image):# 轉(zhuǎn)換圖像為灰度圖gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 計(jì)算圖像x,y方向上的Scharr梯度幅度表示ddepth = cv2.cv.CV_32F if imutils.is_cv2() else cv2.CV_32FgradX = cv2.Sobel(gray, ddepth=ddepth, dx=1, dy=0, ksize=-1)gradY = cv2.Sobel(gray, ddepth=ddepth, dx=0, dy=1, ksize=-1)# 計(jì)算x梯度與y梯度的差值(由于是x減y的,故只能檢測橫向的條形碼,算法并不通用),獲取到條形碼的大致范圍gradient = cv2.subtract(gradX, gradY)gradient = cv2.convertScaleAbs(gradient)# 高斯平滑(去掉高頻噪音干擾) 閾值化圖像(是的圖像的黑白區(qū)域更加明顯,閾值的設(shè)置很重要)blurred = cv2.blur(gradient, (9, 9))(_, thresh) = cv2.threshold(blurred, 225, 255, cv2.THRESH_BINARY)# 構(gòu)建一個(gè)閉合內(nèi)核應(yīng)用在閾值化的圖像上,使得條形碼之間的細(xì)線空隙更小;kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 7))closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)# 構(gòu)建一系列腐蝕、膨脹操作(去掉條形碼周圍的小斑點(diǎn)的干擾,要么消亡,要么生長成為條形碼區(qū)域;)closed = cv2.erode(closed, None, iterations=4)closed = cv2.dilate(closed, None, iterations=4)# 尋找輪廓cnts = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)cnts = imutils.grab_contours(cnts)# 如果沒有輪廓,返回None,認(rèn)為圖像中不存在條形碼if len(cnts) == 0:return None# 否則,根據(jù)外接圓面積排序,留下最大的輪廓認(rèn)為是條形碼區(qū)域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)# 返回條形碼區(qū)域的邊界框return box# 構(gòu)建命令行參數(shù)及解析
# --video,視頻文件的路徑
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video", help="path to the (optional) video file")
args = vars(ap.parse_args())# 如果提供了視頻文件,則讀取視頻文件
if not args.get("video", False):vs = VideoStream(src=0).start()time.sleep(2.0)
# 否則,加載電腦自帶的攝像頭
else:vs = cv2.VideoCapture(args["video"])# 循環(huán)遍歷幀
while True:# 獲取當(dāng)前幀# 如果是從視頻中VideoStram獲取則直接獲取當(dāng)前幀,否則,當(dāng)前視頻流VideoCapture中捕獲下一幀frame = vs.read()frame = frame[1] if args.get("video", False) else frame# 檢測是否到了視頻尾部if frame is None:break# 檢測視頻幀的條形碼box = detect(frame)# 如果檢測到了條形碼,在其上繪制綠色框if box is not None:cv2.drawContours(frame, [box], -1, (0, 255, 0), 2)# 展示幀,并記錄用戶是否有按鍵cv2.imshow("Frame", frame)key = cv2.waitKey(1) & 0xFF# 按下‘q’鍵,結(jié)束循環(huán)if key == ord("q"):break# 清除視頻流對象的指針
# 如果未使用視頻文件,停止視頻文件流
if not args.get("video", False):vs.stop()
# 否則,釋放攝像頭指針
else:vs.release()# 關(guān)閉所有展示的窗口
cv2.destroyAllWindows()
參考
- https://www.pyimagesearch.com/2014/12/15/real-time-barcode-detection-video-python-opencv/
總結(jié)
以上是生活随笔為你收集整理的使用Python,OpenCV在视频中进行实时条形码检测的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2020这一年,我完成了这几件大事
- 下一篇: Java IDEA import sun