Python+OpenCV实现定位二维码
相较于BarCode,QRCode有明显的特征区域,也就是左上角、右上角、左下角三个”回“字区域,得益于hierarchy中,父子关系的轮廓是连续的(下标),所以这个时候我们就可以通过cv2.findContours()返回的hierarchy来进行定位。
我们直接上代码
import cv2 import numpy def qrcode(image): # 有些二维码和边缘紧贴,无法识别出整个矩形,所以我们先对图片大小进行扩展 expand_length = 10 edge = expand_length // 2 h, w = image.shape[:2] image_extend = numpy.zeros((image.shape[0] + expand_length, image.shape[1] + expand_length, 3), numpy.uint8) image_extend[:] = 255 image_extend[edge:edge + h, edge:edge + w] = image # 转灰度、二值化、找轮廓 gray = cv2.cvtColor(image_extend, cv2.COLOR_BGR2GRAY) # blur = cv2.GaussianBlur(gray, (5, 5), 0) _, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) contours, hir = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) ''' 2.4282182798755647 2.3203121154092337 2.3487607213520345 2.318010267306266 ''' # 三个“回”字特征轮廓存储 parent_hierarchy_list = [] parent_contours_list = [] # 通过层级信息去查找三个“回”字特征区域 for index, item in enumerate(hir[0][:-2]): # 查找最外层(A)轮廓 if item[2] != -1: parent_index = item[2] - 1 if hir[0][index+1][3] == parent_index: # 查找次一层(B)轮廓 child_first = hir[0][index+1][2] - 1 if hir[0][index+2][3] == child_first: # 查找最里层(C)轮廓 # 计算A轮廓的周长和C轮廓周长的比值 error = cv2.arcLength(contours[parent_index], True) / cv2.arcLength(contours[parent_index + 2], True) if 2 < error < 3: parent_hierarchy_list.append(item) parent_contours_list.append(contours[index]) # 绘制出三个“回”字特征区域的最外层轮廓 cv2.drawContours(image_extend, contours, index, (0, 255, 0), 3) # 将整个二维码区域绘制出来 points_list = [] for index, box in enumerate(parent_contours_list): x, y, w, h = cv2.boundingRect(box) if index == 0: points_list.append((x, y+h)) if index == 1: points_list.append((x+w, y)) if index == 2: points_list.append((x, y)) points_list = numpy.array(points_list) rect = cv2.minAreaRect(points_list) box = cv2.boxPoints(rect) box = numpy.int0(box) cv2.drawContours(image_extend, [box], 0, (255, 0, 0), 2) cv2.imshow('', image_extend) if __name__ == '__main__': img = cv2.imread('../images/QRCode_3.png') qrcode(img) cv2.waitKey() cv2.destroyAllWindows()
通常我们所见的二维码都是有留白边缘区域的,但是在随便找一些二维码图的过程中,有一些是没有留白边缘区域的:
上图是在IDE中打开的,原图是没有灰色边缘的,这个时候我们如果直接读取这张图片,得到的轮廓信息并不是我们期待的三个连续的父子关系的hierarchy,为了避免这种情况,这里就手动向外扩展十个像素,人为制造一个间隔。
通常来说,我们通过三层for循环来定位特征区域已经是足够的,但是如果二维码的其他区域也出现了三层轮廓,那么我们就需要进行筛选,所以代码通过计算最外层轮廓的长度和最内存轮廓长度的比值来进行筛选,每一个“回”的黑白框框的比例大概为1:1:3:1:1,也就是说他们的边长比为7:3,而这个比值在标准二维码中,只有三个特征区域才符合。
代码的21到24行中的数值,便是尝试过了四个不同的二维码得出的比值,都接近7:3。
最后我们绘制出四个边框,完成二维码的定位:
到此这篇关于Python+OpenCV实现定位二维码的文章就介绍到这了,更多相关Python OpenCV定位二维码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
使用pandas将numpy中的数组数据保存到csv文件的方法
今天小编就为大家分享一篇使用pandas将numpy中的数组数据保存到csv文件的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2018-06-06PyQt5连接MySQL及QMYSQL driver not loaded错误解决
这篇文章主要介绍了PyQt5连接MySQL及QMYSQL driver not loaded错误解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-04-04
最新评论