<p>对于任何需要在实际解码之前提取干净QR码ROI的人,这里有一个简单的方法,可以使用阈值、形态学操作和轮廓过滤来提取QR码</p>
<ol>
<li><p><strong>获取二值图像。</strong><a href="https://opencv24-python-tutorials.readthedocs.io/en/latest/py_tutorials/py_gui/py_image_display/py_image_display.html" rel="nofollow noreferrer">Load image</a>、<a href="https://opencv24-python-tutorials.readthedocs.io/en/stable/py_tutorials/py_imgproc/py_colorspaces/py_colorspaces.html" rel="nofollow noreferrer">grayscale</a>、<a href="https://opencv24-python-tutorials.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_filtering/py_filtering.html" rel="nofollow noreferrer">Gaussian blur</a>、<a href="https://opencv24-python-tutorials.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_thresholding/py_thresholding.html#otsus-binarization" rel="nofollow noreferrer">Otsu's threshold</a></p>
</li>
<li><p><strong>连接各个QR轮廓。</strong>使用<a href="https://opencv24-python-tutorials.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html#structuring-element" rel="nofollow noreferrer">^{<cd1>}</a>创建一个矩形结构内核,然后使用<code>cv2.MORPH_CLOSE</code>执行<a href="https://opencv24-python-tutorials.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html" rel="nofollow noreferrer">morphological operations</a></p>
</li>
<li><p><strong>二维码过滤器。</strong><a href="https://docs.opencv.org/2.4/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#findcontours" rel="nofollow noreferrer">Find contours</a>
并使用<a href="https://docs.opencv.org/master/dd/d49/tutorial_py_contour_features.html" rel="nofollow noreferrer">contour approximation</a>、<a href="https://docs.opencv.org/master/dd/d49/tutorial_py_contour_features.html" rel="nofollow noreferrer">contour area</a>和<a href="https://opencv24-python-tutorials.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_contours/py_contour_properties/py_contour_properties.html#aspect-ratio" rel="nofollow noreferrer">aspect ratio</a>进行过滤</p>
</li>
</ol>
<hr/>
<p>这是图像处理管道</p>
<p>加载图像,灰度,高斯模糊,然后大津的阈值得到一个二值图像</p>
<p><a href="https://i.stack.imgur.com/P24H0.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/P24H0.png" alt="enter image description here"/></a></p>
<p>现在,我们创建一个矩形内核和变形接近组合成一个轮廓二维码</p>
<p><a href="https://i.stack.imgur.com/UkbLL.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/UkbLL.png" alt="enter image description here"/></a></p>
<p>我们使用轮廓面积、轮廓近似和纵横比找到二维码的轮廓并进行滤波。检测到的二维码以绿色突出显示</p>
<p><a href="https://i.stack.imgur.com/U20Fm.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/U20Fm.png" alt="enter image description here"/></a></p>
<p>提取的ROI</p>
<p><a href="https://i.stack.imgur.com/h5EGC.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/h5EGC.png" alt="enter image description here"/></a></p>
<p>代码</p>
<pre><code>import cv2
import numpy as np
# Load imgae, grayscale, Gaussian blur, Otsu's threshold
image = cv2.imread('1.png')
original = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (7,7), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Morph close
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=1)
# Find contours and filter for QR code using contour area, approximation, and aspect ratio
cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.04 * peri, True)
x,y,w,h = cv2.boundingRect(approx)
area = cv2.contourArea(c)
ar = w / float(h)
if len(approx) == 4 and area > 1000 and (ar > .85 and ar < 1.3):
cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 3)
ROI = original[y:y+h, x:x+w]
# cv2.imwrite('ROI.png', ROI)
# Display
cv2.imshow('thresh', thresh)
cv2.imshow('close', close)
cv2.imshow('image', image)
cv2.imshow('ROI', ROI)
# Save images
# cv2.imwrite('thresh.png', thresh)
# cv2.imwrite('close.png', close)
# cv2.imwrite('image.png', image)
# cv2.imwrite('ROI.png', ROI)
cv2.waitKey()
</code></pre>