2019-01-03 15:44:13 qq_27637587 阅读数 798

几何畸变图像恢复 OpenCV3 - 数字图像处理作业3

作业3:相同条件下拍到的棋盘图和日历钟表图,尝试建立几何畸变关系,并对它们进行恢复。注意:不能采用椭圆的变换。
在这里插入图片描述
在这里插入图片描述

算法步骤

  1. 坐标变换: 在畸变和正常图象之间建立坐标关系。
    在这里插入图片描述
  2. 灰度级插值,最邻近像素灰级代替法
    在这里插入图片描述

实际操作过程:

第一步. 角点检测

调用openCV角点检测函数获取棋盘格角点。

	//cornerMat CV_32FC2 56 rows * 1 cols * 2channel 取值用Point2f 或者 Vec2f
	findChessboardCorners(chessImg, Size(8, 7), cornerMat, CALIB_CB_FILTER_QUADS);
	drawChessboardCorners(chessCorner, Size(8, 7), cornerMat, true);
	imshow("chess with corner", chessCorner);

在这里插入图片描述

第二步. 得到畸变前的网格点位置

通过图片中心畸变小(基本无畸变)的特性,计算得出棋盘格角点畸变前的坐标,见下图绿色点。
畸变前网格点

第三步. 控制网格法得出畸变函数

为了拟合该图的函数,双线性变换参数不够,增加参数数量得到如下公式:
x=a0+a1x+a2y+a3xy+a4x2+a5y2+a6xy2+a7x2yx'=a_0+a_1x+a_2y+a_3xy+a_4x^2+a_5y^2+a_6xy^2+a_7x^2y y=b0+b1x+b2y+b3xy+b4x2+b5y2+b6xy2+b7x2yy'=b_0+b_1x+b_2y+b_3xy+b_4x^2+b_5y^2+b_6xy^2+b_7x^2y
一共16个未知数,通过梯度下降算法迭代来拟合函数,计算参数。由于畸变的中心对称性质,注意在参数计算中,将原点设为画面中心的点。

梯度下降拟合函数曲线过程

第四步. 最近邻像素插值

通过上一步得到的参数,计算原图中每个点的畸变后位置坐标,取最近邻像素值替代,即可恢复出原图像。
在这里插入图片描述
源代码下载链接

2017-12-03 16:48:48 Gavinv 阅读数 2279

