OpenCV只能找到图片中的二维码,识别二维码需要用pyzbar工具包。
找到二维码是参考的博文:https://blog.csdn.net/liqiancao/article/details/55670749
安装pyzbar:pip install pyzbar
import numpy as np
import cv2
import pyzbar.pyzbar as pyzbar
#加载图片
image = cv2.imread("E:/picture/bai.png")
#转换为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#用Sobel算子计算x,y方向上的梯度,之后在x方向上减去y方向上的梯度,通过这个减法,我们留下具有高水平梯度和低垂直梯度的图像区域。
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)
cv2.imshow("gradient",gradient)
#使用低通滤泼器平滑图像(9 x 9内核),这将有助于平滑图像中的高频噪声。低通滤波器的目标是降低图像的变化率。如将每个像素替换为该像素周围像素的均值。这样就可以平滑并替代那些强度变化明显的区域。
#原本没有过滤颜色通道的时候,这个高斯模糊有效,但是如果进行了颜色过滤,不用高斯模糊效果更好
#blurred = cv2.blur(gradient, (9, 9))
#对模糊图像二值化。梯度图像中不大于255的任何像素都设置为0(黑色)。 否则,像素设置为255(白色)。
(_, thresh) = cv2.threshold(gradient, 225, 255, cv2.THRESH_BINARY)
cv2.imshow("thresh",thresh)
#在上图中我们看到二维码区域有很多黑色的空余,我们要用白色填充这些空余,使得后面的程序更容易识别二维码区域,这需要做一些形态学方面的操作。
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 21))
closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
cv2.imshow("closed",closed)
#图像上还有一些小的白色斑点,这会干扰之后的二维码轮廓的检测,要把它们去掉。分别执行4次形态学腐蚀与膨胀。
closed = cv2.erode(closed, None, iterations = 4)
closed = cv2.dilate(closed, None, iterations = 4)
#找出轮廓
contours, hierarchy = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
c = sorted(contours, key = cv2.contourArea, reverse = True)[0]
#最小外界矩形
rect = cv2.minAreaRect(c)
#矩形的四个角点取整
box = np.int0(cv2.boxPoints(rect))
#画出该矩形
cv2.drawContours(image, [box], -1, (0, 255, 0), 3)
cv2.imshow("Image", image)
#找出矩形行、列的区域
Xs = [i[0] for i in box]
Ys = [i[1] for i in box]
y1 = min(Ys)
y2 = max(Ys)
x1 = min(Xs)
x2 = max(Xs)
# 找到图像中的二维码并进行解码
img1 = image[y1:y2,x1:x2]
barcodes = pyzbar.decode(img1)
#输出二维码中内容
print(barcodes[0])
cv2.waitKey(0)
输出的内容:Decoded(data=b’123’, type=‘QRCODE’, rect=Rect(left=0, top=0, width=256, height=256), polygon=[Point(x=0, y=0), Point(x=0, y=256), Point(x=256, y=256), Point(x=256, y=0)])
效果图: