【OpenCV图像处理】1.22 像素值映射

2023-11-03

相关理论

  • 什么是像素重映射

    • 简单点说就是把输入图像中各个像素按照一定的规则映射到另外一张图像的对应位置上去,形成一张新的图像
    • g ( x , y ) = f ( h ( x , y ) ) g(x, y)=f(h(x, y)) g(x,y)=f(h(x,y)) 这里 g ( x , y ) g(x,y) g(x,y)是目标图像, h ( x , y ) h(x,y) h(x,y)是功能函数, f f f是源图像。映射效果如下:
    • 在这里插入图片描述
    • 假设有映射函数 h ( z , y ) = ( I . c o l s − x , y ) h(z, y)=(I.{cols}-x, y) h(z,y)=(I.colsx,y),图像会按照x轴方向发生反转,如下:
      在这里插入图片描述 在这里插入图片描述
      上图中,红色圈关于x的位置改变。
  • API介绍 – cv::remap

    remap(
    InputArray src,// 输入图像
    OutputArray dst,// 输出图像
    InputArray  map1,// x 映射表 CV_32FC1/CV_32FC2
    InputArray map2,// y 映射表
    int interpolation,// 选择的插值方法,常见线性插值,可选择立方等
    int borderMode,// BORDER_CONSTANT
    const Scalar borderValue// color 
    )
    
    • 参数解释:
      • 第三个参数map1:InputArray类型的map1,它有两种可能的表示对象:表示点(x,y)的第一个映射。表示CV_16SC2 , CV_32FC1 或CV_32FC2类型的X值。
      • 第四个参数map2:InputArray类型的map2,同样,它也有两种可能的表示对象,而且他是根据map1来确定表示那种对象。若map1表示点(x,y)时。这个参数不代表任何值。表示CV_16UC1 , CV_32FC1类型的Y值(第二个值)。
      • 第五个参数interpolation:int类型的interpolation,插值方式,之前的resize( )函数中有讲到,需要注意,resize( )函数中提到的INTER_AREA插值方式在这里是不支持的,所以可选的插值方式如下:
        在这里插入图片描述
      • 第六个参数borderMode:int类型的borderMode,边界模式,有默认值BORDER_CONSTANT,表示目标图像中“离群点(outliers)”的像素值不会被此函数修改。取值可以是如下几种:
      • 在这里插入图片描述
      • 第七个参数borderValue:const Scalar&类型的borderValue,当有常数边界时使用的值,其有默认值Scalar( ),即默认值为0。

代码 & 运行效果

完整代码:

#include <iostream>
#include <string>
#include <vector>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/types_c.h>

using namespace std;
using namespace cv;

#ifndef P22
#define P22 22
#endif

#if P22 //像素映射
int t1_value = 50;
int max_value = 255;
const char* OUTPUT_TITLE = "Canny result";
Mat  src,dest, map_x, map_y;
int indexx = 0;

void update_map()
{
    for(int row=0; row < src.rows; row++)
    {
        for( int col=0; col < src.cols; col++)
        {
            switch(indexx)
            {
                //原图长宽各缩小一半,即原图的1/4
                case 0:
                    if(col > src.cols*0.25 && col < src.cols*0.75&&
                       row > src.rows*0.25 && row < src.rows*0.75)
                    {
                        map_x.at<float>(row, col) = 2*(col - src.cols*0.25) + 0.5;
                        map_y.at<float>(row, col) = 2*(row - src.rows*0.25) + 0.5;
                    } else {
                        map_x.at<float>(row, col) = 0;
                        map_y.at<float>(row, col) = 0;
                    }
                    break;

                //图像左右翻转,类似于照镜子
                case 1:
                    map_x.at<float>(row, col) = (src.cols-col-1);
                    map_y.at<float>(row, col) = row;
                    break;

                //图像上下翻转
                case 2:
                    map_x.at<float>(row, col) = col;
                    map_y.at<float>(row, col) = (src.rows-row-1);
                    break;

                //图像上下左右都翻转
                case 3:
                    map_x.at<float>(row, col) = (src.cols-col-1);
                    map_y.at<float>(row, col) = (src.rows-row-1);
                    break;
            }
        }
    }
}
#endif

int main() {
    std::string path = "../color_line.JPG";
    cv::Mat img = cv::imread(path, 5);

    string str_input = "input image";
    string str_output = "output image";

    if(img.empty())
    {
        std::cout << "open file failed" << std::endl;
        return -1;
    }
    
#if P22 //像素值映射
    map_x.create(img.size(), CV_32FC1);
    map_y.create(img.size(), CV_32FC1);

    src = img;

    int c = 0;
    while(true)
    {
        c = waitKey(500);
        indexx = c % 4;
        if((char)c == 27)  break;

        update_map();
        remap(src, dest, map_x, map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0,255));
        imshow(str_output, dest);
    }
#endif

    cv::waitKey(0);
    cv::destroyAllWindows();
    return 0;
}

