自动驾驶AVM环视算法–全景的俯视图像和原图

测试环境 

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("视频播放");

输出的测试视频

https://www.bilibili.com/video/BV1ab4y1N7pM/

未经允许不得转载:金书世界 » 自动驾驶AVM环视算法–全景的俯视图像和原图

相关文章

评论 (0)