首页 > 其他分享 >智能车图像处理逆透视教程

智能车图像处理逆透视教程

时间:2022-11-03 12:23:46浏览次数:86  
标签:教程 Mat 透视 图像处理 RESULT 图像 un change

去畸变请参考:图像处理去畸变教程_LoseHu的博客-CSDN博客

去畸变+逆透视请参考:​​​​​​​​​​​​​​​​​​​​​智能车去畸变+逆透视教程_LoseHu的博客-CSDN博客

逆透视:如下

1.简介

对于初做车的同学,看见摄像头图像神奇的侧视角难免会有些烦躁,我刚开始也是如此,所以在此,想详细的分享一下我们的透视变换方案。(实战教学)

先上各种效果图。

​编辑

编辑

​编辑​编辑​编辑

优点:

        使用指针映射透视变换数组,只需要初始化映射一次,后续不需要时间​​​​​​​

        通用性强,可移植性高

       还可以已知原图坐标情况下求透视后坐标

2.摄像头环境

        硬件:总钻风摄像头(由于多车组使用沁恒芯片,修改过硬件适应dvp)

        镜头:140度镜头,畸变小于5%

        摄像头分辨率:120*188(长*宽)

        透视图分辨率:100*114(长*宽)

        摄像头高度:30cm左右

总钻风是很常见的智能车摄像头,之所以选用140度镜头,是因为其角度大,且畸变率非常小,完全不影响图像处理,可以省去去畸变的烦恼,摄像头120*188是因为其比例可以使视野最大。

3.逆透视简单原理

        众所周知,对于十字这个元素,标准赛道(不算路肩、黑胶带),它是一个宽度为45cm的标准正方形。但是因为摄像头角度问题,十字的正方形在图片中是一个梯形。

 

编辑

那嚒我们所要做的,就是根据图片中的这一块梯形(实则是正方形),这一个信息,将图片进行拉伸变换,使之成为标准的俯视图。

​编辑

 公式:

编辑

 w与w’在二维图中为1

编辑

 已知结果图中坐标,通过上述公式就能在原图中找到对应的坐标。

编辑

 那么这个3*3矩阵就是我们需要使用上位机求取的。

4.通过上位机求取矩阵

环境准备:

          拍摄的十字图像(或正方形图像),灰度与二值化图均可,要能完全展示出正方形部分,如:

​编辑​编辑

 图像中可以显示出车头,因为在后续的透视过程中可以通过图像修改参数平移去除。

那么,根据图中的假正方形,就可以进行后续操作。

上位机操作:

 

​编辑

 结果图宽高:得到的透视图像的宽高。

方形中心距顶部像素:在结果图中,正方形的中心,距离图像最上端多少个像素行(值越大,图像越向下平移)。

方形像素边长:在结果图中,正方形的边长相当于多少个像素(值越大,图片就会被放大更多,如果是45,就是一像素对应1cm距离)。

四个XY值:图中方形四个顶点的坐标,通过鼠标右键在图中点击就可以自动输入(点击顺序:左下---右下---左上---右上)。


逆透视上位机操作:https://live.csdn.net/v/231520

     最终矩阵会复制到您的剪切板中,如:

{{-10.603578,4.261626,-292.576700},
{0.665623,6.708527,-1508.674551},
{0.000570,0.016935,-2.741442}};

 

注意事项:

        1.图片经过逆透视操作后得到的结果图,因为对图片进行了拉伸,底边两个角落可能会出现无内容部分(如下图),使用时应当避免.可通过修改结果图大小,或者增大方形中心距顶部像素来对图形进行平移去除。

编辑

         2.鼠标点击顺序要符合左下---右下---左上---右上。

         有些图片打开失败,请检查图片后缀,有的是jpg格式,后缀却是bmp。

编辑

5.在智能车上使用矩阵:

原理说明:

求得矩阵后,就可根据矩阵,和结果图的坐标,计算出结果图中的某个点,在原图中的坐标。

但如果每获取到一帧图像,都进行一次映射,非常耗费时间。所以我们使用指针。

