1. 程式人生 > >Python實現識別多個條碼/二維碼(二)

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工具包進行解碼。

    下面放上結果圖

有朋友問我zbar的安裝,確實不好找哈,所以這裡放上鍊接~