如何用openCV进行坐标变换

keep1goal 2010-10-19 08:57:18
RT,最近在忙一个项目,单摄像头拍摄幕布,采集激光笔在幕布上的光点。问题是获得光点的图像坐标后(即在获取帧的bmp中的坐标),如何转换为幕布坐标系下的坐标?以幕布左下为原点,图像中并不一定对正幕布。只看了openCV上摄像头标定的例子,不甚理解。请各位大大帮个忙。
...全文
1203 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
keep1goal 2010-11-03
  • 打赏
  • 举报
回复

void __fastcall TForm1::Button7Click(TObject *Sender)
{

cvNamedWindow("摄像头标定",1);
//cvMoveWindow("摄像头标定",-1366,0);
capture = cvCaptureFromCAM(0);
frame2 = cvQueryFrame(capture);
//frame2=cvLoadImage("D:\\chess.jpg",1);
image2 = cvCreateImage(cvSize(frame2->width,frame2->height),8,3);
image2->origin =frame2->origin;
cvCopy(frame2,image2,0);

cvShowImage("摄像头标定",image2);

cvSetMouseCallback("摄像头标定",getPT,NULL);
//屏幕左上
scrmat->data.fl[0]=0;
scrmat->data.fl[1]=0;
//屏幕右上
scrmat->data.fl[2]=640;
scrmat->data.fl[3]=0;
//屏幕左下
scrmat->data.fl[4]=0;
scrmat->data.fl[5]=sHeight;
//屏幕右下
scrmat->data.fl[6]=640;
scrmat->data.fl[7]=sHeight;
}

void getPT(int event,int x,int y,int flags,void* t)
{
if(!image2)return;
if(image2->origin) //windows的bitmap标准
y = image2->height - y;
switch(event)
{
case CV_EVENT_LBUTTONDOWN:
imagept = cvPoint(x,y);
calib_sum++;
if(calib_sum==1)
{
cvCircle(image2,imagept,3,CV_RGB(255,0,0),2,8,0);
imagemat->data.fl[0]=x;
imagemat->data.fl[1]=y;
}
if(calib_sum==2)
{
cvCircle(image2,imagept,3,CV_RGB(255,0,0),2,8,0);
imagemat->data.fl[2]=x;
imagemat->data.fl[3]=y;
}
if(calib_sum==3)
{
cvCircle(image2,imagept,3,CV_RGB(255,0,0),2,8,0);
imagemat->data.fl[4]=x;
imagemat->data.fl[5]=y;
}
if(calib_sum==4)
{
cvCircle(image2,imagept,5,CV_RGB(255,0,0),2,8,0);
cvShowImage("摄像头标定",image2);
imagemat->data.fl[6]=x;
imagemat->data.fl[7]=y;
cvFindHomography(imagemat,scrmat,homo);
int bSave=MessageBox(NULL,"已获得透视矩阵,是否存储?","投影笔",MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2);
if(bSave==IDYES)
{
CvFileStorage *file=cvOpenFileStorage("homo.xml",NULL,CV_STORAGE_WRITE);
cvWrite(file,"A",homo,cvAttrList(0,0));
cvReleaseFileStorage(&file);
Savehomo=true;
}

Gethomo=true;
calib_sum=0;
cvReleaseCapture(&capture);
cvDestroyWindow("摄像头标定");
}
cvShowImage("摄像头标定",image2);
break;
}
}
前几天忙,忘回帖了。就此结贴,谢谢各位!
keep1goal 2010-10-21
  • 打赏
  • 举报
回复
晚上把代码贴出来。
keep1goal 2010-10-21
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 chy_ai_ni 的回复:]

这个问题可以通过坐标映射来完成。但是我看你的描述是想在没有额外数据的情况下进行转换,这个有点难度。一般的转换是先找至少4个点,这些点的屏幕坐标和幕布坐标都是已知的,然后根据这至少4个点来计算出转换参数,再用转换参数去把屏幕坐标转换为幕布坐标。
另外这个转换不需要定标,只是一个简单的仿射变换。
[/Quote]
呵呵,我用国际象棋盘的内角点来定位,不是没有额外数据。
你说不用定标,我很赞同,看来自己想复杂了。
最近找到了一篇投影变换的文章,很有启发。
投影几何校正原理简介
http://hi.baidu.com/mtapp/blog/item/d14bb8f6945c101eb07ec503.html
april1yu 2010-10-20
  • 打赏
  • 举报
回复
http://www.opencv.org.cn/index.php/%E9%A6%96%E9%A1%B5
fengbingchun 2010-10-20
  • 打赏
  • 举报
回复
去OpenCV论坛看看吧
chy_ai_ni 2010-10-20
  • 打赏
  • 举报
回复
这个问题可以通过坐标映射来完成。但是我看你的描述是想在没有额外数据的情况下进行转换,这个有点难度。一般的转换是先找至少4个点,这些点的屏幕坐标和幕布坐标都是已知的,然后根据这至少4个点来计算出转换参数,再用转换参数去把屏幕坐标转换为幕布坐标。
另外这个转换不需要定标,只是一个简单的仿射变换。
keep1goal 2010-10-20
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 xiuxianshen 的回复:]

OpenCV好像是左上原点
[/Quote]
openCV是坐下为原点。
我想这个问题应该是投影映射,用不上摄像头的标定。因为摄像头标定目的是获得像素/厘米的对应关系,进行距离测定的。不标定也可用投影映射。大家看如何?
xiuxianshen 2010-10-20
  • 打赏
  • 举报
回复
OpenCV好像是左上原点

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