Python實現識別多個條碼/二維碼(二)
阿新 • • 發佈:2019-01-26
這篇部落格實現的是“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的安裝,確實不好找哈,所以這裡放上鍊接~