效果展示:

  • 图像缩小
    在这里插入图片描述
  • 左右翻转
    在这里插入图片描述
  • 上下翻转
    在这里插入图片描述
  • 上下左右都翻转
    在这里插入图片描述
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【OpenCV图像处理】1.22 像素值映射 的相关文章

  • c++拷贝构造函数(深拷贝,浅拷贝)详解

    一 什么是拷贝构造函数 首先对于普通类型的对象来说 它们之间的复制是很简单的 例如 int a 100 int b a 而类对象与普通对象不同 类对象内部结构一般较为复杂 存在各种成员变量 下面看一个类对象拷贝的简单例子 include
  • 引入wangeditor 报错 error in ./node_modules/@wangeditor/editor/dist/index.esm.js

    ERROR Failed to compile with 1 errors 17 53 12 error in node modules wangeditor editor dist index esm js Module parse fa
  • Mac升级之后已破解的intellij idea无法启动

    打开终端 进入 gt gt gt Users ethan Library Application Support JetBrains IntelliJIdea 对应版本 gt gt gt vim idea vmoptions 删除之前配置的
  • Struts2反序列化漏洞复现

    环境 vulhub 环境搭建 进入s2 048目录 切换root用户 启动漏洞环境 docker compose up d 漏洞复现 浏览器访问 showcase Gangster Name输入 233 233 其余随便填 将Gangste
  • Linux服务器遭受黑客攻击时的日志分析排除

    0x00 前言 Linux系统拥有非常灵活和强大的日志功能 可以保存几乎所有的操作记录 并可以从中检索出我们需要的信息 本文简介一下Linux系统日志及日志分析技巧 0x01 日志简介 日志默认存放位置 var log 查看日志配置情况 m
  • Postman 如何进行参数化

    前言 Postman作为一款接口测试工具 受到了非常多的开发工程师的拥护 那么做为测试 了解Postman这款工具就成了必要的了 这篇文章就是为了解决Postman怎么进行参数化的 全局变量 全局变量是将这个变量设置成整个程序的都可以用 不
  • SSH客户端工具——PuTTY(1)

    引言 本文介绍了SSH客户端工具PuTTY的下载和在Windows下的安装方法 怎么使用PuTTYgen生成SSH密钥对 以及如何通过PuTTY远程登录SSH服务器 一 安装PuTTY PuTTY是在Windows平台下常用的SSH客户端工
  • 羊年计划

    今天是新年上班第一天 告诉自己 要有个计划 要改变 要成就 要突破 要加油 那么到底要如何呢 新年里要做哪些事呢 订婚 婚姻大事 要包容 要相亲相爱 今年我要带着宝贝儿走出去 到处玩 我要带着宝宝坐下来 为梦想奋斗 减肥 健康的身体是革命的
  • 【测试开发】自动化测试在美团外卖的实践与落地

    文章目录 自动化测试在美团外卖的实践与落地 1 项目背景 2 项目目标 3 方案选型 4 实践和探索 4 1 问题和挑战 4 2 前置条件准备 4 3 用例录制与回放的数据一致性 4 4 用例录制与回放的操作一致性 4 5 可溯源的自动化测
  • 你假笨JVM参数 - 001 ReservedCodeCacheSize

    你假笨JVM参数分享全整理 微信小程序 JVMPocket JVM参数交流平台 Javaer的神奇口袋 序号 001 时间 2017 07 13 参数 XX ReservedCodeCacheSize 含义 Reserved code ca
  • C++程序设计初步——关系运算和逻辑运算

    C 中有众多的操作符来对其C 的程序内容进行运算 有 3 6 关系运算和逻辑运算 C 中若要比较数据时可以使用关系运算符 同样在进行逻辑层面的运算时 用逻辑运算符将逻辑量进行连接 3 6 1 关系运算和关系表达式 C 的关系运算符 lt 小
  • Matlab——二维绘图(最为详细,附上相关实例)

    为了帮助各位同学备战数学建模和学习Matlab的使用 今天我们来聊一聊 Matlab 中的绘图技巧吧 对于 Matlab 这样的科学计算软件来说 绘图是非常重要的一项功能 在数据处理和分析时 良好的绘图技巧能够更直观地呈现数据 增强数据可读
  • Ubuntu16.04+cuda8.0安装教程

    1 安装nvidia驱动 首先去官网上查看适合你GPU的驱动 例如 本人的GPU适合的驱动如图 执行如下语句 安装 sudo add apt repository ppa graphics drivers ppa sudo apt get
  • MAVEN 报错:Plugin 'org.apache.maven.plugins:maven-compiler-plugin:2.3.2' not found

    一 问题 MAVEN 设置编译版本时 报错 Plugin org apache maven plugins maven compiler plugin 2 3 2 not found 如下图 配置如下 二 解决方法 将JDK版本跟POM文件
  • web安全 基础

    web发展史 web1 0 个人网站 门户站 SQL注入 上传漏洞 web2 0 微博 Blog XSS CSRF web流程 客户端 前段 钓鱼 暗链 XSS 点击劫持 CSRF URL跳转 服务端 后端 SQL注入 命令注入 文件上传
  • Spring Cloud Gateway 整合 sentinel 实现流控熔断

    一 什么是网关限流 在微服务架构中 网关层可以屏蔽外部服务直接对内部服务进行调用 对内部服务起到隔离保护的作用 网关限流 顾名思义 就是通过网关层对服务进行限流 从而达到保护后端服务的作用 Sentinel 从 1 6 0 版本开始就提供了

随机推荐