当前位置:   article > 正文

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

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

测试环境 

opencv310

vs2022

参考:金书世界

算法源码获取:

链接:https://pan.baidu.com/s/1kVUA2YgRAxk7m1TYi-wsnQ?pwd=aax9 提取码:aax9 

算法的实现主要是根据四个摄像头的安装位置、相机的的内外参数实现对图像的畸变矫正、视图的变换和全景的图像拼接、图像拼接的位置的平滑过度;

测试的输出效果图像

算法的实现过程

需要根据标定相机的外参数初始化相机旋转和平移矩阵

  1. 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);
  2. 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);
  3. 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);
  4. 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);

需要根据标定相机的内参参数初始化相机畸变矫正参数(当前测试的相机内参是相同的,所以使用相同的参数进行初始化)

  1. for (int i = 0; i < 4; i++)
  2. {
  3. Data->Aa[i] = a[i];
  4. Data->Fa[i] = a[i];
  5. Data->Ba[i] = a[i];
  6. Data->La[i] = a[i];
  7. Data->Ra[i] = a[i];
  8. }

创建拼接系数表的内存并初始化参数表

  1. Data->Ftable = (float*)malloc(Dw * Dh * sizeof(float));
  2. Data->Btable = (float*)malloc(Dw * Dh * sizeof(float));
  3. Data->Ltable = (float*)malloc(Dw * Dh * sizeof(float));
  4. Data->Rtable = (float*)malloc(Dw * Dh * sizeof(float));

初始化后的系数表可视化显示的结果

  1. Dimg[3 * i + 0 + j * 3 * Dw] += (unsigned char)(Data->Ftable[i + j * Dw] * 255);
  2. Dimg[3 * i + 1 + j * 3 * Dw] += (unsigned char)(Data->Ftable[i + j * Dw] * 255);
  3. Dimg[3 * i + 2 + j * 3 * Dw] += (unsigned char)(Data->Ftable[i + j * Dw] * 255);
  4. Dimg[3 * i + 0 + j * 3 * Dw] += (unsigned char)(Data->Btable[i + j * Dw] * 255);
  5. Dimg[3 * i + 1 + j * 3 * Dw] += (unsigned char)(Data->Btable[i + j * Dw] * 255);
  6. Dimg[3 * i + 2 + j * 3 * Dw] += (unsigned char)(Data->Btable[i + j * Dw] * 255);
  7. Dimg[3 * i + 0 + j * 3 * Dw] += (unsigned char)(Data->Ltable[i + j * Dw] * 255);
  8. Dimg[3 * i + 1 + j * 3 * Dw] += (unsigned char)(Data->Ltable[i + j * Dw] * 255);
  9. Dimg[3 * i + 2 + j * 3 * Dw] += (unsigned char)(Data->Ltable[i + j * Dw] * 255);
  10. Dimg[3 * i + 0 + j * 3 * Dw] += (unsigned char)(Data->Rtable[i + j * Dw] * 255);
  11. Dimg[3 * i + 1 + j * 3 * Dw] += (unsigned char)(Data->Rtable[i + j * Dw] * 255);
  12. Dimg[3 * i + 2 + j * 3 * Dw] += (unsigned char)(Data->Rtable[i + j * Dw] * 255);

前视系数表可视化的结果

后视系数表可视化的结果

左视系数表可视化的结果

右视系数表可视化的结果

各个视图的和系数表想成后的结果如下所示

前视图像和系数表相乘后的结果

后视图像和系数表相乘后的结果

左视图像和系数表相乘后的结果

右视图像和系数表相乘后的结果

融合拼接后的效果

获取四个摄像头的图像数据(本测试使用的是opencv读取图像的方式实现的)

  1. CvCapture* C_img_F = cvCreateFileCapture("G:\\CSDN\\AVM\\Video\\Front.avi");
  2. CvCapture* C_img_B = cvCreateFileCapture("G:\\CSDN\\AVM\\Video\\Back.avi");
  3. CvCapture* C_img_L = cvCreateFileCapture("G:\\CSDN\\AVM\\Video\\Left.avi");
  4. CvCapture* C_img_R = cvCreateFileCapture("G:\\CSDN\\AVM\\Video\\Right.avi");
  5. img_F = cvQueryFrame(C_img_F)
  6. img_B = cvQueryFrame(C_img_B);
  7. img_L = cvQueryFrame(C_img_L);
  8. 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);

输出图像的拼接函数

  1. cvSetImageROI(img_AVM_all, cvRect(0, 0, 1280, 720));
  2. cvCopy(img_F, img_AVM_all);
  3. cvResetImageROI(img_AVM_all);
  4. cvSetImageROI(img_AVM_all, cvRect(1280, 0, 1280, 720));
  5. cvCopy(img_B, img_AVM_all);
  6. cvResetImageROI(img_AVM_all);
  7. cvSetImageROI(img_AVM_all, cvRect(0, 720, 1280, 720));
  8. cvCopy(img_L, img_AVM_all);
  9. cvResetImageROI(img_AVM_all);
  10. cvSetImageROI(img_AVM_all, cvRect(1280, 720, 1280, 720));
  11. cvCopy(img_R, img_AVM_all);
  12. cvResetImageROI(img_AVM_all);
  13. cvSetImageROI(img_AVM_all, cvRect(1280*2, 0, 1080, 1440));
  14. cvCopy(img_AVM, img_AVM_all);
  15. cvResetImageROI(img_AVM_all);

