基于生长的棋盘格角点检测方法 代码介绍
本文主要讲述代码同时丰富参考博客中的一些小点和问题
参考文章:
https://blog.csdn.net/sunshine_zoe/article/details/78303658
参考资料
1、论文
Geiger A, Moosmann F, Car Ö, et al. Automatic camera and range sensor calibration using a single shot[C]//Robotics and Automation (ICRA), 2012 IEEE International Conference on. IEEE, 2012: 3936-3943.
2、代码网站(我改了其中一些的顺序,增加了一些用于适应自己的情况)
http://www.cvlibs.net/software/libcbdetect/
目录
直接上干货
代码块 MATLAB
增加地址(论文的代码里面没有的,适用于小白,地址需要改成自己的,增加的原因是有时候图片不能识别)
C:\Users\Administrator\Desktop\libcbdetect (1)\libcbdetect\matching
addpath('C:\Users\Administrator\Desktop\libcbdetect (1)\libcbdetect\matching');
addpath('C:\Users\Administrator\Desktop\libcbdetect (1)\libcbdetect\data');
I = imread('09.jpg');
demo.m分块:主要分为三大块。1.角点检测;2.棋盘格检测;3.画出来
corners = findCorners(I,0.01,1);
chessboards = chessboardsFromCorners(corners);
plotChessboards(chessboards,corners);
findcorners.m
灰度转换
img = im2double(img);
if length(size(img))==3
img = rgb2gray(img);
end
findCorners ::计算梯度的角度,归一化到【0,pi】;梯度强度,并归一化到【0,1】
% sobel masks 卷积核
du = [-1 0 1; -1 0 1; -1 0 1];
dv = du';
% compute image derivatives (for principal axes estimation)
img_du = conv2(double(img),du,'same');%卷积:对img进行du卷积,返回和img相同尺寸的卷积结果
img_dv = conv2(double(img),dv,'same');%两个方向的梯度
img_angle = atan2(img_dv,img_du); %梯度方向
img_weight = sqrt(img_du.^2+img_dv.^2); %梯度值
figure(1); imshow(img_weight); hold on;%%%%%%%%%%%%%%%1
% correct angle to lie in between [0,pi]
img_angle(img_angle<0) = img_angle(img_angle<0)+pi;
img_angle(img_angle>pi) = img_angle(img_angle>pi)-pi;
% scale input image
img = double(img);
img_min = min(img(:));
img_max = max(img(:));
img = (img-img_min)/(img_max-img_min);
findCorners::滤波(其实就是参考博客中写到的8个角点模型,卷积)
这里我增加了一个radius(4) = 30;使他可以检测到中心点附近的(广角相机)角点
createCorrelationPatch这个函数就是其中4个模型,后面会通过case1和case2来增加对称性但是颜色相反的模型。
原程序:
修改之后:
% 3 scales 后面会用到
radius(1) = 4;
radius(2) = 8;
radius(3) = 12;
radius(4) = 30;
% filter image
img_corners = zeros(size(img,1),size(img,2));
for template_class=1:size(template_props,1)
% create correlation template 创建三个/四个尺寸的四个模板
template = createCorrelationPatch(template_props(template_class,1),template_props(template_class,2),template_props(template_class,3));
% filter image according with current template 滤波(上面的四个模板)
img_corners_a1 = conv2(img,template.a1,'same');
img_corners_a2 = conv2(img,template.a2,'same');
img_corners_b1 = conv2(img,template.b1,'same');
img_corners_b2 = conv2(img,template.b2,'same');
% compute mean
img_corners_mu = (img_corners_a1+img_corners_a2+img_corners_b1+img_corners_b2)/4;
% case 1: a=white, b=black
img_corners_a = min(img_corners_a1-img_corners_mu,img_corners_a2-img_corners_mu);%每个元素单独比较
img_corners_b = min(img_corners_mu-img_corners_b1,img_corners_mu-img_corners_b2);
img_corners_1 = min(img_corners_a,img_corners_b);
% case 2: b=white, a=black
img_corners_a = min(img_corners_mu-img_corners_a1,img_corners_mu-img_corners_a2);
img_corners_b = min(img_corners_b1-img_corners_mu,img_corners_b2-img_corners_mu);
img_corners_2 = min(img_corners_a,img_corners_b);
% update corner map
img_corners = max(img_corners,img_corners_1);
img_corners = max(img_corners,img_corners_2);
end
findCorners::nonMaximumSuppression 非极大值抑制
原文给的非极大值抑制算法的详细原理参考:
http://www.cnblogs.com/liekkas0626/p/5219244.html
中第一个图片不知道是什么语言,我修改了一下,可以参考着看:
本文用了一个技巧,它先检测右上角部分,找到极大值点;
然后寻找该点的n*n的区域(处于右边沿的按照实际大小检测相应的大小);
如果n*n区域中还有更大的点就跳出,跳出的点作为新的检测点,继续循环;如果没有则判断它是否大于tau,得到极大值点,然后循环。
直到检测完整张图片。
function maxima = nonMaximumSuppression(img,n,tau,margin)%抑制范围0-n;极大值需要大于tau;
% extract parameters
width = size(img,2);
height = size(img,1);
% init maxima list 初始化
maxima = [];
%% non maximum suppression 非极大抑制
for i=n+1+margin: n+1: width-n-margin
for j=n+1+margin: n+1: height-n-margin
maxi = i;
maxj = j;
maxval = img(j,i);
for i2=i:i+n
for j2=j:j+n
currval = img(j2,i2);
if currval>maxval
maxi = i2;
maxj = j2;
maxval = currval;
end
end
end
%%
failed = 0;
for i2=maxi-n:min(maxi+n,width-margin)
for j2=maxj-n:min(maxj+n,height-margin)
currval = img(j2,i2);
if currval>maxval && (i2<i || i2>i+n || j2<j || j2>j+n)
failed = 1;
break;
end
end
if failed
break;
end
end
%%
if maxval>=tau && ~failed
maxima = [maxima; maxi maxj];%将得到的极大值点放到maxima后面,初始的maxima为空
end
end
end
findCorners::refineCorners 亚像素化 没有看直接贴出来
%% subpixel refinement 亚像素
if refine_corners
corners = refineCorners(img_du,img_dv,img_angle,img_weight,corners,10);
end
findCorners::去除杂点:1.不是边沿点;2.为角点打分,低于tau的删去
%% remove corners without edges
idx = corners.v1(:,1)==0 & corners.v1(:,2)==0;
corners.p(idx,:) = [];
corners.v1(idx,:) = [];
corners.v2(idx,:) = [];
figure(4); imshow(uint8(I2));hold on;%%%%%%%%%%%%%%%%4
alpha=0:pi/20:2*pi; %角度[0,2*pi]
R=4; %半径
x=R*cos(alpha);
y=R*sin(alpha);
for i=1:size(corners.p,1)
plot(x+corners.p(i,1),y+corners.p(i,2),'-')
fill(x+corners.p(i,1),y+corners.p(i,2),'r');
end
%%
disp('Scoring ...');
% score corners 角点得分
corners = scoreCorners(img,img_angle,img_weight,corners,radius);
% remove low scoring corners
idx = corners.score<tau;
corners.p(idx,:) = [];
corners.v1(idx,:) = [];
corners.v2(idx,:) = [];
corners.score(idx) = [];
figure(5); imshow(uint8(I2));hold on;%%%%%%%%%%%%%%%%5
alpha=0:pi/20:2*pi; %角度[0,2*pi]
R=4; %半径
x=R*cos(alpha);
y=R*sin(alpha);
for i=1:size(corners.p,1)
plot(x+corners.p(i,1),y+corners.p(i,2),'-')
fill(x+corners.p(i,1),y+corners.p(i,2),'r');
end
findCorners::最后,没看…还是写在这里
% make v1(:,1)+v1(:,2) positive (=> comparable to c++ code)
idx = corners.v1(:,1)+corners.v1(:,2)<0;
corners.v1(idx,:) = -corners.v1(idx,:);
% make all coordinate systems right-handed (reduces matching ambiguities from 8 to 4)
%使所有坐标系统向右(减少匹配模糊从8到4)
corners_n1 = [corners.v1(:,2) -corners.v1(:,1)];
flip = -sign(corners_n1(:,1).*corners.v2(:,1)+corners_n1(:,2).*corners.v2(:,2));
corners.v2 = corners.v2.*(flip*ones(1,2));
% convert to 0-based index
corners.p = corners.p-1;
根据角点找边沿
chessboards = chessboardsFromCorners(corners);
脚注
生成一个脚注1.
UML 图:
可以渲染序列图:
或者流程图:
离线写博客
即使用户在没有网络的情况下,也可以通过本编辑器离线写博客(直接在曾经使用过的浏览器中输入write.blog.csdn.net/mdeditor即可。Markdown编辑器使用浏览器离线存储将内容保存在本地。
用户写博客的过程中,内容实时保存在浏览器缓存中,在用户关闭浏览器或者其它异常情况下,内容不会丢失。用户再次打开浏览器时,会显示上次用户正在编辑的没有发表的内容。
博客发表后,本地缓存将被删除。
用户可以选择 把正在写的博客保存到服务器草稿箱,即使换浏览器或者清除缓存,内容也不会丢失。
注意:虽然浏览器存储大部分时候都比较可靠,但为了您的数据安全,在联网后,请务必及时发表或者保存到服务器草稿箱。
浏览器兼容
- 目前,本编辑器对Chrome浏览器支持最为完整。建议大家使用较新版本的Chrome。
- IE9以下不支持
- IE9,10,11存在以下问题
- 不支持离线功能
- IE9不支持文件导入导出
- IE10不支持拖拽文件导入
- 这里是 脚注 的 内容. ↩
上一篇: 图像分割:区域生长