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

news2024/12/23 7:54:09

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

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

逆透视+去畸变:如下

1.简介

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

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

2.优点

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

3.原理

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

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

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

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

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

去畸变+逆透视演示

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2479.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

web前端进阶之一些动画

1.字体图标的基本使用 首先下载iconfont文件夹&#xff0c;用link标签引入&#xff0c;使用如下&#xff1a; <i class"iconfont icon-favorites-fill green"></i> //改样式的话使用iconfont或者使用 .green(自己设置的类名) .iconfont {font-size: 60…

React.memo 和 useMemo 的使用

文章の目录问题背景useMemo 进行优化React.memo 进行优化props的值是基本类型props的值是引用类型写在最后问题背景 大家在使用 React 框架进行开发时一定遇到过以下问题&#xff1a; 当函数式组件中的某一状态改变&#xff0c;整个组件刷新&#xff0c;重新渲染在类组件中 s…

解决虚拟机下 “Linux和Windows之间复制粘贴” 的问题

大家在安装完虚拟机后&#xff0c;其实很多东西都还是要跟Windows打交道的&#xff0c;比如像Linux下某个软件的环境配置&#xff0c;你在Linux下遇到种种问题&#xff0c;这时你已习惯回到Windows下&#xff0c;默默的打开了“一亿名程序员都在用的CSDN平台”&#xff0c;找到…

腾讯疯狂招人,肝完自动化测试这关,20k+妥了

前言 对于程序员来说&#xff0c;BAT 为首的一线互联网公司肯定是自己的心仪对象&#xff0c;毕竟能到这些大厂工作&#xff0c;不仅薪资高待遇好&#xff0c;而且能力技术都能够得到提升&#xff0c;最关键的是还能够给自己镀上一层金&#xff0c;让人瞻仰。 最近很多同行群…

测试开发工程师到底是做什么的?

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

本地电脑搭建SFTP服务器,并实现公网访问

1. 搭建SFTP服务器 1.1 下载 freesshd 服务器软件 下载地址&#xff1a;freeSSHd and freeFTPd image_1gbuejept12741719ta61ubn8ej9.png-63.1kB 选择freeFTPD.exe下载 下载后&#xff0c;点击安装 image_1gbueks891c258ee2o315kmf9m.png-57.7kB 安装之后&#xff0c;它会提…

Reactor反应器模式

单线程Reactor反应器模式 在事件驱动模式中&#xff0c;当有事件触发时&#xff0c;事件源会将事件dispatch分发到handler处理器进行事件处理。反应器模式中的反应器角色&#xff0c;类似于事件驱动模式中的dispatcher事件分发器角色。 在反应器模式中&#xff0c;有Reactor反…

企业进行高质量数据管理,实施数据治理的关键是什么?

随着数据通过各种方式创造了巨大价值&#xff0c;各领域的企业开始不断挖掘数据的作用&#xff0c;数据的重要性得到了社会各界的共同认可。像我们熟知的数据治理、数据管理、数据标准以及数据资产都是因为数据地位不断提升&#xff0c;企业开始重视起数据全生命周期流程&#…

SpringBoot笔记(一)核心内容

官网&#xff1a;https://spring.io/projects/spring-boot Spring Boot可以轻松创建独立的、基于Spring的生产级应用程序&#xff0c;它可以让你“运行即可”。大多数Spring Boot应用程序只需要少量的Spring配置。 SpringBoot功能&#xff1a; 创建独立的Spring应用程序直接嵌…

2022.11.1 固体物理

Drude Model 原子由原子核和核外电子组成 我们首先看一下不同材料的自由电子密度 知道原子数目基本就知道了核外电子的数目 如果是单位体积内的&#xff0c;知道密度&#xff0c;我们就可以知道质量&#xff0c;根据摩尔质量和阿伏伽德罗常数&#xff0c;我们就可以知道原子…

网络层——IP协议

网络层 网络层概述 网络层主要考虑数据传输的路上问题&#xff0c;在复杂的网络环境中确定一个合适的路径。 网络层设计要尽量简单&#xff0c;向上层只提供简单灵活的、无连接的、不保证可靠性的数据报服务。网络层不提供服务质量的承诺&#xff01; IP 数据报的格式 如何分…

计算机网络---第四章网络层---ipv4---选择题

9# 1IPV4在第一个4B&#xff0c;5678位。当它为0101时&#xff0c;表示首部长度为5420B&#xff0c;这也是最常见的。当它为1111时&#xff0c;表示首部长度为15460B&#xff0c;此时加上了可选字段40B 2协议字段在第三个4B的9到16位&#xff0c;表示IP的上层协议&#xff0c;…

聚观早报 | 吉利汽车拟将极氪独立上市;比亚迪斥资近50亿元造船

今日要闻&#xff1a;吉利汽车拟将极氪独立上市&#xff1b;比亚迪斥资近50亿元造船&#xff1b;华硕开设首个AI智能工厂&#xff1b;升级款Mac将于明年3月推出&#xff1b;世界互联网大会将于11月9日举行吉利汽车拟将极氪独立上市 10 月 31 日消息&#xff0c;吉利汽车午间在港…

个人设计web前端大作业——HTML+CSS华为官网首页

常见网页设计作业题材有 个人、 美食、 公司、 学校、 旅游、 电商、 宠物、 电器、 茶叶、 家居、 酒店、 舞蹈、 动漫、 服装、 体育、 化妆品、 物流、 环保、 书籍、 婚纱、 游戏、 节日、 戒烟、 电影、 摄影、 文化、 家乡、 鲜花、 礼品、 汽车、 其他等网页设计题目, A…

【Java 数据结构】顺序表

篮球哥温馨提示&#xff1a;编程的同时不要忘记锻炼哦&#xff01;我们不过是普通人&#xff0c;只不过在彼此眼中闪闪发光 目录 1、什么是顺序表&#xff1f; 2、模拟实现ArrayList 2.1 模拟实现前的约定 2.2 构造方法 2.3 add方法 2.4 contains 方法 2.5 indexOf 方法…

Python量化初学者入门必备,如何入门Python量化交易?

前言 量化可以简单分为数据管理、策略分析和策略执行三个模块&#xff0c;数据是基础&#xff0c;策略分析是核心&#xff0c;其中策略自动化执行&#xff08;算法交易&#xff09;在国内由于政策限制实施起来比较麻烦。&#xff08;文末送福利&#xff09; 从Python的角度看…

Centos8.2编译安装Nginx

一、介绍 1、Nginx 简介 Nginx 是一个高性能的 HTTP 和反向代理 WEB 服务器&#xff0c;除它之外 Apache、Tomcat、Jetty、IIS&#xff0c;它们都是 WEB 服务器&#xff0c;或者叫做 WWW &#xff08;World Wide Web&#xff09;服务器&#xff0c;相应的也都具备 WEB 服务器的…

服务器的管理IIS 6.0

IIS 6.0 和 Windows Server 2003在网络应用服务器的管理、可用性、可靠性、安全性、性能与可扩展性方面提供了许多新的功能。IIS 6.0同样增强了网络应用的开发与国际性支持。IIS 6.0和 Windows Server 2003提供了最可靠的、高效的、连接的、完整的网络服务器解决方案。 中文名I…

Node.js | MongoDB 入门讲解 Mongoose 模块的初步应用

&#x1f5a5;️ NodeJS专栏&#xff1a;Node.js从入门到精通 &#x1f5a5;️ 博主的前端之路&#xff08;源创征文一等奖作品&#xff09;&#xff1a;前端之行&#xff0c;任重道远&#xff08;来自大三学长的万字自述&#xff09; &#x1f5a5;️ TypeScript知识总结&…

【测试沉思录】10. 我们用到的3种Mock测试方案

欢迎订阅我的新专栏《现代命令行工具指南》&#xff0c;精讲目前最流行的开源命令行工具&#xff0c;大大提升你的工作效率。 作者&#xff1a;王媛媛 编辑&#xff1a;毕小烦 Mock 这个词对于测试人员来说并不陌生&#xff0c;当我们要测试的接口 A 依赖接口 B &#xff0c;可…