Matlab实现 通过检测QR二维码位置探测图案进行精确定位

您所在的位置:网站首页 二维码识别模块 Matlab实现 通过检测QR二维码位置探测图案进行精确定位

Matlab实现 通过检测QR二维码位置探测图案进行精确定位

2023-12-30 15:31| 来源: 网络整理| 查看: 265

近邻点集融合算法 QR二维码结构简介

QR二维码识别中在对图像预处理后最重要的一步就是要进行定位,QR二维码中有三个位置探测图形,通过扫描其特征便可以进行精细定位。

QR二维码结构 其中位置探测图形的比例特征如下:

QR二维码位置探测图形 本文介绍的方法用于在二维码经过图像预处理并已经粗定位二维码大致位置后,检测位置探测图案坐标以精确定位。 首先要做的是,横竖扫描图像像素,找到满足黑白黑白黑且比例关系近似1:1:3:1:1的,将其两端的中点坐标记录下来,最终得到整幅图像所有的候选点,代码附在文末。 效果如图:

扫描得到的所有候选点 下一步使用原创的近邻点融合算法筛选出真正的位置探测图形所在位置的点。

近邻点融合

1、搜索每个点附近一定距离内近邻点的数量,用每个点近邻点集的平均坐标代替原本的坐标:这样可以将比较集中的点的集群向内收缩融合,孤立点由于没有紧邻点则会直接删除,在不停的迭代中其他零散的点的紧邻点减少的速度会远远大于三个位置探测图形所在位置相对更集中的点。 融合效果如左图,右图是每个近邻点集求出平均坐标后的效果。 各近邻点集紧邻点集平均坐标 2、当得到的近邻点集数量小于某个值时(默认定为20)或者迭代次数到达预设的最大迭代次数(10),结束迭代。 3、筛选出拥有紧邻点最多的三个点,求出其平均坐标就是三个位置探测图形所在的坐标了。 效果如图: 在这里插入图片描述 后续只需要通过判断这三个点的位置关系,对图像进行校正即可。 更新: 使用400张左右的二维码图片进行测试,其中包含了不同方向不同角度,以上方法得到的定位准确率仅有70%不到,因此算法仍需优化。 思考后加入了一个反馈机制,对于得到的三个坐标进行计算,判断其各种位置关系是否是真正的三个位置探测图形,若计算结果发现位置关系差别较大,则对近邻点融合算法的参数进行调整重新融合,相关代码已更新。

经过实验对比,该算法准确率可以提高到89%左右,单次耗时在Matlab下为2秒左右,而 https://blog.csdn.net/c602273091/article/details/42033069 中提到的方法在matlab下的准确略能达到95%,且运行速度普遍低于1秒,集中在0.8-0.9秒,但是实验发现几乎所有错误都集中在前200张图片,因此该方法在普适情况下更加适用,但是在某些情况下近邻点融合算法能略占优势。

本文所述算法以及 https://blog.csdn.net/c602273091/article/details/42033069 中算法的matlab实现(命名为group_points.m)已打包上传,链接如下: https://download.csdn.net/download/whitett/11139476 不知道为啥要5个积分,需要可以评论联系我。

QR二维码精定位算法: %横竖扫描图像像素,找到满足黑白黑白黑且比例关系近似1:1:3:1:1的, %将其两端的中点坐标记录下来,最终得到整幅图像所有的候选点, %然后下一步筛选出真正的位置探测图形所在位置的点。 %紧邻点融合算法: %1、搜索每个点附近一定距离内近邻点的数量,用 %每个点近邻点集的平均坐标代替原本的坐标:这样可以将比较集中的点 %的集群向内收缩融合,孤立点由于没有紧邻点则会直接删除,在不停的 %迭代中其他零散的点的紧邻点减少的速度会远远大于三个位置探测图形 %所在位置相对更集中的点。 %2、当拥有近邻点集的点数量小于某个值时(默认定为20)或者 %迭代次数到达预设的最大迭代次数时结束迭代。 %3、筛选出拥有紧邻点最多的三个点,求出其平均坐标就是三个 %位置探测图形所在的坐标了。 %4、判断得到的三个点坐标是否是正确的三个位置探测图形位置, %若不是,则调整参数进行二次计算,直到判断通过。 function points = detect(img) clc;close all; [m, n,~] = size(img); tol = 5; %初始距离阈值 points = findInRowAndCol(img); %横纵像素扫描,找到拥有1:1:3:1:1比例的位置 % tol = 4; iterate =10; %最大迭代次数 num = 0; itnum = 0; numMax = 30; %结束迭代条件,小于numMax个点则结束 for i = 1:iterate [num, points,numRepeat] = Points_merge(tol,points); %近邻点融合函数 itnum = itnum + 1; if(num < numMax) %小于numMax个点集结束迭代 break; end end % 排序,前三个即为紧邻点数量最多的三个点 for i = 1:num-1 for j = i:num if(numRepeat(i) < numRepeat(j)) temp = numRepeat(i); numRepeat(i) = numRepeat(j); numRepeat(j) = temp; temp1 = points(i,1); points(i,1) = points(j,1); points(j,1) = temp1; temp2 = points(i,2); points(i,2) = points(j,2); points(j,2) = temp2; end end end %反馈,若三点不满足一定条件则进行二次计算重新定位 count = 0; %计算重复定位次数 Feedback = detectFeedback(points); if(Feedback == 0) points = dectectAgain1(img, tol, numMax, count) end %画出拥有近邻点集做多的前三个点的平均坐标 for index = 1:3 x(index) = points(index,1); y(index) = points(index,2); end figure(1); subplot(1,1,1); imshow(img); hold on for index = 1:3 plot(y(index),x(index),'*r'); end grid on