鱼眼图像即便校正这个专题已经写到了第5版了,本次博客需要探讨的是关于在鱼眼图像畸变校正中的畸变半径的确定问题。同时结束鱼眼图像畸变校正的专题,在此做一个总结。并给出具体的解决方案。
鱼眼图像畸变半径的获取。
在之前的博客中已经探讨了关于如何进行鱼眼图像畸变矫正的方案,主要是说明了球面透视投影算法,以及基于等距模型的球面透视投影的方法,实际上这种空间坐标映射的变换方法难度很大。在处理这类问题的时候最主要的是要在头脑里建立5个坐标系:世界坐标系,摄像机坐标系,成像平面坐标系,图像图标系,像素平面坐标系。这5个具体的坐标系共同组成了一个完整的成像系统。其中摄像机坐标系以及成像平面坐标系可以看作是一个完整的坐标系统在简化的摄像机模型中作为一个坐标系统来近似。由于具体示意图不在手边,等之后完善修改的时候添加直观地示意图:
简要说明下这几个坐标系的意思:
世界坐标系:CCS实际上就是指现实世界的绝对坐标系。上北下南左西右东。实际的建立时建立的是三位的坐标系。
摄像机坐标系:实际上就是讲的已摄像机平面为参考平面的所建立的坐标系。空空间关系上来看摄像机坐标系并不总是与世界坐标系在同一平面。更多可能是一个交叉空间。
成像平面坐标系:在摄像机内部成像的过程中现实世界所成的像并不是直接在摄像机的坐标中心成像而是在摄像机的光学中心成像,所谓的光学中心实际上就是镜头组合的焦点。可以理解所称的像是在以光心为圆心的平面上的。
图像坐标系:图像所在的坐标系,不同的成像模型成像的关系是不同的。
像素坐标系:就是我们使用最为广泛的图像处理的坐标系。不同的系统原点位置不同。
这里在理清了这几个坐标系的关系之后下一步就是校正关系的推导。常见的鱼眼矫正的方法大致分为三类:2D空间校正,3D空间校正,基于内容的校正。
2D空间校正就是常见的经纬度校正。一般只用经度校正。CSDN上有一片写的很好的博客。
http://blog.csdn.net/lkj345/article/details/60146164
作者对经纬度校正做了比较详细的整理。值得借鉴但是注意一点文中使用的是MATLAB代码,为了进行效率优化作者使用了变换的矩阵操作代替了loop,这个做法很好。但是不建议C++实现时使用。在具体的C++实现时可以参考变换公式。
3D空间校正:
对于3D空间校正我之前的博客中已经写了很多了,具体的MATLAB代码在鱼眼图像畸变校正_|||中可以下载。在此不再赘述。
基于内容的校正:
这个方法是比较先进的方法使用到了机器学习的方法。但是实现起来难度较大。当然也可以思考将现在的一些深度学习模型迁移到这里来进行校正。说一下大致的思路基于内容的畸变校正时我们可以在获取到了相机模型的畸变参数之后使用SVM 的方法进行训练,训练的目的实际上就是为了为了得到更好的校正拟合参数。再将这个拟合参数加入到建立的相机模型中来辅助校正。这种方法可以得到最好的效果。但是运算量太大,不太适合工程使用。
在对鱼眼图像校正有了比较系统的认识之后,下一步需要做的就是对具体的实现方法的说明,当然不可能细致到每一项。相关的技术都有比较好的参考文档。我就不再班门弄斧。
精确的畸变参数的获取:
如果要做到比较精确的畸变参数的获取,就需要使用到张正友博士的棋盘标定的方法了。对于不同的参数需要使用不同的分辨率板。常见的就是获取摄像机的外参和内参,外参包括摄像机的旋转矩阵,平移矩阵。内参主要是摄像机的焦距以及畸变半径的修正参数。当然了除了这几个参数之外我们同样需要获取成像平面到图像坐标系平面的高度。以及成像平面到世界坐标系之间的高度。对于这些参数我们需要使用不同的标定板来得到。
鱼眼图像畸变半径的粗略估计:
基本思想是通过过图像处理的方式获得ROI区域。然后对ROI区域求解半径。
大致的方案:
二值化,形态学操作,连通域获取,最大外接矩形,半径计算,参数输出
这里写图片描述
这里写图片描述
到此本专题就结束了,希望有兴趣的朋友一起交流学习。(上图只是校正的效果不是最终的拼接效果)

2019-01-08 15:59:25 Aidam_Bo 阅读数 254

透镜由于制造精度以及组装工艺的偏差会引入畸变,导致原始图像的失真。镜头的畸变分为径向畸变和切向畸变两类。

1. 径向畸变

顾名思义,径向畸变就是沿着透镜半径方向分布的畸变,产生原因是光线在原理透镜中心的地方比靠近中心的地方更加弯曲,这种畸变在普通廉价的镜头中表现更加明显,径向畸变主要包括桶形畸变和枕形畸变两种。以下分别是枕形和桶形畸变示意图:

成像仪光轴中心的畸变为0,沿着镜头半径方向向边缘移动,畸变越来越严重。畸变的数学模型可以用主点(principle point)周围的泰勒级数展开式的前几项进行描述,通常使用前两项,即k1和k2,对于畸变很大的镜头,如鱼眼镜头,可以增加使用第三项k3来进行描述,成像仪上某点根据其在径向方向上的分布位置,调节公式为:

