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

智能车图像处理去畸变+逆透视教程

时间:2022-11-03 12:14:43浏览次数:71  
标签:教程 int 透视 畸变 图像处理 double local change

逆透视请参考:智能车逆透视教程(含上位机、源码)_LoseHu的博客-CSDN博客

去畸变请参考:智能车去畸变教程(含上位机、源码)_LoseHu的博客-CSDN博客


逆透视+去畸变:如下

1.简介

        在前两个博文中已经分别说明了单独去畸变、逆透视的方法。为了同时实现畸变+逆透视,利用之前博文的教程分两步求取矩阵,进行变换。原图以及效果图:

​编辑​编辑

 正如逆透视以及去畸变那样,这种综合的方法自然是保留了两者的特点,例如可以去除图像的畸变,仍然可以利用透视更改图片缩放、图片大小、视野大小。。。。

2.优点

        兼具了去畸变与逆透视的优点

3.原理

        参考去畸变与逆透视的原理

4.通过上位机求取变换参数

        通过上位机分两步完成,具体每一步请参考:

        1.逆透视:智能车逆透视教程(含上位机、源码)_LoseHu的博客-CSDN博客

        2.去畸变:智能车去畸变教程(含上位机、源码)_LoseHu的博客-CSDN博客


去畸变+逆透视演示:https://live.csdn.net/v/249396

        如视频中的那样,每一步都需要将剪切板中的参数保存下来,如

double cameraMatrix[3][3]={{296.482019,0.000000,152.664982},{0.000000,286.375269,104.540031},{0.000000,0.000000,1.000000}};
double distCoeffs[5]={-0.459946,0.283675,0.002304,0.002566,-0.109265};
int move_xy[2]={55,32};
double change_un_Mat[3][3] ={{-1.762057,1.446330,-48.051135},{0.111681,0.215732,-90.406315},{0.000404,0.006296,-1.003619}};

注意事项:

        1.每一步注意事项参考对应的博客

        2.记得保存去畸变后用于逆透视的图片与两步的参数

5.在智能车上完成去畸变+逆透视

        使用时,只需在图像初始化中调用一次ImageChange_Init()函数即可,如去畸变与逆透视一样,这个初始化函数在整个程序中应该只被调用一次。后续使用ImageUsed获取图像像素值。

        记得替换其中的参数

代码如下:

//
// Created by RUPC on 2022/10/29.
//
#define RESULT_ROW 100 //结果图的行列
#define RESULT_COL 114
#define         USED_ROW                120  //用于变换图的行列
#define         USED_COL                188
typedef unsigned char uint8_t;                                              // 无符号  8 bits
uint8_t *PerImg_ip[RESULT_ROW][RESULT_COL];
#define PER_IMG     mt9v03x_image_dvp//mt9v03x_image_dvp:用于透视变换的图像 也可以使用二值化图
#define ImageUsed   *PerImg_ip//*PerImg_ip定义使用的图像,ImageUsed为用于巡线和识别的图像
static uint8_t BlackColor = 255;	//无内容部分像素值
/******************变换参数******************************/
//去畸变参数
double cameraMatrix[3][3] = {{296.482019, 0.000000,   152.664982},
                             {0.000000,   286.375269, 104.540031},
                             {0.000000,   0.000000,   1.000000}};
double distCoeffs[5] = {-0.459946, 0.283675, 0.002304, 0.002566, -0.109265};
int move_xy[2] = {10, 0};
//逆透视参数
double change_un_Mat[3][3] = {{2.936703,  0.314530, -60.814898},
                              {-0.263326, 2.308885, -108.340381},
                              {-0.000835, 0.000896, 0.969316}};