扫描1:1:3:1:1位置探测图案的代码:

%横、纵两个方向扫描图像像素,找到满足黑白黑白黑且 %比例关系近似1:1:3:1:1的,将其两端的中点坐标记录下来, %最终得到整幅图像所有的候选点。 function pointAll = findInRowAndCol() clear;close all;clc; f = imread('test.jpg'); k=graythresh(f); img=im2bw(f,k); img = 255*img; [rows, cols] = size(img); skipRows = 1; currentState = 0; pointRow = []; pointCol = []; % C = []; %横向扫描 for row = 1:skipRows:rows stateCount(1) = 0; % 占比为1的黑色像素 stateCount(2) = 0; % 占比为1的白色像素 stateCount(3) = 0; % 占比为3的黑色像素 stateCount(4) = 0; % 占比为1的白色像素 stateCount(5) = 0; % 占比为1的黑色像素 currentState = 1; % 模块属性计数器(黑色像素模块/白色像素模块) ptr_row = img(row,:); for col = 1:cols if(ptr_row(col) < 128) %该像素为黑色 if(mod(currentState, 2) == 0) %若当前计数器为白色模块计数器,将其转入下一级计数器即黑色模块计数器 currentState = currentState + 1; end stateCount(currentState) = stateCount(currentState) + 1; else %该像素为白色 if(mod(currentState, 2) == 0) %若当前计数器为白色模块计数器,将其转入下一级计数器即黑色模块计数器 stateCount(currentState) = stateCount(currentState) + 1; else if(currentState == 5) %在最后一个黑色模块计数器后出现了一个白色像素,即已经获取了黑 白 黑 白 黑的连续像素片段 %需要开始通过1:1:3:1:1判断前5个模块是否是位置探测图形的特征 [check,totalFinderSize] = QRcheckRatio(stateCount);%判断是否符合1:1:3:1:1 % C = [C,check]; if(check == 1) %满足比例,记入 x = row; y = col - totalFinderSize/2; pointRow = [pointRow;[x,y]]; currentState = 1; stateCount(1) = 0; stateCount(2) = 0; stateCount(3) = 0; stateCount(4) = 0; stateCount(5) = 0; else % 不满足比例,继续扫描 currentState = 4; stateCount(1) = stateCount(3); stateCount(2) = stateCount(4); stateCount(3) = stateCount(5); stateCount(4) = 1; stateCount(5) = 0; end else % 不是最后一个黑色模块计数器5 % 转换为白色模块计数器 currentState = currentState + 1; stateCount(currentState) = stateCount(currentState) + 1; end end end end end %纵向扫描 for col = 1:skipRows:cols stateCount(1) = 0; % 占比为1的黑色像素 stateCount(2) = 0; % 占比为1的白色像素 stateCount(3) = 0; % 占比为3的黑色像素 stateCount(4) = 0; % 占比为1的白色像素 stateCount(5) = 0; % 占比为1的黑色像素 currentState = 1; % 模块属性计数器(黑色像素模块/白色像素模块) ptr_col = img(:,col); for row = 1:rows if(ptr_col(row) < 128) %该像素为黑色 if(mod(currentState, 2) == 0) %若当前计数器为白色模块计数器,将其转入下一级计数器即黑色模块计数器 currentState = currentState + 1; end stateCount(currentState) = stateCount(currentState) + 1; else %该像素为白色 if(mod(currentState, 2) == 0) %若当前计数器为白色模块计数器,将其转入下一级计数器即黑色模块计数器 stateCount(currentState) = stateCount(currentState) + 1; else if(currentState == 5) %在最后一个黑色模块计数器后出现了一个白色像素,即已经获取了黑 白 黑 白 黑的连续像素片段 %需要开始通过1:1:3:1:1判断前5个模块是否是位置探测图形的特征 [check,totalFinderSize] = QRcheckRatio(stateCount);%判断是否符合1:1:3:1:1 if(check) x = row - totalFinderSize/2; y = col; pointCol = [pointCol;[x,y]]; currentState = 1; stateCount(1) = 0; stateCount(2) = 0; stateCount(3) = 0; stateCount(4) = 0; stateCount(5) = 0; else % 不满足比例,继续扫描 currentState = 4; stateCount(1) = stateCount(3); stateCount(2) = stateCount(4); stateCount(3) = stateCount(5); stateCount(4) = 1; stateCount(5) = 0; end else % 不是最后一个黑色模块计数器5 % 转换为白色模块计数器 currentState = currentState + 1; stateCount(currentState) = stateCount(currentState) + 1; end end end end end %画点 pointAll = [pointRow; pointCol]; x = pointAll(:,1); y = pointAll(:,2); subplot(1,1,1) imshow(img); hold on plot(y,x,'*r'); grid on