算法的图片的测试代码

  1. // TODO: 在此添加控件通知处理程序代码
  2. IplImage* img_AVM = cvCreateImage(cvSize(1080, 1920), 8, 3);
  3. IplImage* img_AVM_resize = cvCreateImage(cvSize(404, 720), 8, 3);
  4. IplImage* img_F = cvLoadImage("Front.png");
  5. IplImage* img_B = cvLoadImage("Back.png");
  6. IplImage* img_L = cvLoadImage("Left.png");
  7. IplImage* img_R = cvLoadImage("Right.png");
  8. IplImage* det_TOP_F = cvCreateImage(cvSize(img_F->width, img_F->height), img_F->depth, img_F->nChannels);
  9. IplImage* det_TOP_B = cvCreateImage(cvSize(img_B->width, img_B->height), img_B->depth, img_B->nChannels);
  10. IplImage* det_TOP_L = cvCreateImage(cvSize(img_L->width, img_L->height), img_L->depth, img_L->nChannels);
  11. IplImage* det_TOP_R = cvCreateImage(cvSize(img_L->width, img_L->height), img_L->depth, img_L->nChannels);
  12. js_AVM_obj AVMData;
  13. js_init_avm(&AVMData, img_AVM->width, img_AVM->height);
  14. 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);
  15. cvWaitKey(0);

算法视频测试代码

  1. // TODO: 在此添加控件通知处理程序代码
  2. IplImage* img_AVM_all = cvCreateImage(cvSize(1280*2+1080, 1440), 8, 3);
  3. IplImage* img_AVM = cvCreateImage(cvSize(1080, 1440), 8, 3);
  4. IplImage* img_AVM_resize = cvCreateImage(cvSize(1200, 480), 8, 3);
  5. IplImage* det_TOP_F = cvCreateImage(cvSize(1280, 720), 8, 3);
  6. IplImage* det_TOP_B = cvCreateImage(cvSize(1280, 720), 8, 3);
  7. IplImage* det_TOP_L = cvCreateImage(cvSize(1280, 720), 8, 3);
  8. IplImage* det_TOP_R = cvCreateImage(cvSize(1280, 720), 8, 3);
  9. CvVideoWriter* writer = cvCreateVideoWriter("G:\\CSDN\\AVM\\Video\\AVM_Result.avi", CV_FOURCC('X', 'V', 'I', 'D'), 25, cvSize(1280 * 2 + 1080, 1440));
  10. cvNamedWindow("视频播放", CV_WINDOW_AUTOSIZE);
  11. CvCapture* C_img_F = cvCreateFileCapture("G:\\CSDN\\AVM\\Video\\Front.avi");
  12. CvCapture* C_img_B = cvCreateFileCapture("G:\\CSDN\\AVM\\Video\\Back.avi");
  13. CvCapture* C_img_L = cvCreateFileCapture("G:\\CSDN\\AVM\\Video\\Left.avi");
  14. CvCapture* C_img_R = cvCreateFileCapture("G:\\CSDN\\AVM\\Video\\Right.avi");
  15. IplImage* img_F, *img_B, *img_L, *img_R;
  16. js_AVM_obj AVMData;
  17. js_init_avm(&AVMData, img_AVM->width, img_AVM->height);
  18. while (img_F = cvQueryFrame(C_img_F))
  19. {
  20. img_B = cvQueryFrame(C_img_B);
  21. img_L = cvQueryFrame(C_img_L);
  22. img_R = cvQueryFrame(C_img_R);
  23. 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);
  24. cvSetImageROI(img_AVM_all, cvRect(0, 0, 1280, 720));
  25. cvCopy(img_F, img_AVM_all);
  26. cvResetImageROI(img_AVM_all);
  27. cvSetImageROI(img_AVM_all, cvRect(1280, 0, 1280, 720));
  28. cvCopy(img_B, img_AVM_all);
  29. cvResetImageROI(img_AVM_all);
  30. cvSetImageROI(img_AVM_all, cvRect(0, 720, 1280, 720));
  31. cvCopy(img_L, img_AVM_all);
  32. cvResetImageROI(img_AVM_all);
  33. cvSetImageROI(img_AVM_all, cvRect(1280, 720, 1280, 720));
  34. cvCopy(img_R, img_AVM_all);
  35. cvResetImageROI(img_AVM_all);
  36. cvSetImageROI(img_AVM_all, cvRect(1280*2, 0, 1080, 1440));
  37. cvCopy(img_AVM, img_AVM_all);
  38. cvResetImageROI(img_AVM_all);
  39. cvWriteFrame(writer, img_AVM_all);
  40. cvResize(img_AVM_all, img_AVM_resize);
  41. cvShowImage("视频播放", img_AVM_resize);
  42. char c = cvWaitKey(1);
  43. if (c == 27)break;
  44. }
  45. cvReleaseVideoWriter(&writer);
  46. cvReleaseCapture(&C_img_F);
  47. cvReleaseCapture(&C_img_B);
  48. cvReleaseCapture(&C_img_L);
  49. cvReleaseCapture(&C_img_R);
  50. cvDestroyWindow("视频播放");

输出的测试视频

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

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号