公式里(x0,y0)是畸变点在成像仪上的原始位置,(x,y)是畸变较真后新的位置,下图是距离光心不同距离上的点经过透镜径向畸变后点位的偏移示意图,可以看到,距离光心越远,径向位移越大,表示畸变也越大,在光心附近,几乎没有偏移。

2. 切向畸变

切向畸变是由于透镜本身与相机传感器平面(成像平面)或图像平面不平行而产生的,这种情况多是由于透镜被粘贴到镜头模组上的安装偏差导致。畸变模型可以用两个额外的参数p1和p2来描述:

下图显示某个透镜的切向畸变示意图,大体上畸变位移相对于左下——右上角的连线是对称的,说明该镜头在垂直于该方向上有一个旋转角度。

径向畸变和切向畸变模型中一共有5个畸变参数,在Opencv中他们被排列成一个5*1的矩阵,依次包含k1、k2、p1、p2、k3,经常被定义为Mat矩阵的形式,如Mat distCoeffs=Mat(1,5,CV_32FC1,Scalar::all(0));这5个参数就是相机标定中需要确定的相机的5个畸变系数。求得这5个参数后,就可以校正由于镜头畸变引起的图像的变形失真,下图显示根据镜头畸变系数校正后的效果:

2010-09-22 22:31:00 xingyu19871124 阅读数 13232

数字图像处理的课题报告打算做个图像畸变校正方向的,忙了几天把matlab仿真程序做出来了,下一步使用VC来实现这个过程!

这里先把程序贴出来以备后用!

梯形畸变的校正流程:直方图均衡---》垂直边缘检测----》开操作---》radon变换求极值---》求检测直线---》取点---》校正

matlab代码如下:

clc ;%清屏
clear all ;%清内存

%读取原图像
img=imread('大楼1.bmp') ;

%转化为灰度图像
img_gray=rgb2gray(img) ;
figure(1) ;
imshow(img_gray) ;
title('Gray Image') ;

%直方图均衡
img_histeq=histeq(img_gray) ;
figure(2) ;
imshow(img_histeq,[]) ;
title('Histgram Equalization Image') ;
%sobel边缘检测
%  img_sobel=edge(img_histeq,'sobel') ;
img_sobel=sobel(img_histeq) ;
figure(3) ;
imshow(img_sobel,[]) ;
title('Sobel Edge Detection ') ;
kernel=[1;1;1;1;1;1;1;1] ;
img_erode=imerode(img_sobel,kernel) ;
img_dilate=imdilate(img_erode,kernel) ;
figure(4)
imshow(img_dilate) ;
title('Dilate Image') ;
%radon检测直线
theta = 0:179;
[R,xp] = radon(img_dilate,theta);
figure(5) ;
imagesc(theta, xp, R); colormap(hot);
xlabel('/theta (degrees)'); ylabel('x/prime');
title('R_{/theta} (x/prime)');
colorbar

%计算直线 注意radon变换的圆心在图像的中心
gray_max1=max(max(R(:,1:90))) ;
gray_max2=max(max(R(:,90:180))) ;
[len1,theta1]=find(R==gray_max1) ;
[len2,theta2]=find(R==gray_max2) ;
theta1=theta1+90-1 ;
theta2=theta2-90-1 ;
len1=len1-length(R)/2 ;
len2=len2-length(R)/2;
%斜率
k1=-cot(theta1*pi/180) ;%注意前面要带负号,因为y朝下
k2=-cot(theta2*pi/180) ;

%求原点到直线的垂足的坐标
[m,n]=size(img_dilate) ;
x1=n/2+len1*sin(theta1*pi/180);
y1=m/2-len1*cos(theta1*pi/180);
x2=n/2-len2*sin(theta2*pi/180);
y2=m/2-len2*cos(theta2*pi/180);

%在图像中画线,标出检测出来的直线,直线方程为x-x0=k(y-y0) ;
y1_1=0 ;
x1_1=k1*(y1_1-y1)+x1 ;
y1_2=m ;
x1_2=k1*(y1_2-y1)+x1 ;