其中判断是否满足比例关系的函数代码如下:

function [bool,totalFinderSize] = QRcheckRatio(stateCount) totalFinderSize = 0; for i = 1:5 count = stateCount(i); totalFinderSize = totalFinderSize + count; if(count == 0) bool = false; end end if(totalFinderSize 120 || angle2 > 120 || angle3 > 120) result = 0; %点在x方向上距离较近时的情况进行排除, %该情况下三点几乎呈现等边三角形并且x坐标值距离较近 elseif(angle1 < 70 && angle2 < 70 && angle3 < 70 &&... (abs(point1(2)-point2(2)) > length1/3.5 &&... abs(point2(2)-point3(2)) > length2/3.5 &&... abs(point1(2)-point3(2)) > length3/3.5)) result = 0; end %最终判断 if(result == 0) Feedback = 0; end

二次计算循环块1

function points = dectectAgain1(img, tol, numMax, count) clc;close all; count = count + 1; %重复定位次数增加一次 points = findInRowAndCol(img); %横纵像素扫描,找到拥有1:1:3:1:1比例的位置 tol = tol + count; %初始距离阈值 iterate =10; %最大迭代次数 num = 0; itnum = 0; numMax = numMax + 2; %结束迭代条件,小于numMax个点则结束 for i = 1:iterate [num, points,numRepeat] = Points_merge(tol,points); %近邻点融合函数 itnum = itnum + 1; if(num < numMax) %小于numMax个点集结束迭代 break; end end % 排序,前三个即为紧邻点数量最多的三个点 for i = 1:num-1 for j = i:num if(numRepeat(i) < numRepeat(j)) temp = numRepeat(i); numRepeat(i) = numRepeat(j); numRepeat(j) = temp; temp1 = points(i,1); points(i,1) = points(j,1); points(j,1) = temp1; temp2 = points(i,2); points(i,2) = points(j,2); points(j,2) = temp2; end end end %反馈 Feedback = detectFeedback(points); if(Feedback == 0 && tol > 1) points = dectectAgain2(img, tol, numMax, count); end

二次计算循环块2

function points = dectectAgain2(img, tol, numMax, count) clc;close all; count = count + 1; %重复定位次数增加一次 points = findInRowAndCol(img); %横纵像素扫描,找到拥有1:1:3:1:1比例的位置 tol = tol - count; %初始距离阈值 iterate =10; %最大迭代次数 num = 0; itnum = 0; numMax = numMax + 2; %结束迭代条件,小于numMax个点则结束 for i = 1:iterate [num, points,numRepeat] = Points_merge(tol,points); %近邻点融合函数 itnum = itnum + 1; if(num < numMax) %小于numMax个点集结束迭代 break; end end % 排序,前三个即为紧邻点数量最多的三个点 for i = 1:num-1 for j = i:num if(numRepeat(i) < numRepeat(j)) temp = numRepeat(i); numRepeat(i) = numRepeat(j); numRepeat(j) = temp; temp1 = points(i,1); points(i,1) = points(j,1); points(j,1) = temp1; temp2 = points(i,2); points(i,2) = points(j,2); points(j,2) = temp2; end end end %反馈 Feedback = detectFeedback(points); if(Feedback == 0 && tol > 1) points = dectectAgain1(img, tol, numMax, count); end

以上均为个人学习所得,欢迎分享交流。 本文参考: https://blog.csdn.net/c602273091/article/details/43901137



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3