在初始化时只需要对指针地址进行一次映射,以后只需要调用指针数组,就可以获取到透视后的图。(需要注意的是,和图像一样的大的指针数组可能会导致您的内存溢出,所以建议将透视图尺寸缩小,即减小RESULT_ROW与RESULT_COL也可以避免黑边出现

change_un_Mat[3][3] 是你通过上位机求取的矩阵,在您的剪切板中。

ImageUsed[0][0]代表图像左上角的值

PER_IMG    为用来透视变换的图片,如果使用灰度图,那么ImageUsed就是灰度图的逆透视图,

如果使用二值化图,那么ImageUsed就是二值化的逆透视图

BlackColor的值为没有内容部分的灰度值。

只需要初始化时调用一次ImagePerspective_Init()函数,只需要初始化时调用一次!!!!一次就行!!!!!!!

//
// Created by RUPC on 2022/9/20.
//
#define RESULT_ROW 100//结果图行列
#define RESULT_COL 114
#define         USED_ROW                120  //用于透视图的行列
#define         USED_COL                188
#define PER_IMG     SimBinImage//SimBinImage:用于透视变换的图像
#define ImageUsed   *PerImg_ip//*PerImg_ip定义使用的图像,ImageUsed为用于巡线和识别的图像
typedef unsigned char       uint8_t;                                              // 无符号  8 bits
uint8_t *PerImg_ip[RESULT_ROW][RESULT_COL];

void ImagePerspective_Init(void) {

    static uint8_t BlackColor = 0;
    double change_un_Mat[3][3] = {          //114w*100h
            { -0.01609759704190238, 0.01932561893613478, -2.040617594981866 }, {
                    0.0004352209945470896, -0.000367865364438621,
                    -0.7035606436969671 }, { 1.115951268069474e-005,
                    0.0001970185393508392, -0.03104642853440032 }, };
    for (int i = 0; i < RESULT_COL ;i++) {
        for (int j = 0; j < RESULT_ROW ;j++) {
            int local_x = (int) ((change_un_Mat[0][0] * i
                    + change_un_Mat[0][1] * j + change_un_Mat[0][2])
                    / (change_un_Mat[2][0] * i + change_un_Mat[2][1] * j
                            + change_un_Mat[2][2]));
            int local_y = (int) ((change_un_Mat[1][0] * i
                    + change_un_Mat[1][1] * j + change_un_Mat[1][2])
                    / (change_un_Mat[2][0] * i + change_un_Mat[2][1] * j
                            + change_un_Mat[2][2]));
            if (local_x
                    >= 0&& local_y >= 0 && local_y < USED_ROW && local_x < USED_COL){
                PerImg_ip[j][i] = &PER_IMG[local_y][local_x];
            }
            else {
                PerImg_ip[j][i] = &BlackColor;          //&PER_IMG[0][0];
            }

        }
    }

}


/*完成摄像头初始化后,调用一次ImagePerspective_Init,此后,直接调用ImageUsed   即为透视结果*/

 

屏幕显示透视变换后的灰度图DEMO:
int main(void)
{

    All_Init();//屏幕、摄像头、以及其他外设初始化
    ImagePerspective_Init();
    while(1)
    {
        if (mt9v03x_finish_flag_dvp == 1) {
            uint8_t show[RESULT_ROW][RESULT_COL];
                for(int i=0;i<RESULT_ROW;i++)
                {
                    for(int j=0;j<RESULT_COL;j++)
                    {
                        show[i][j]=ImageUsed[i][j];
                    }
                }
            ips114_show_gray_image(0,0,show[0],RESULT_COL,RESULT_ROW,RESULT_COL,RESULT_ROW,0);
            mt9v03x_finish_flag_dvp = 0;

        }
    }
}

 

效果显示: 

 

​编辑

 

 已知原图坐标情况下求透视后坐标

        如果只想对边线或是某些点进行逆透视,在使用同样矩阵下,可以参考17届智能车-多车编队寻光测距_Wyean的博客-CSDN博客

 

6.资源文件

        其中包含了测试图包

        CSDN:https://download.csdn.net/download/wu58430/86399773

        推荐github:https://github.com/wu58430/RUBO-IPM

        如果只使用用途,下载github中Release即可。

        现在已经完成了逆透视、去畸变、逆透视+去畸变的操作,除非程序有重大bug,后续不会考虑更新。此三种只是图片处理方法,如此软件只适用于简化和降低操作的门槛,以便大家共同进步,图像处理方法无好坏之分,但确实有精妙与粗糙之别。

版权声明:

        此软件仅用于竞赛、学习交流,禁止任何商业用途,包括有营利性的、商业的教学指导活动。

7.更新日志

        2022.8.23        修复了不同版本windows兼容问题

        2022.8.27        修复中文路径、视图大小异常问题,缩小程序体积

        2022.9.23        增加了彩色图像显示,输出格式改为数组

        2022.10.7        代码迁移至QT6.3.1环境,加入去畸变,加入保存图片功能
        2022.10.29        融合两种方法,修复保存图像色彩错误问题

 

 

 

 

 

 

标签:教程,Mat,透视,图像处理,RESULT,图像,un,change
From: https://www.cnblogs.com/RUBO/p/16854047.html

相关文章

  • 智能车图像处理去畸变+逆透视教程
    ​逆透视请参考:智能车逆透视教程(含上位机、源码)_LoseHu的博客-CSDN博客去畸变请参考:智能车去畸变教程(含上位机、源码)_LoseHu的博客-CSDN博客​逆透视+去畸变:如下1......
  • 【适合小白教程】将喜马拉雅下载的xm文件转换为其他音频格式!
    喜马拉雅下载的音频文件格式为XM,想转换为mp3或者其他音频格式。XM加密的目前没有办法 不过可以用IDM在网页直接下载不过就是非常慢点一集一集的下 以前有个软件不......
  • 长期可用【教程】如何把喜马拉雅音频下载到电脑
    这篇文章只适合给技术小白,这是一篇教你如何将喜马拉雅上的音频下载到电脑上转换成MP3格式的教程,付费的要想下载,你得有vip会员。 喜马拉雅有个特点,就算付过费的内容你也......
  • 在CentOS7下安装Oracle11教程
    前言安装oracle时,发现网上的文章总是缺少一些信息,导致安装不顺利,因为我对一些文章进行了整合,用以备忘。Oracle安装首先下载linux版本的oracle安装文件,然后通过XFTP上传......
  • laravel入门教程(二)
    上次说到了子域名路由,这回从命名空间前缀说起命名空间前缀通过使用路由组命名空间前缀,就可以避免在群组内使用很长的控制器进行引用,如API/ControllerA@indexAPI/ControllerB......
  • laravel入门教程(一)
    laravel入门教程(一)本教程是针对laravel5来讲解的####0.1、一个简单的示例//文件:routes/web.php<?phpRoute::get('/','WelcomeController@index');//文件:app/Http/Contro......
  • CAD安装包2023软件中文汉化版安装教程
    1.鼠标右击【CAD2023】压缩包(Win11系统需先点击“显示更多选项”)选择【解压到CAD2023】。2.打开解压后的文件夹,双击打开【CAD2023】文件夹。3.鼠标右击【Setup】选择【管......
  • 超详细部署Kafka教程
    部署Kafka#官方文档http://kafka.apache.org/quickstart1、环境准备#在三个节点提前部署jdk和zookeeper[root@node1~]#java-versionopenjdkversion"1.8.0_342"[root@nod......
  • 记录--UNI-APP安卓本地打包详细教程(保姆级)
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助forin和forof相对于大家肯定都不陌生,都是用来遍历属性的没错。那么先看下面的一个例子:例1const......
  • WordPress零基础建站教程:搭建本地数据库 1/10
    网页作为互联网内容的基本组成,承担了互联网几乎所有的内容展示功能,在我们点击一个链接时,几乎都是将我们转入一个网页显示界面,而我们也是通过这些形式各异的网页,打开了万紫千......