如何利用opencv计算图像畸变系数,并进行校正与摄像机标定?

如何利用opencv计算图像畸变系数,并进行校正与摄像机标定?,第1张

如果知道图像,不知道相机还怎么通过相机来标定畸变

1:只给定一张图片可宏中以根据图像中相关特征进行标定缺誉,简单讲就是利用: line is straight 这个原理。

2:目前最常用的方法,是通过二维标定板,通过对 reprojection error 最小化进行非线性优化,来实蔽扮山现对相机的标定。并非根据看似高大上的训练集来标定。

3:畸变参数只是标定法所求参数的一部分,即:两个径向畸变系数和两个切向畸变系数。消除畸变的目的是让相机尽量地逼近针孔相机模型,这样相机成像时直线才会保持其直线性。

4:一般常见的畸变校正算法都是根据这一原理来实现的。当然,还有二般的情况。

#include "cv.h"

#include "highgui.h"

#include "cxcore.h"

#include "cvcam.h"

//图像的像素直接提取

#define_I(img,x,y) ((unsigned char*)((img)->imageData + (img)->widthStep*(y)))[(x)]

//亚像素级灰度值

#define_IF(image,x,y)( ((int)(x+1)-(x))*((int)(y+1)-(y))*_I((image),(int)(x),(int)(y)) + ((int)(x+1)-(x))*((y)-(int)(y))*_I((image),(int)(x),(int)(y+1)) + ((x)-(int)(x))*((int)(y+1)-(y))*_I((image),(int)(x+1),(int)(y)) + ((x)-(int)(x))*((y)-(int)(y))*_I((image),(int)(x+1),(int)(y+1)) )//插值后的像素值(IN表示interpolation),x、y可以为小数

void callback(IplImage* image)

void main()

{

int ncams = cvcamGetCamerasCount( )//返回可以访问的摄像头数目

HWND mywin

cvcamSetProperty(0, CVCAM_PROP_ENABLE, CVCAMTRUE)

cvcamSetProperty(0, CVCAM_PROP_RENDER, CVCAMTRUE)

mywin = (HWND)cvGetWindowHandle("cvcam window")

cvcamSetProperty(0, CVCAM_PROP_WINDOW, &mywin)

cvcamSetProperty(0, CVCAM_PROP_CALLBACK, callback)

//cvcamGetProperty(0, CVCAM_VIDEOFORMAT,NULL)

cvNamedWindow( "径向矫正1", 1 )//创建窗口

cvNamedWindow( "径向矫正2", 1 )//创建窗口

cvcamInit( )

cvcamStart( )

cvWaitKey(0)

cvcamStop( )

cvcamExit( )

cvDestroyWindow( "径向矫正1" )//销毁窗口

cvDestroyWindow( "径向矫正2" )//销毁窗口

}

void callback(IplImage* image)