/*******************************************************/
void find_xy(int x, int y, int local[2]) {
    double fx = cameraMatrix[0][0]
    , fy = cameraMatrix[1][1]
    , ux = cameraMatrix[0][2]
    , uy = cameraMatrix[1][2]
    , k1 = distCoeffs[0]
    , k2 = distCoeffs[1]
    , k3 = distCoeffs[4]
    , p1 = distCoeffs[2]
    , p2 = distCoeffs[3];
    double xCorrected = (x - ux) / fx;
    double yCorrected = (y - uy) / fy;
    double xDistortion, yDistortion;
    double r2 = xCorrected * xCorrected + yCorrected * yCorrected;
    double deltaRa = 1. + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2;
    double deltaRb = 1 / (1.);
    double deltaTx = 2. * p1 * xCorrected * yCorrected + p2 * (r2 + 2. * xCorrected * xCorrected);
    double deltaTy = p1 * (r2 + 2. * yCorrected * yCorrected) + 2. * p2 * xCorrected * yCorrected;
    xDistortion = xCorrected * deltaRa * deltaRb + deltaTx;
    yDistortion = yCorrected * deltaRa * deltaRb + deltaTy;
    xDistortion = xDistortion * fx + ux;
    yDistortion = yDistortion * fy + uy;
    if (yDistortion >= 0 && yDistortion < USED_ROW && xDistortion >= 0 && xDistortion < USED_COL) {
        local[0] = (int) yDistortion;
        local[1] = (int) xDistortion;
    } else {
        local[0] = -1;
        local[1] = -1;
    }
}

void find_xy1(int x, int y, int local[2]) {
    int local_x = (int) ((change_un_Mat[0][0] * x
                          + change_un_Mat[0][1] * y + change_un_Mat[0][2])
                         / (change_un_Mat[2][0] * x + change_un_Mat[2][1] * y
                            + change_un_Mat[2][2]));
    int local_y = (int) ((change_un_Mat[1][0] * x
                          + change_un_Mat[1][1] * y + change_un_Mat[1][2])
                         / (change_un_Mat[2][0] * x + change_un_Mat[2][1] * y
                            + change_un_Mat[2][2]));
    if (local_x
        >= 0 && local_y >= 0) {
        local[0] = local_y;
        local[1] = local_x;
    } else {
        local[0] = -1;
        local[1] = -1;
    }
}

void ImageChange_Init() {
    for (int i = 0; i < RESULT_ROW; i++) {
        for (int j = 0; j < RESULT_COL; j++) {
            int local_xy[2] = {-1};
            find_xy1(j, i, local_xy);
            if (local_xy[0] != -1 && local_xy[0] != -1) {
                int local_xy1[2] = {-1};
                find_xy(local_xy[1] - move_xy[0], local_xy[0] - move_xy[1], local_xy1);
                if (local_xy1[0] != -1 && local_xy1[1] != -1) {
                    PerImg_ip[i][j] = &mt9v03x_image_dvp[local_xy1[0]][local_xy1[1]];
                } else PerImg_ip[i][j] = &BlackColor;
            } else PerImg_ip[i][j] = &BlackColor;
        }
    }
}
/*ImageUsed[0][0]代表图像左上角的值*/

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

 

  屏幕显示去畸变+逆透视后的灰度图DEMO:

int main(void)
{
 
    All_Init();//屏幕、摄像头、以及其他外设初始化
    ImageChange_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;
 
        }
    }
}

 

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        融合两种方法,修复保存图像色彩错误问题

 

 

 

标签:教程,int,透视,畸变,图像处理,double,local,change
From: https://www.cnblogs.com/RUBO/p/16854009.html

相关文章

  • 【适合小白教程】将喜马拉雅下载的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
    网页作为互联网内容的基本组成,承担了互联网几乎所有的内容展示功能,在我们点击一个链接时,几乎都是将我们转入一个网页显示界面,而我们也是通过这些形式各异的网页,打开了万紫千......
  • WordPress零基础建站教程:内网穿透将本地web站点发布到公网 5/10
    在前面的文章中,我们已经向大家介绍了如何搭建一个属于自己的网页,虽然这个网页还没有添加内容,但确实已经有了网页的基本框架,等着我们用创意和需求去填满它。为了我们的网页能......