赞
踩
测试环境
opencv310
vs2022
参考:金书世界
算法源码获取:
链接:https://pan.baidu.com/s/1kVUA2YgRAxk7m1TYi-wsnQ?pwd=aax9 提取码:aax9
算法的实现主要是根据四个摄像头的安装位置、相机的的内外参数实现对图像的畸变矫正、视图的变换和全景的图像拼接、图像拼接的位置的平滑过度;
测试的输出效果图像
算法的实现过程
需要根据标定相机的外参数初始化相机旋转和平移矩阵
- js_initAngle(Data->data_TOP_F, 90, 0, 0); js_initAngle(Data->data_0_F, 25, 0, 0); js_initAngleT(Data->data_TOP_F, Data->data_TOP_T_F);
- js_initAngle(Data->data_TOP_B, 90, 0, 180); js_initAngle(Data->data_0_B, 25, 0, 0); js_initAngleT(Data->data_TOP_B, Data->data_TOP_T_B);
- js_initAngle(Data->data_TOP_L, 90, -90, 0); js_initAngle(Data->data_0_L, 25, 0, 0); js_initAngleT(Data->data_TOP_L, Data->data_TOP_T_L);
- js_initAngle(Data->data_TOP_R, 90, 90, 0); js_initAngle(Data->data_0_R, 25, 0, 0); js_initAngleT(Data->data_TOP_R, Data->data_TOP_T_R);
需要根据标定相机的内参参数初始化相机畸变矫正参数(当前测试的相机内参是相同的,所以使用相同的参数进行初始化)
- for (int i = 0; i < 4; i++)
- {
- Data->Aa[i] = a[i];
- Data->Fa[i] = a[i];
- Data->Ba[i] = a[i];
- Data->La[i] = a[i];
- Data->Ra[i] = a[i];
- }
创建拼接系数表的内存并初始化参数表
- Data->Ftable = (float*)malloc(Dw * Dh * sizeof(float));
- Data->Btable = (float*)malloc(Dw * Dh * sizeof(float));
- Data->Ltable = (float*)malloc(Dw * Dh * sizeof(float));
- Data->Rtable = (float*)malloc(Dw * Dh * sizeof(float));
初始化后的系数表可视化显示的结果
- Dimg[3 * i + 0 + j * 3 * Dw] += (unsigned char)(Data->Ftable[i + j * Dw] * 255);
- Dimg[3 * i + 1 + j * 3 * Dw] += (unsigned char)(Data->Ftable[i + j * Dw] * 255);
- Dimg[3 * i + 2 + j * 3 * Dw] += (unsigned char)(Data->Ftable[i + j * Dw] * 255);
-
- Dimg[3 * i + 0 + j * 3 * Dw] += (unsigned char)(Data->Btable[i + j * Dw] * 255);
- Dimg[3 * i + 1 + j * 3 * Dw] += (unsigned char)(Data->Btable[i + j * Dw] * 255);
- Dimg[3 * i + 2 + j * 3 * Dw] += (unsigned char)(Data->Btable[i + j * Dw] * 255);
-
- Dimg[3 * i + 0 + j * 3 * Dw] += (unsigned char)(Data->Ltable[i + j * Dw] * 255);
- Dimg[3 * i + 1 + j * 3 * Dw] += (unsigned char)(Data->Ltable[i + j * Dw] * 255);
- Dimg[3 * i + 2 + j * 3 * Dw] += (unsigned char)(Data->Ltable[i + j * Dw] * 255);
-
- Dimg[3 * i + 0 + j * 3 * Dw] += (unsigned char)(Data->Rtable[i + j * Dw] * 255);
- Dimg[3 * i + 1 + j * 3 * Dw] += (unsigned char)(Data->Rtable[i + j * Dw] * 255);
- Dimg[3 * i + 2 + j * 3 * Dw] += (unsigned char)(Data->Rtable[i + j * Dw] * 255);
前视系数表可视化的结果
后视系数表可视化的结果
左视系数表可视化的结果
右视系数表可视化的结果
各个视图的和系数表想成后的结果如下所示
前视图像和系数表相乘后的结果
后视图像和系数表相乘后的结果
左视图像和系数表相乘后的结果
右视图像和系数表相乘后的结果
融合拼接后的效果
获取四个摄像头的图像数据(本测试使用的是opencv读取图像的方式实现的)
- CvCapture* C_img_F = cvCreateFileCapture("G:\\CSDN\\AVM\\Video\\Front.avi");
- CvCapture* C_img_B = cvCreateFileCapture("G:\\CSDN\\AVM\\Video\\Back.avi");
- CvCapture* C_img_L = cvCreateFileCapture("G:\\CSDN\\AVM\\Video\\Left.avi");
- CvCapture* C_img_R = cvCreateFileCapture("G:\\CSDN\\AVM\\Video\\Right.avi");
- img_F = cvQueryFrame(C_img_F)
- img_B = cvQueryFrame(C_img_B);
- img_L = cvQueryFrame(C_img_L);
- img_R = cvQueryFrame(C_img_R);
算法实现函数
js_getAVM_TOP(&AVMData, img_AVM->imageData, img_F->imageData, img_B->imageData, img_L->imageData, img_R->imageData, img_F->width, img_F->height, img_AVM->width, img_AVM->height, img_AVM->nChannels);
输出图像的拼接函数
- cvSetImageROI(img_AVM_all, cvRect(0, 0, 1280, 720));
- cvCopy(img_F, img_AVM_all);
- cvResetImageROI(img_AVM_all);
-
- cvSetImageROI(img_AVM_all, cvRect(1280, 0, 1280, 720));
- cvCopy(img_B, img_AVM_all);
- cvResetImageROI(img_AVM_all);
-
- cvSetImageROI(img_AVM_all, cvRect(0, 720, 1280, 720));
- cvCopy(img_L, img_AVM_all);
- cvResetImageROI(img_AVM_all);
-
- cvSetImageROI(img_AVM_all, cvRect(1280, 720, 1280, 720));
- cvCopy(img_R, img_AVM_all);
- cvResetImageROI(img_AVM_all);
-
- cvSetImageROI(img_AVM_all, cvRect(1280*2, 0, 1080, 1440));
- cvCopy(img_AVM, img_AVM_all);
- cvResetImageROI(img_AVM_all);
算法的图片的测试代码
- // TODO: 在此添加控件通知处理程序代码
- IplImage* img_AVM = cvCreateImage(cvSize(1080, 1920), 8, 3);
- IplImage* img_AVM_resize = cvCreateImage(cvSize(404, 720), 8, 3);
- IplImage* img_F = cvLoadImage("Front.png");
- IplImage* img_B = cvLoadImage("Back.png");
- IplImage* img_L = cvLoadImage("Left.png");
- IplImage* img_R = cvLoadImage("Right.png");
- IplImage* det_TOP_F = cvCreateImage(cvSize(img_F->width, img_F->height), img_F->depth, img_F->nChannels);
- IplImage* det_TOP_B = cvCreateImage(cvSize(img_B->width, img_B->height), img_B->depth, img_B->nChannels);
- IplImage* det_TOP_L = cvCreateImage(cvSize(img_L->width, img_L->height), img_L->depth, img_L->nChannels);
- IplImage* det_TOP_R = cvCreateImage(cvSize(img_L->width, img_L->height), img_L->depth, img_L->nChannels);
-
- js_AVM_obj AVMData;
- js_init_avm(&AVMData, img_AVM->width, img_AVM->height);
- js_getAVM_TOP(&AVMData,img_AVM->imageData, img_F->imageData, img_B->imageData, img_L->imageData, img_R->imageData, img_F->width, img_F->height, img_AVM->width, img_AVM->height, img_AVM->nChannels);
-
-
- cvWaitKey(0);
算法视频测试代码
- // TODO: 在此添加控件通知处理程序代码
- IplImage* img_AVM_all = cvCreateImage(cvSize(1280*2+1080, 1440), 8, 3);
- IplImage* img_AVM = cvCreateImage(cvSize(1080, 1440), 8, 3);
- IplImage* img_AVM_resize = cvCreateImage(cvSize(1200, 480), 8, 3);
- IplImage* det_TOP_F = cvCreateImage(cvSize(1280, 720), 8, 3);
- IplImage* det_TOP_B = cvCreateImage(cvSize(1280, 720), 8, 3);
- IplImage* det_TOP_L = cvCreateImage(cvSize(1280, 720), 8, 3);
- IplImage* det_TOP_R = cvCreateImage(cvSize(1280, 720), 8, 3);
-
- CvVideoWriter* writer = cvCreateVideoWriter("G:\\CSDN\\AVM\\Video\\AVM_Result.avi", CV_FOURCC('X', 'V', 'I', 'D'), 25, cvSize(1280 * 2 + 1080, 1440));
- cvNamedWindow("视频播放", CV_WINDOW_AUTOSIZE);
- CvCapture* C_img_F = cvCreateFileCapture("G:\\CSDN\\AVM\\Video\\Front.avi");
- CvCapture* C_img_B = cvCreateFileCapture("G:\\CSDN\\AVM\\Video\\Back.avi");
- CvCapture* C_img_L = cvCreateFileCapture("G:\\CSDN\\AVM\\Video\\Left.avi");
- CvCapture* C_img_R = cvCreateFileCapture("G:\\CSDN\\AVM\\Video\\Right.avi");
- IplImage* img_F, *img_B, *img_L, *img_R;
- js_AVM_obj AVMData;
- js_init_avm(&AVMData, img_AVM->width, img_AVM->height);
- while (img_F = cvQueryFrame(C_img_F))
- {
- img_B = cvQueryFrame(C_img_B);
- img_L = cvQueryFrame(C_img_L);
- img_R = cvQueryFrame(C_img_R);
- js_getAVM_TOP(&AVMData, img_AVM->imageData, img_F->imageData, img_B->imageData, img_L->imageData, img_R->imageData, img_F->width, img_F->height, img_AVM->width, img_AVM->height, img_AVM->nChannels);
-
-
- cvSetImageROI(img_AVM_all, cvRect(0, 0, 1280, 720));
- cvCopy(img_F, img_AVM_all);
- cvResetImageROI(img_AVM_all);
-
- cvSetImageROI(img_AVM_all, cvRect(1280, 0, 1280, 720));
- cvCopy(img_B, img_AVM_all);
- cvResetImageROI(img_AVM_all);
-
- cvSetImageROI(img_AVM_all, cvRect(0, 720, 1280, 720));
- cvCopy(img_L, img_AVM_all);
- cvResetImageROI(img_AVM_all);
-
- cvSetImageROI(img_AVM_all, cvRect(1280, 720, 1280, 720));
- cvCopy(img_R, img_AVM_all);
- cvResetImageROI(img_AVM_all);
-
- cvSetImageROI(img_AVM_all, cvRect(1280*2, 0, 1080, 1440));
- cvCopy(img_AVM, img_AVM_all);
- cvResetImageROI(img_AVM_all);
-
- cvWriteFrame(writer, img_AVM_all);
- cvResize(img_AVM_all, img_AVM_resize);
- cvShowImage("视频播放", img_AVM_resize);
- char c = cvWaitKey(1);
- if (c == 27)break;
- }
- cvReleaseVideoWriter(&writer);
- cvReleaseCapture(&C_img_F);
- cvReleaseCapture(&C_img_B);
- cvReleaseCapture(&C_img_L);
- cvReleaseCapture(&C_img_R);
- cvDestroyWindow("视频播放");
输出的测试视频
自动驾驶AVM环视算法实现全景的俯视图像和原图
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。