Python实现识别多个条码/二维码(二)

    这篇博客实现的是“Python实现识别多个条码/二维码(一)”未完成的解码任务。由于系统坏了,软件重装等一系列原因,所以拖到现在。。不好意思哈。

    在上一篇中我们已经能把两个条形码找出并框起来了,接下来就是要解码。先上代码吧。

from sys import exit
from Image import _ImageCrop
from PIL import Image
import numpy as np
import zbar
import cv2
 
# 加载图片并把它转换为灰度图片
image = cv2.imread('F:/work/barcode/bar_code/20.jpg')
img = Image.open(r'F:/work/barcode/bar_code/20.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

#cv2.imshow("sobel_Image", gray)
#cv2.waitKey(0)
#使用Canny做边缘检测
gradient = cv2.Canny(gray , 20 ,520)
#cv2.imshow("Canny_Image", gradient)
#cv2.waitKey(0)

(_, thresh) = cv2.threshold(gradient, 225, 255, cv2.THRESH_BINARY) # 二值化
cv2.imshow("threshold_Image", thresh)
#cv2.waitKey(0)
# 构建kernel然后应用到 thresholded 图像上
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 5))#形态学处理,定义矩形结构
closed = cv2.dilate(thresh, kernel, iterations = 1)#膨胀图像,连接断点
#cv2.imshow("dilate_Image", closed)
#cv2.waitKey(0)

im, contours, hierarchy = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
#print contours
x = len(contours)
a = []
s = []

#打印面积
for i in range(0,x):
    s.append(cv2.contourArea(contours[i]))

#保留面积大于8000的轮廓
for m in range(0,x):
    if s[m] >= 8000 and s[m] <= 25000 :
        a.append(s[m])
    else:
        continue
        
z = max(a)

#for j in a:
#    print "a was : %f",j

for k in range(0,x):
    #增加一些筛选条件
    if s[k] >= 8000 and s[k] <= 25000 and ((z - s[k]) <= 8500 ) :
        rect = cv2.minAreaRect(contours[k])#返回矩形的中心点坐标,长宽,旋转角度
        box = np.int0(cv2.boxPoints(rect))
        cv2.drawContours(image, [box], -1, (255, 0, 0), 2)#画一个方框把条形码区域圈起来

        u,v,w,t = cv2.boundingRect(contours[k]) #获取轮廓坐标
        #print u,v,w,t
        #根据坐标把条码裁剪下来并保存
        o = (u,v,u+w,v+t)
        barcode = img.crop(o)
        barcode.save(r'F:/work/barcode/bar_code/crop4.jpg')
        #print "s : %f",s[k]
        #构建解码器
        scanner = zbar.ImageScanner()
        scanner.parse_config('enable')
        pil = Image.open('F:/work/barcode/bar_code/crop4.jpg').convert('L')
        width, height = pil.size
        #解码
        raw = pil.tostring()
        image0 = zbar.Image(width, height, 'Y800', raw)
        scanner.scan(image0)
        for symbol in image0:
            print 'decoded', symbol.type, 'symbol', '"%s"' % symbol.data
    else:
        continue

cv2.imshow("Image", image)
cv2.waitKey(0)
exit(0)

    找条码的程序与前文基本相同。解码的实现从获取轮廓坐标开始。其实就是我们把条码从原图上裁剪下来(这里先保存后打开是因为CV2与PIL的交替使用),然后用zabr工具包进行解码。

    下面放上结果图


猜你喜欢

转载自blog.csdn.net/TIME_LEAF/article/details/80722522