{

IplImage* Show1 = cvCreateImage( cvSize(320,240), IPL_DEPTH_8U, 1)

IplImage* Show2 = cvCreateImage( cvSize(420,340), IPL_DEPTH_8U, 1)

IplImage* ImageC1 = cvCreateImage( cvSize(320,240), IPL_DEPTH_8U, 1)

//转换为灰度图

cvCvtColor( image, ImageC1, CV_RGB2GRAY)

cvFlip( ImageC1, NULL, 0)

double *mi

double *md

mi = new double[3*3]

md = new double[4]

CvMat intrinsic_matrix,distortion_coeffs

//腊核摄像机内参数

cvInitMatHeader(&intrinsic_matrix,3,3,CV_64FC1,mi)

//镜头畸变参数

cvInitMatHeader(&distortion_coeffs,1,4,CV_64FC1,md)

///////////////////////////////芹租////////////轮首掘//////

////////////////////////////320*240 120度广角镜头

//参数由matlab获得

double fc1,fc2,cc1,cc2,kc1,kc2,kc3,kc4

fc1 = 667.23923/2.5

fc2 = 669.78156/2.5

cc1 = 429.96933/2.5

cc2 = 351.48350/2.5

kc1 = -0.40100

kc2 = 0.19463

kc3 = 0.00508

kc4 = -0.00051

cvmSet(&intrinsic_matrix, 0, 0, fc1)

cvmSet(&intrinsic_matrix, 0, 1, 0)

cvmSet(&intrinsic_matrix, 0, 2, cc1)

cvmSet(&intrinsic_matrix, 1, 0, 0)

cvmSet(&intrinsic_matrix, 1, 1, fc2)

cvmSet(&intrinsic_matrix, 1, 2, cc2)

cvmSet(&intrinsic_matrix, 2, 0, 0)

cvmSet(&intrinsic_matrix, 2, 1, 0)

cvmSet(&intrinsic_matrix, 2, 2, 1)

cvmSet(&distortion_coeffs, 0, 0, kc1)

cvmSet(&distortion_coeffs, 0, 1, kc2)

cvmSet(&distortion_coeffs, 0, 2, kc3)

cvmSet(&distortion_coeffs, 0, 3, kc4)

////////////////////////////320*240 120度广角镜头

/////////////////////////////////////////////////

//矫正畸变(opencv)

cvUndistort2( ImageC1, Show1, &intrinsic_matrix, &distortion_coeffs)

//矫正畸变

for (int nx=0nx<420nx++)

{

for (int ny=0ny<340ny++)

{

double x=nx-50

double y=ny-50

double xx=(x-cc1)/fc1

double yy=(y-cc2)/fc2

double r2=pow(xx,2)+pow(yy,2)

double r4=pow(r2,2)

double xxx=xx*(1+kc1*r2+kc2*r4)+2*kc3*xx*yy+kc4*(r2+2*xx*xx)

double yyy=yy*(1+kc1*r2+kc2*r4)+2*kc4*xx*yy+kc3*(r2+2*yy*yy)

double xxxx = xxx*fc1+cc1

double yyyy = yyy*fc2+cc2

if (xxxx>0 &&xxxx<320 &&yyyy>0 &&yyyy<240)

{

_I(Show2,nx,ny) = (int)_IF(ImageC1,xxxx,yyyy)

}

else

{

_I(Show2,nx,ny) = 0

}

}

}

//画线

cvLine( Show1, cvPoint(0,10), cvPoint(320,10), cvScalar(255,255,255),3 )

cvLine( Show1, cvPoint(0,230), cvPoint(320,230), cvScalar(255,255,255),3 )

cvLine( Show1, cvPoint(10,0), cvPoint(10,240), cvScalar(255,255,255),3 )

cvLine( Show1, cvPoint(310,0), cvPoint(310,240), cvScalar(255,255,255),3 )

cvLine( Show1, cvPoint(0,0), cvPoint(320,240), cvScalar(255,255,255),3 )

cvLine( Show1, cvPoint(0,240), cvPoint(320,0), cvScalar(255,255,255),3 )

cvLine( Show1, cvPoint(0,10), cvPoint(320,10), cvScalar(0,0,0) )

cvLine( Show1, cvPoint(0,230), cvPoint(320,230), cvScalar(0,0,0) )

cvLine( Show1, cvPoint(10,0), cvPoint(10,240), cvScalar(0,0,0) )

cvLine( Show1, cvPoint(310,0), cvPoint(310,240), cvScalar(0,0,0) )

cvLine( Show1, cvPoint(0,0), cvPoint(320,240), cvScalar(0,0,0) )

cvLine( Show1, cvPoint(0,240), cvPoint(320,0), cvScalar(0,0,0) )

//显示

cvShowImage("径向矫正1", Show1)

cvShowImage("径向矫正2", Show2)

cvWaitKey(1)

cvReleaseImage( &Show1 )

cvReleaseImage( &Show2 )

cvReleaseImage( &ImageC1 )

}

来自: http://www.eyesourcecode.com/t/41983/1/1


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12414025.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存