我很难找到一组形态学操作,使我能够使用cv2.connectedComponentsWithStats()
或cv2.findContours()
(但我更愿意使用cv2.connectedComponentsWithStats()
)检测(仅)各种图像中的QR码。
我绝对需要代码来处理的图像如下:
第一次
我一直在使用两个不同的代码,一个使用cv2.connectedComponentsWithStats()
,另一个使用cv2.findContours()
和一些其他方法(基于nathancy对Detect a QR code from an image and crop using OpenCV的回答)。为了测试,我一直在使用以下代码:
1.使用cv2.connectedComponentsWithStats()
,这个代码的问题是,它捕捉到的比第二个QR码更多,正如你在下面看到的。在第一个中它工作得很好,在第三个中也是如此,如果缩放到0.5,否则它也会像第二个图像一样检测到比QR码更多的信息。
import cv2
import numpy as np
#img = cv2.imread('Code-1.jpg'); scale = 1;
img = cv2.imread('Code-2.jpg'); scale = 1;
#img = cv2.imread('Code-3.jpg'); scale = 0.5;
width = int(img.shape[1] * scale); height = int(img.shape[0] * scale); img = cv2.resize(img, (width, height))
og = img.copy()
gray = np.zeros((img.shape[0], img.shape[1]), dtype=np.uint8)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gaussianblur = cv2.GaussianBlur(gray, (7,7), 0)
otsuthresh = cv2.threshold(gaussianblur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
edges = cv2.Canny(otsuthresh, threshold1=100, threshold2=200)
dilate = cv2.dilate(edges,(5,5),iterations=1)
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(dilate, 8, cv2.CV_32S)
for i in range(1,num_labels):
objint = (labels == i).astype(np.uint8)*255/i
x = stats[i, cv2.CC_STAT_LEFT]
y = stats[i, cv2.CC_STAT_TOP]
w = stats[i, cv2.CC_STAT_WIDTH]
h = stats[i, cv2.CC_STAT_HEIGHT]
area = stats[i, cv2.CC_STAT_AREA]
ratio = w / float(h)
(cX, cY) = centroids[i]
if area > 500 and (ratio > .95 and ratio < 1.05) and (w < 0.99*img.shape[1]):
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
ROI = og[y:y + h, x:x + w]
cv2.imwrite('ROI.png', ROI)
cv2.imshow('image', img)
cv2.imshow('QR code', ROI)
1.使用cv2.findContours()
时,该程序无法检测到图像中的任何QR代码,但可以检测到其他一些随机图像
import cv2
import numpy as np
#img = cv2.imread('Code-1.jpg'); scale = 1;
img = cv2.imread('Code-2.jpg'); scale = 1;
#img = cv2.imread('Code-3.jpg'); scale = 0.5;
width = int(img.shape[1] * scale); height = int(img.shape[0] * scale); img = cv2.resize(img, (width, height))
og = img.copy()
gray = np.zeros((img.shape[0], img.shape[1]), dtype=np.uint8)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gaussianblur = cv2.GaussianBlur(gray, (7,7), 0)
otsuthresh = cv2.threshold(gaussianblur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
closed = cv2.morphologyEx(otsuthresh, cv2.MORPH_CLOSE, kernel, iterations=3)
contours = cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if len(contours) == 2:
contours = contours[0]
else:
contours = contours[1]
for cnt in contours:
perim = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, 0.05 * perim, True)
x,y,w,h = cv2.boundingRect(approx)
area = cv2.contourArea(cnt)
ratio = w / float(h)
if len(approx) == 4 and area > 1000 and (ratio > .80 and ratio < 1.2):
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 4)
ROI = og[y:y + h, x:x + w]
cv2.imwrite('ROI.png', ROI)
cv2.imshow('image', img)
cv2.imshow('QR code', ROI)
谢谢你的阅读,如果我不清楚的东西,请让我知道。
菲利佩·阿尔梅达
1条答案
按热度按时间i5desfxk1#
也许,你可以试试QReader。它只是一个OpenCV,Pyzbar和其他QR检测和图像过滤方法的 Package 器,但它对这些情况的工作相当开箱即用。
这就是它给出的输出:
第一次