y2_1=0 ;
x2_1=k2*(y2_1-y2)+x2 ;
y2_2=m ;
x2_2=k2*(y2_2-y2)+x2 ;
figure(4) ;
hold on ;
% line('xdata', [left right], 'ydata', [top bottom])
%标注垂足
markpoint(x2,y2,'g') ;
markpoint(x1,y1,'g') ;
%将检测出来的直线画出来
line([x1_1,x1_2],[y1_1,y1_2]) ;
line([x2_1,x2_2],[y2_1,y2_2]) ;


%寻找四个连接点
y11=m*3/4 ;
x11=k1*(y11-y1)+x1 ;
y111=m/4 ;
x111=x11 ;
x11_1=k1*(y111-y1)+x1 ;
y21=y11 ;
x21=k2*(y21-y2)+x2 ;
y211=y111 ;
x211=x21 ;
x21_1=k2*(y211-y2)+x2 ;

markpoint(x11,y11,'g') ;
markpoint(x111,y111,'g') ;
markpoint(x11_1,y111,'r') ;
markpoint(x21,y21,'g') ;
markpoint(x211,y211,'g') ;
markpoint(x21_1,y211,'r') ;
%校正
basepoints=[x11 y11;x21 y21;x111,y111;x211,y211] ;
inputpoints=[x11 y11;x21 y21;x11_1,y111;x21_1,y211] ;
cpt=cp2tform(inputpoints,basepoints,'projective') ;
figure(6) ;
img_correction=imtransform(img,cpt) ;
imshow(img_correction);
title('Distortion Correction Image') ;

 

%标点函数

function markpoint(x,y,color)
line([x-5,x+5],[y,y],'Color',color) ;
line([x,x],[y-5,y+5],'Color',color) ;

%垂直边缘检测函数,不是sobel边缘检测

function img_sobel=sobel(img_test)
[m,n]=size(img_test) ;
img_sobel=zeros(m,n) ;
alpha=2 ;
for i=2:m-1
    for j=2:n-1
        temp=uint16(abs(int16(img_test(i-1,j-1))+alpha*int16(img_test(i,j-1))+int16(img_test(i+1,j-1))-int16(img_test(i-1,j+1))-alpha*int16(img_test(i,j+1))-int16(img_test(i+1,j+1)))) ;
        if(temp>125)
            temp=255 ;
        else
            temp=0 ;
        end
        img_sobel(i,j)=uint8(temp) ;
    end
end
return ;

2017-11-09 19:26:09 JNingWei 阅读数 4430

概念

对比角度 透视 畸变
概念本质 规律 像差
根本原因 单镜头在平面上描绘物体空间远近关系的必然缺陷 能让画面有更强的纵深感
能否补救 由机位和拍摄距离等因素决定的,对于单镜头而言 无法补救 通过技术 可改善
包含类型 扩展变形 & 压缩变形 桶形畸变 & 枕形畸变

Note:

  • 像差:指在光学中,实际像与根据单透镜理论确定的理想像的偏离。

具体类别

学名 类属 具体含义 运用
扩展变形 透视 小,距离感 + + 近距离拍摄,广角镜头能让画面有更强的纵深感
压缩变形 透视 大,距离感 - - 远距离拍摄,长焦镜头视角窄,能让画面显得更近
桶形畸变 畸变 镜头像场中央区的放大比率 大于 边缘区 艺术效果
枕形畸变 畸变 镜头像场中央区的放大比率 小于 边缘区 艺术效果

效果图

扩展变形:
这里写图片描述 这里写图片描述

压缩变形:
这里写图片描述

桶形畸变:
这里写图片描述

枕形畸变:
这里写图片描述



Ref :

摄影中的透视和畸变是一回事儿么?



FPGA图像处理之路

阅读数 1836

没有更多推荐了,返回首页