基于opencv+python的二维码识别

时间:2024-03-08 17:13:14

花了2天时间终于把二维码识别做出来了,不过效果一般,后面会应用在ROS辅助定位上,废话少说先上图:

具体过程参考了这位大神的博客:http://blog.csdn.net/qq_25491201/article/details/51065547

详细解释:

第一步:利用opencv提取二维码区域

1,先将读入的摄像头frame转换成灰度图:

gray = cv2.cvtColor(image_path, cv2.COLOR_BGR2GRAY)

2,使用opencv自带的Sobel算子进行过滤:

gradX = cv2.Sobel(gray, cv2.CV_32F, 1, 0,-1)
gradY = cv2.Sobel(gray, cv2.CV_32F, 0, 1,-1)

具体参数可参考:http://blog.csdn.net/sunny2038/article/details/9170013

3,将过滤得到的X方向像素值减去Y方向的像素值:

gradient = cv2.subtract(gradX, gradY)

4,先缩放元素再取绝对值,最后转换格式为8bit型

gradient = cv2.convertScaleAbs(gradient)

5,均值滤波取二值化:

blurred = cv2.blur(gradient, (9, 9))
(_, thresh) = cv2.threshold(blurred, 160, 160, cv2.THRESH_BINARY)

6,腐蚀和膨胀的函数:

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)

7,找到边界findContours函数

binary,cnts,hierarchy = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

8,计算出包围目标的最小矩形区域:

c = sorted(cnts, key = cv2.contourArea, reverse = True)[0]
rect = cv2.minAreaRect(c)
box = np.int0(cv2.boxPoints(rect))

 

第二步:识别二维码

关于识别那就比较简单了,主要是加载import zbar库,然后scan就好了。

cap = cv2.VideoCapture(camera_idx)

# create a reader
scanner = zbar.ImageScanner()
# configure the reader
scanner.parse_config(
\'enable\')


box = detect.detect(frame)
if box != None:
# 这下面的3步得到扫描区域,扫描区域要比检测出来的位置要大
min = np.min(box, axis=0)
max = np.max(box, axis=0)

roi = frame[min[1] - 10:max[1] + 10, min[0] - 10:max[0] + 10]
print roi.shape
# 把区域里的二维码传换成RGB,并把它转换成pil里面的图像,因为zbar得调用pil里面的图像,而不能用opencv的图像
roi = cv2.cvtColor(roi, cv2.COLOR_BGR2RGB)
pil = Image.fromarray(frame).convert(\'L\')
width, height = pil.size
raw = pil.tostring()

# 把图像装换成数据
zarimage = zbar.Image(width, height, \'Y800\', raw)

# 扫描器进行扫描
scanner.scan(zarimage)