python opencv single barcode detection and recognition

python opencv single barcode detection and recognition

Implementation based on python opencv pyzbar.

Original image:
Insert picture description here
Result image:
Insert picture description here
Directly upload the code:

import cv2
import numpy as  np
import math
from pyzbar.pyzbar import decode

#读图
img=cv2.imread(r'XX.png',1) #读取图片
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  #将图片变为灰度图片

#使用Sobel算子,求得水平和垂直方向灰度图像的梯度差
gradX = cv2.Sobel(gray,ddepth = cv2.CV_32F,dx = 1,dy = 0,ksize = -1)
gradY = cv2.Sobel(gray,ddepth = cv2.CV_32F,dx = 0,dy = 1,ksize = -1)
gradient = cv2.subtract(gradX, gradY)
gradient = cv2.convertScaleAbs(gradient)
images = cv2.resize(gradient,(480,640))
cv2.imshow("closed1", images)
cv2.waitKey(0)
#均值滤波,消除高频噪声 (8*8)像素块
blurred = cv2.blur(gradient,(8,8))
#二值化
ret,thresh = cv2.threshold(blurred, 225, 255, cv2.THRESH_BINARY)
#闭运算 填充条码空隙 (参数自己调整)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(25,25))
closed1 = cv2.morphologyEx(thresh,cv2.MORPH_CLOSE,kernel, iterations = 2)
# images = cv2.resize(closed1,(480,640))
# cv2.imshow("closed1", images)
# cv2.waitKey(0)
#4次腐蚀 再4次膨胀:消除小斑点
closed2 = cv2.erode(closed1, None, iterations = 4)
closed3 = cv2.dilate(closed2, None, iterations = 4)
# images = cv2.resize(closed3,(480,640))
# cv2.imshow("closed3", images)
# cv2.waitKey(0)
#开运算
ret,th2=cv2.threshold(closed3,0.1,255,cv2.THRESH_BINARY)
kernel = np.ones((10,10),np.uint8)
opening = cv2.morphologyEx(th2, cv2.MORPH_OPEN, kernel,iterations = 2)
images = cv2.resize(opening,(480,640))
cv2.imshow("contours", images)
cv2.waitKey(0)
#腐蚀
kernel = np.ones((5,5),np.uint8)
erosion = cv2.erode(opening,kernel,iterations = 2)
opening = cv2.resize(erosion ,(480,640))
cv2.imshow("contours",opening )
cv2.waitKey(0)

#找出边界
contours, hierarchy = cv2.findContours(erosion.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

#获取最大轮廓
c = sorted(contours, key = cv2.contourArea, reverse = True)[0]

#图形旋转矫正 并截取最大边界区域
#修改最小框大小 放大50
rect = cv2.minAreaRect(c)
b = list(rect)
b[1] = list(b[1])
b[1][0] = b[1][0] + 50
b[1][1] = b[1][1] + 50
new_rect = tuple(b)
box = np.int0(cv2.boxPoints(new_rect))                     
#draw_img = cv2.drawContours(img.copy(), [box], -1, (0, 0, 255), 3)
# 获取画框宽高(x=orignal_W,y=orignal_H)
orignal_W = math.ceil(np.sqrt((box[3][1] - box[2][1])**2 + (box[3][0] - box[2][0])**2))
orignal_H= math.ceil(np.sqrt((box[3][1] - box[0][1])**2 + (box[3][0] - box[0][0])**2))
# 原图中的四个顶点,与变换矩阵
pts1 = np.float32([box[0], box[1], box[2], box[3]])
pts2 = np.float32([[int(orignal_W+1),int(orignal_H+1)], [0, int(orignal_H+1)], [0, 0], [int(orignal_W+1), 0]])
# 生成透视变换矩阵;进行透视变换
M = cv2.getPerspectiveTransform(pts1, pts2)
result_img = cv2.warpPerspective(img, M*1.5, (int(orignal_W+20),int(orignal_H+20)))
cv2.imshow("JIAOZHEN",result_img)
cv2.waitKey(0)
#二值化 筛掉一些错误
ret,thresh = cv2.threshold(result_img,128, 255, cv2.THRESH_BINARY)
#二维码编码检测
barcodes = decode(thresh)
result = []
for barcode in barcodes:
    barcodeData = barcode.data.decode("utf-8")
    result.append(barcodeData)
print(result)
       

Finally, the barcode will be output:

['6936281406719']

Note: The pyzbar module can recognize barcodes in the horizontal and vertical directions. After perspective transformation, the above images are basically vertical or horizontal and can be recognized. However, the imshow effect of large-angle images is not very good, and may be upside down. . .

Guess you like

Origin blog.csdn.net/djj199301111/article/details/107616015