使用 Python OpenCV 将二维码旋转到正确的位置
Rotating QR code to the correct position using Python OpenCV
我是python的初学者,目前正在研究QR码检测和解码。我很难将检测到的二维码旋转到正确的位置。我已经使用 minAreaRect()
旋转我的二维码,但它不起作用。有没有解决方法或正确的方法来做到这一点?谢谢!
ROI2 = cv2.imread('ROI.png')
gray2 = cv2.cvtColor(ROI2, cv2.COLOR_BGR2GRAY)
blur2 = cv2.GaussianBlur(gray2, (9, 9), 0)
thresh2 = cv2.threshold(blur2, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Morph close
# kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
# close2 = cv2.morphologyEx(thresh2, cv2.MORPH_CLOSE, kernel2, iterations=10)
# Find contours and filter for QR code
cnts2 = cv2.findContours(thresh2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts2 = cnts2[0] if len(cnts2) == 2 else cnts2[1]
c = sorted(cnts2, key=cv2.contourArea, reverse=True)[0]
draw = cv2.cvtColor(thresh2, cv2.COLOR_GRAY2BGR)
cv2.drawContours(draw, [c], 0, (0, 255, 0), 2)
rotrect = cv2.minAreaRect(c)
box = cv2.boxPoints(rotrect)
box = numpy.int0(box)
cv2.drawContours(draw, [box], 0, (0, 0, 255), 2)
cv2.imshow('thresh', thresh2)
cv2.imshow('ROI', ROI2)
cv2.imshow('minarearect', draw)
据我了解,您正在尝试对图像进行校正。为此,我们需要首先计算旋转的边界框角度,然后执行线性变换。这个想法是使用
cv2.minAreaRect
+ cv2.warpAffine
。根据文档,cv2.minAreaRect
returns
(center(x, y), (width, height), angle of rotation) = cv2.minAreaRect(...)
第三个参数为我们提供了校正图像所需的角度。
输入图片->
输出结果
Skew angle: -39.99416732788086
代码
import cv2
import numpy as np
# Load image, grayscale, Otsu's threshold
image = cv2.imread('2.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = 255 - gray
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
# Compute rotated bounding box
coords = np.column_stack(np.where(thresh > 0))
angle = cv2.minAreaRect(coords)[-1]
if angle < -45:
angle = -(90 + angle)
else:
angle = -angle
print("Skew angle: ", angle)
# Rotate image to deskew
(h, w) = image.shape[:2]
center = (w // 2, h // 2)
M = cv2.getRotationMatrix2D(center, angle, 1.0)
rotated = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
cv2.imshow('rotated', rotated)
cv2.waitKey()
注意:请参阅 了解另一种使用投影剖面法校正偏斜的方法。
使用 QRCodeDetector::detectAndDecode
检测 代码,并根据 straight_qrcode
值 重绘 代码。 QRCodeDetector 可能无法 解码 您可以使用简单的阈值和轮廓 定位 的所有代码。尤其是部分缺失(包括静区),二维码检测器可能会出问题。
这将始终以其规范方向显示代码,并将取景器图案指向 NW、NE 和 SW 方向。
简单 minAreaRect
只会将代码的边缘与图像轴对齐,但无法判断 QR 代码中的“向上”方向。
import cv2 as cv
im = cv.imread("OnDlO.png")
det = cv.QRCodeDetector()
(rv, points, straight_qrcode) = det.detectAndDecode(im)
# rv == 'testing123456'
# points:
# array([[[304. , 36. ],
# [415. , 321. ],
# [141.55959, 428.3963 ],
# [ 32. , 151. ]]], dtype=float32)
# some white padding
with_quiet_zone = cv.copyMakeBorder(straight_qrcode, 1, 1, 1, 1, borderType=cv.BORDER_CONSTANT, value=255)
# scale it up for display
larger = cv.resize(with_quiet_zone, dsize=None, fx=16, fy=16, interpolation=cv.INTER_NEAREST)
# and show it
cv.imshow("larger", larger)
cv.waitKey()
输入:
输出:
我是python的初学者,目前正在研究QR码检测和解码。我很难将检测到的二维码旋转到正确的位置。我已经使用 minAreaRect()
旋转我的二维码,但它不起作用。有没有解决方法或正确的方法来做到这一点?谢谢!
ROI2 = cv2.imread('ROI.png')
gray2 = cv2.cvtColor(ROI2, cv2.COLOR_BGR2GRAY)
blur2 = cv2.GaussianBlur(gray2, (9, 9), 0)
thresh2 = cv2.threshold(blur2, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Morph close
# kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
# close2 = cv2.morphologyEx(thresh2, cv2.MORPH_CLOSE, kernel2, iterations=10)
# Find contours and filter for QR code
cnts2 = cv2.findContours(thresh2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts2 = cnts2[0] if len(cnts2) == 2 else cnts2[1]
c = sorted(cnts2, key=cv2.contourArea, reverse=True)[0]
draw = cv2.cvtColor(thresh2, cv2.COLOR_GRAY2BGR)
cv2.drawContours(draw, [c], 0, (0, 255, 0), 2)
rotrect = cv2.minAreaRect(c)
box = cv2.boxPoints(rotrect)
box = numpy.int0(box)
cv2.drawContours(draw, [box], 0, (0, 0, 255), 2)
cv2.imshow('thresh', thresh2)
cv2.imshow('ROI', ROI2)
cv2.imshow('minarearect', draw)
据我了解,您正在尝试对图像进行校正。为此,我们需要首先计算旋转的边界框角度,然后执行线性变换。这个想法是使用
cv2.minAreaRect
+ cv2.warpAffine
。根据文档,cv2.minAreaRect
returns
(center(x, y), (width, height), angle of rotation) = cv2.minAreaRect(...)
第三个参数为我们提供了校正图像所需的角度。
输入图片->
输出结果
Skew angle: -39.99416732788086
代码
import cv2
import numpy as np
# Load image, grayscale, Otsu's threshold
image = cv2.imread('2.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = 255 - gray
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
# Compute rotated bounding box
coords = np.column_stack(np.where(thresh > 0))
angle = cv2.minAreaRect(coords)[-1]
if angle < -45:
angle = -(90 + angle)
else:
angle = -angle
print("Skew angle: ", angle)
# Rotate image to deskew
(h, w) = image.shape[:2]
center = (w // 2, h // 2)
M = cv2.getRotationMatrix2D(center, angle, 1.0)
rotated = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
cv2.imshow('rotated', rotated)
cv2.waitKey()
注意:请参阅
使用 QRCodeDetector::detectAndDecode
检测 代码,并根据 straight_qrcode
值 重绘 代码。 QRCodeDetector 可能无法 解码 您可以使用简单的阈值和轮廓 定位 的所有代码。尤其是部分缺失(包括静区),二维码检测器可能会出问题。
这将始终以其规范方向显示代码,并将取景器图案指向 NW、NE 和 SW 方向。
简单 minAreaRect
只会将代码的边缘与图像轴对齐,但无法判断 QR 代码中的“向上”方向。
import cv2 as cv
im = cv.imread("OnDlO.png")
det = cv.QRCodeDetector()
(rv, points, straight_qrcode) = det.detectAndDecode(im)
# rv == 'testing123456'
# points:
# array([[[304. , 36. ],
# [415. , 321. ],
# [141.55959, 428.3963 ],
# [ 32. , 151. ]]], dtype=float32)
# some white padding
with_quiet_zone = cv.copyMakeBorder(straight_qrcode, 1, 1, 1, 1, borderType=cv.BORDER_CONSTANT, value=255)
# scale it up for display
larger = cv.resize(with_quiet_zone, dsize=None, fx=16, fy=16, interpolation=cv.INTER_NEAREST)
# and show it
cv.imshow("larger", larger)
cv.waitKey()
输入:
输出: