当前位置: 首页 > news >正文

[OpenCV] 数字图像处理 C++ 学习——15像素重映射(cv::remap) 附完整代码

文章目录

  • 前言
  • 1.像素重映射理论基础
  • 2.代码实现
    • (1) remap()细节
    • (2)水平翻转
    • (2)垂直翻转
    • (3)旋转 180 度
    • (4)径向扭曲
  • 3.完整代码

前言

像素重映射将图像中的每个像素映射到新位置,实现图像的扭曲、校正等操作。在 OpenCV 中,cv::remap() 函数就是用于实现这种功能的。本文将详细介绍像素重映射的基本原理以及在 OpenCV 中的实现方法,并给出完整代码。

1.像素重映射理论基础

像素重映射的原理是将图像的每个像素通过预定义的映射规则重新分配到新的位置。映射规则可以是任意的数学函数,比如旋转、缩放、扭曲等,甚至可以通过查表的方式进行非线性的映射。

在这里插入图片描述

像素重映射可以用以下公式表示:
dst ( x ′ , y ′ ) = src ( x , y ) \text{dst}(x', y') = \text{src}(x, y) dst(x,y)=src(x,y)
其中 (x, y) 是源图像中的像素位置,(x', y') 是目标图像中的像素位置。通过映射函数,可以将源图像的像素映射到目标图像的相应位置。

常见的重映射应用

图像扭曲:将图像以某种方式进行扭曲处理,使其变形。

镜头畸变校正:通过重映射可以校正图像中由于镜头引起的畸变,如鱼眼镜头畸变。

图像旋转与缩放:可以将图像按照指定的角度和比例进行旋转与缩放。

2.代码实现

实验用到图像,供学习使用sherlock.jpg

(1) remap()细节

cv::remap(
InputArray src,// 输入图像
OutputArray dst,// 输出图像
InputArray  map1,// x 映射表 CV_32FC1/CV_32FC2
InputArray map2,// y 映射表
int interpolation,// 选择的插值方法,常见线性插值,可选择立方等
int borderMode,// 指定图像边界的处理方式,默认为 BORDER_CONSTANT。
const Scalar borderValue// 用于边界像素的值,默认是黑色。
)

(2)水平翻转

map1 中的列坐标从右向左映射,map2 保持原始的行坐标不变。

for (int i = 0; i < src.rows; i++) {for (int j = 0; j < src.cols; j++) {map1.at<float>(i, j) = static_cast<float>(src.cols - j - 1);  // 水平翻转map2.at<float>(i, j) = static_cast<float>(i);}}Mat dst_hflip;remap(src, dst_hflip, map1, map2, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));namedWindow("Horizontal Flip", WINDOW_AUTOSIZE);imshow("Horizontal Flip", dst_hflip);

结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(2)垂直翻转

map2 中的行坐标从下向上映射,而 map1 保持列坐标不变。

	// 2. 垂直翻转for (int i = 0; i < src.rows; i++) {for (int j = 0; j < src.cols; j++) {map1.at<float>(i, j) = static_cast<float>(j);map2.at<float>(i, j) = static_cast<float>(src.rows - i - 1);  // 垂直翻转}}Mat dst_vflip;remap(src, dst_vflip, map1, map2, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));namedWindow("Vertical Flip", WINDOW_AUTOSIZE);imshow("Vertical Flip", dst_vflip);

结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(3)旋转 180 度

同时进行水平和垂直翻转

	// 3. 旋转 180 度for (int i = 0; i < src.rows; i++) {for (int j = 0; j < src.cols; j++) {map1.at<float>(i, j) = static_cast<float>(src.cols - j - 1);  // 水平翻转map2.at<float>(i, j) = static_cast<float>(src.rows - i - 1);  // 垂直翻转}}Mat dst_rotate180;remap(src, dst_rotate180, map1, map2, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));namedWindow("Rotate 180 degrees", WINDOW_AUTOSIZE);imshow("Rotate 180 degrees", dst_rotate180);

结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(4)径向扭曲

通过对极坐标中的半径进行二次变换,产生径向扭曲效果,图像向中心点扭曲,产生类似鱼眼镜头的效果。

	// 4. 径向扭曲效果float cx = src.cols / 2.0;float cy = src.rows / 2.0;float radius = min(cx, cy);for (int i = 0; i < src.rows; i++) {for (int j = 0; j < src.cols; j++) {float dx = j - cx;float dy = i - cy;float r = sqrt(dx * dx + dy * dy);float theta = atan2(dy, dx);float r_distorted = radius * (r / radius) * (r / radius);  // 径向扭曲map1.at<float>(i, j) = cx + r_distorted * cos(theta);map2.at<float>(i, j) = cy + r_distorted * sin(theta);}}Mat dst_radial;remap(src, dst_radial, map1, map2, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));namedWindow("Radial Distortion", WINDOW_AUTOSIZE);imshow("Radial Distortion", dst_radial);

结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.完整代码

#include<opencv2/opencv.hpp>
#include<highgui.hpp>
#include<iostream>
#include<math.h>using namespace cv;
using namespace std;void remap_image()
{cv::Mat src;src = imread("sherlock.jpg");if (src.empty()) {printf("could not find the image...\n");return;}namedWindow("Source Image", WINDOW_AUTOSIZE);imshow("Source Image", src);//创建映射矩阵Mat map1(src.size(), CV_32FC1);Mat map2(src.size(), CV_32FC1);// 1. 水平翻转for (int i = 0; i < src.rows; i++) {for (int j = 0; j < src.cols; j++) {map1.at<float>(i, j) = static_cast<float>(src.cols - j - 1);  // 水平翻转map2.at<float>(i, j) = static_cast<float>(i);}}Mat dst_hflip;remap(src, dst_hflip, map1, map2, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));namedWindow("Horizontal Flip", WINDOW_AUTOSIZE);imshow("Horizontal Flip", dst_hflip);// 2. 垂直翻转for (int i = 0; i < src.rows; i++) {for (int j = 0; j < src.cols; j++) {map1.at<float>(i, j) = static_cast<float>(j);map2.at<float>(i, j) = static_cast<float>(src.rows - i - 1);  // 垂直翻转}}Mat dst_vflip;remap(src, dst_vflip, map1, map2, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));namedWindow("Vertical Flip", WINDOW_AUTOSIZE);imshow("Vertical Flip", dst_vflip);// 3. 旋转 180 度for (int i = 0; i < src.rows; i++) {for (int j = 0; j < src.cols; j++) {map1.at<float>(i, j) = static_cast<float>(src.cols - j - 1);  // 水平翻转map2.at<float>(i, j) = static_cast<float>(src.rows - i - 1);  // 垂直翻转}}Mat dst_rotate180;remap(src, dst_rotate180, map1, map2, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));namedWindow("Rotate 180 degrees", WINDOW_AUTOSIZE);imshow("Rotate 180 degrees", dst_rotate180);// 4. 径向扭曲效果float cx = src.cols / 2.0;float cy = src.rows / 2.0;float radius = min(cx, cy);for (int i = 0; i < src.rows; i++) {for (int j = 0; j < src.cols; j++) {float dx = j - cx;float dy = i - cy;float r = sqrt(dx * dx + dy * dy);float theta = atan2(dy, dx);float r_distorted = radius * (r / radius) * (r / radius);  // 径向扭曲map1.at<float>(i, j) = cx + r_distorted * cos(theta);map2.at<float>(i, j) = cy + r_distorted * sin(theta);}}Mat dst_radial;remap(src, dst_radial, map1, map2, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));namedWindow("Radial Distortion", WINDOW_AUTOSIZE);imshow("Radial Distortion", dst_radial);waitKey(0);
}
int main() 
{remap_image();return 0;
}

相关文章:

[OpenCV] 数字图像处理 C++ 学习——15像素重映射(cv::remap) 附完整代码

文章目录 前言1.像素重映射理论基础2.代码实现(1) remap()细节(2)水平翻转(2)垂直翻转(3)旋转 180 度(4)径向扭曲 3.完整代码 前言 像素重映射将图像中的每个像素映射到新位置&#xff0c;实现图像的扭曲、校正等操作。在 OpenCV 中&#xff0c;cv::remap() 函数就是用于实现这…...

Oreace每日运维操作

一&#xff0e;Oreace每日运维操作 目录 一&#xff0e;Oreace每日运维操作 1.1、确认所有的INSTANCE状态正常 1.2、检查文件系统的使用&#xff08;剩余空间&#xff09; 1.3 lwh暗码&#xff0c;&#xff0c;、检查日志文件和trace文件记录 1.4 lwh、检查数据库当日备份…...

【XR】AR HUD

1. AR HUD&#xff08;head up display&#xff09;原理 目标&#xff1a; 产业链上的各大Tier1及PGU企业都在积极开发这一技术&#xff0c;许多厂家已推出LCOS样机&#xff0c;比如说水晶光电、华阳集团、瀚思通、疆程已在北京车展或去年的上海车展上展出了LCOS方案的AR-HUD样…...

C/C++内存管理——内存泄漏/内存碎片

一、什么是内存泄漏 内存泄漏指的是在程序运行过程中,已经分配给程序使用的内存没有得到及时和正确的释放,导致这部分内存无法被程序再次使用或者被操作系统回收。内存泄漏通常发生在动态分配的内存上,如果这部分内存没有被正确释放,随着时间的推移,越来越多的内存将被占…...

使用 GaLore 预训练LLaMA-7B

项目代码&#xff1a; https://github.com/jiaweizzhao/galorehttps://github.com/jiaweizzhao/galore 参考博客&#xff1a; https://zhuanlan.zhihu.com/p/686686751 创建环境 基础环境配置如下&#xff1a; 操作系统: CentOS 7CPUs: 单个节点具有 1TB 内存的 Intel CP…...

gitlab无法push(pre-receive hook declined)

如果是个人的项目&#xff0c;托管在官网&#xff0c;可以参考这位大佬的&#xff0c; GitLab新建项目后push reject提交失败的解决办法_push rejected-CSDN博客 如果是公司的项目&#xff0c;去项目成员里看自己的身份&#xff0c;如果只是developer&#xff0c;是无法push到…...

物品识别——基于python语言

目录 1.物品识别 2.模型介绍 3.文件框架 4.代码示例 4.1 camera.py 4.2 interaction.py 4.3 object_detection.py 4.4 main.py 4.5 运行结果 5.总结 1.物品识别 该项目使用Python&#xff0c;OpenCV进行图像捕捉&#xff0c;进行物品识别。我们将使用YOLO&#xff08…...

【PostgreSQL】安装及使用(Navicat/Arcgis),连接(C#)

简介 PostgreSQL 是一个功能强大的开源对象关系数据库系统 下载地址 PostgreSQL: Downloads 由于我电脑上安装的是arcgispro3.1所以需要下载对应的postgresql版本 PostgreSQL 12 对应的 PostGIS 版本主要是 3.5.0 或更高版本。 安装 一般设置为postgresql 安装扩展插件 此…...

第L6周:机器学习-随机森林(RF)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 目标&#xff1a; 1.什么是随机森林&#xff08;RF&#xff09; 随机森林&#xff08;Random Forest, RF&#xff09;是一种由 决策树 构成的 集成算法 &#…...

【电路笔记】-差分运算放大器

差分运算放大器 文章目录 差分运算放大器1、概述2、差分运算放大器表示2.1 差分模式2.2 减法器模式3、差分放大器示例3.1 相关电阻3.2 惠斯通桥3.3 光/温度检测4、仪表放大器5、总结1、概述 在之前的文章中,我们讨论了反相运算放大器和同相运算放大器,我们考虑了在运算放大器…...

git 命令---想要更改远程仓库

在 Git 中&#xff0c;origin 是默认的远程仓库名称。可以使用以下命令查看当前 Git 仓库的 origin 名称及其对应的 URL&#xff1a; git remote -v这个命令会列出所有配置的远程仓库及其名称&#xff0c;其中 origin 通常是克隆时自动设置的默认远程仓库名称。输出示例&#…...

LeetCode:2848. 与车的相交点 一次遍历,时间复杂度O(n)

2848. 与车的相交点 today 2848. 与车的相交点 题目描述 给你一个下标从 0开始的二维整数数组 nums 表示汽车停放在数轴上的坐标。对于任意下标 i &#xff0c;nums[i] [starti, endi] &#xff0c;其中 s t a r t i start_i starti​ 是第 i 辆车的起点&#xff0c; e n …...

Xcode 16 RC (16A242) 发布下载,正式版下周公布

Xcode 16 RC (16A242) - Apple 平台 IDE IDE for iOS/iPadOS/macOS/watchOS/tvOS/visonOS 请访问原文链接&#xff1a;https://sysin.org/blog/apple-xcode-16/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Xcode 16 的新功…...

git 更换远程地址的方法

需要将正在开发的代码远程地址改成新的地址&#xff0c;通过查询发现有三个方法可以实现&#xff0c;特此记录。具体方法如下&#xff1a; &#xff08;1&#xff09;通过命令直接修改远程仓库地址 git remote 查看所有远程仓库git remote xxx 查看指定远程仓库地址git remote…...

9. 什么是 Beam Search?深入理解模型生成策略

是不是总感觉很熟悉&#xff1f; 在之前第5&#xff0c;7&#xff0c;8篇文章中&#xff0c;我们都曾经用到过与它相关的参数&#xff0c;而对于早就有着实操经验的同学们&#xff0c;想必见到的更多。这篇文章将从示例到数学原理和代码带你进行理解。 Beam Search 对应的中文翻…...

Spring自定义注解

目录 一、interface 关键字 二、元注解 三、简单实现 四、使用切面执行自定义注解逻辑 1) 首先将刚才的注解修改成放在方法上的&#xff1a; 2) 定义一个切面类&#xff1a; 3&#xff09;将注解放入到接口方法中测试&#xff1a; 五、切点表达式 一、interface 关键字 …...

微信小程序:wx.login或调用uni.login时报错the code is a mock one

微信小程序&#xff0c;调用wx.login或调用uni.login方法&#xff0c;返回the code is a mock one 原因与解决 原因:没有关联真实的 appid&#xff0c;解决办法&#xff1a;绑定真实的微信小程序的appid...

URL的执行流程

基本概念&#xff1a; URL&#xff08;统一资源定位符&#xff0c;Uniform Resource Locator&#xff09;的执行流程是指当你在浏览器中输入一个URL并按下回车键时&#xff0c;从输入URL到最终在浏览器中显示网页的完整过程。 1.解析协议 URL 以协议开头&#xff0c;如 http…...

双指针算法专题(2)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; 优选算法专题 想要了解双指针算法的介绍&#xff0c;可以去看下面的博客&#xff1a;双指针算法的介绍 目录 611.有效三角形的个数 LCR 1…...

加密与安全_优雅存储用户密码的最佳实践

文章目录 Pre概述最佳实践避免使用MD5、SHA1等快速哈希算法加盐哈希 &#xff08;不推荐&#xff09;使用BCrypt、Argon2等慢哈希算法 (推荐)BCrypt Code1. 自动生成和嵌入盐2. 哈希结果的格式3. 代价因子 BCrypt特点 防止暴力破解1. 登录失败锁定2. 双因素认证&#xff08;2FA…...

RT-DETR Decoder里的‘去噪’与‘软标签’:加速训练收敛的实战技巧

RT-DETR Decoder里的‘去噪’与‘软标签’&#xff1a;加速训练收敛的实战技巧 在目标检测领域&#xff0c;RT-DETR凭借其出色的实时性能和检测精度&#xff0c;正逐渐成为工业界和学术界的热门选择。然而&#xff0c;许多实践者在模型训练过程中常常遇到收敛速度慢、训练不稳定…...

PINN在流体力学中的应用:Burger方程参数反演全流程解析

PINN在流体力学中的革命性实践&#xff1a;Burger方程参数反演深度指南 当计算流体力学遇上深度学习&#xff0c;一场静悄悄的革命正在发生。传统数值方法在求解复杂流体问题时往往面临计算成本高、适应性差的瓶颈&#xff0c;而物理信息神经网络&#xff08;PINN&#xff09;的…...

学习笔记:敢管,会管,善管——学校行政管理的进阶

管理者角色理解一、管理者在组织结构中的位置校级&#xff1a;领导者管理者中层干部&#xff1a;管理者执行者学校教师&#xff1a;执行者&#xff08;班主任对班级兼顾三者&#xff09;二、从普通教师到中层干部的转变&#xff1a;1.工作职责的变化:从运动员向教练员转变运动员…...

如何高效构建雷达系统:Python雷达模拟的完整实战指南

如何高效构建雷达系统&#xff1a;Python雷达模拟的完整实战指南 【免费下载链接】radarsimpy Radar Simulator built with Python and C 项目地址: https://gitcode.com/gh_mirrors/ra/radarsimpy RadarSimPy是一个基于Python和C构建的开源雷达模拟器&#xff0c;为雷达…...

免费音频编辑终极指南:Audacity 4 让专业音频处理触手可及

免费音频编辑终极指南&#xff1a;Audacity 4 让专业音频处理触手可及 【免费下载链接】audacity Audio Editor 项目地址: https://gitcode.com/GitHub_Trending/au/audacity 你是否曾经想要编辑音频却苦于没有合适的工具&#xff1f;或者被昂贵复杂的专业软件吓退&…...

基于单片机的自行车里程表设计|附源码

基于单片机的自行车里程表设计 源码&#xff1a;点击下载源码 项目简介 这是一个基于51单片机的自行车里程表设计项目&#xff0c;能够实时显示自行车的行驶速度、累计里程&#xff0c;并提供时间显示、超速报警等功能。该项目适合作为单片机课程设计的学习案例&#xff0c;…...

3个核心方案:用UNTRUNC工具修复损坏视频的专业指南

3个核心方案&#xff1a;用UNTRUNC工具修复损坏视频的专业指南 【免费下载链接】untrunc Restore a damaged (truncated) mp4, m4v, mov, 3gp video. Provided you have a similar not broken video. 项目地址: https://gitcode.com/gh_mirrors/unt/untrunc 价值定位&am…...

NeuroKit2:Python神经生理信号处理的全流程解决方案

NeuroKit2&#xff1a;Python神经生理信号处理的全流程解决方案 【免费下载链接】NeuroKit NeuroKit2: The Python Toolbox for Neurophysiological Signal Processing 项目地址: https://gitcode.com/gh_mirrors/ne/NeuroKit 神经生理信号处理是连接生理数据与临床洞察…...

C++ 模板参数推导机制剖析

C 模板参数推导机制剖析 C的模板参数推导是泛型编程的核心机制之一&#xff0c;它允许编译器在调用模板函数或类时自动推断类型参数&#xff0c;从而减少冗余代码并提升开发效率。理解这一机制不仅能帮助开发者编写更灵活的代码&#xff0c;还能避免因类型推导错误导致的编译问…...

开源麻将AI分析工具:3步颠覆传统牌局决策模式

开源麻将AI分析工具&#xff1a;3步颠覆传统牌局决策模式 【免费下载链接】Akagi 支持雀魂、天鳳、麻雀一番街、天月麻將&#xff0c;能夠使用自定義的AI模型實時分析對局並給出建議&#xff0c;內建Mortal AI作為示例。 Supports Majsoul, Tenhou, Riichi City, Amatsuki, wit…...