这篇文章是无意间看到的,稍作修改,写成此文。
附一张效果图
闲言少叙,言归正传。
S.1 调用摄像头
cap = cv2.VideoCapture(0)
S.2 用Sobel算子进行边缘检测,滤波后二值化
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gradX = cv2.Sobel(gray, ddepth = cv2.CV_16S, dx = 1, dy = 0, ksize = -1)
gradY = cv2.Sobel(gray, ddepth = cv2.CV_16S, dx = 0, dy = 1, ksize = -1)
gradient = cv2.subtract(gradX, gradY)
gradient = cv2.convertScaleAbs(gradient)
blurred = cv2.blur(gradient, (9, 9))
(_, thresh) = cv2.threshold(blurred, 225, 255, cv2.THRESH_BINARY)
S.3 通过闭运算排除小型黑洞,并处理掉条形码中的黑块
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 = 8) #这里原来是4,因为通过查看二值图发现小白块太多,所以改成8,效果大大优化
S.4 边缘检测,并绘制矩形框,框选条形码区域
im, contours, hierarchy = cv2.findContours(closed,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
rois = []
x = y = w = h = 0
for c in contours:
x, y, w, h = cv2.boundingRect(c)
if w > 10 and h > 20:
rois.append((x,y,w,h))
for r in rois:
x, y, w, h = r
cv2.rectangle(frame, (x,y), (x+w,y+h), (153,153,0), 2)
完整代码如下
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
while(1):
ret, frame = cap.read()
if ret == True:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gradX = cv2.Sobel(gray, ddepth = cv2.CV_16S, dx = 1, dy = 0, ksize = -1)
gradY = cv2.Sobel(gray, ddepth = cv2.CV_16S, dx = 0, dy = 1, ksize = -1)
gradient = cv2.subtract(gradX, gradY)
gradient = cv2.convertScaleAbs(gradient)
blurred = cv2.blur(gradient, (9, 9))
(_, thresh) = cv2.threshold(blurred, 225, 255, cv2.THRESH_BINARY)
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 = 8)
im, contours, hierarchy = cv2.findContours(closed,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
rois = []
x = y = w = h = 0
for c in contours:
x, y, w, h = cv2.boundingRect(c)
if w > 10 and h > 20:
rois.append((x,y,w,h))
for r in rois:
x, y, w, h = r
cv2.rectangle(frame, (x,y), (x+w,y+h), (153,153,0), 2)
cv2.imshow("123",frame)
k = cv2.waitKey(20)
if k & 0xFF == ord('q'):
break
这样的检测方式当条形码旋转时效果不是很好,等日后熟悉了hough变换再来改进。
参考原文:http://blog.jobbole.com/80448/
感谢前辈们的经验与博客。