C++结合OpenCV:图像的加法运算

news2024/11/18 5:53:28

一、图像运算

针对图像的加法运算、位运算都是比较基础的运算。但是,很多复杂的图像处理功能正是借助这些基础的运算来完成的。所以,牢固掌握基础操作,对于更好地实现图像处理是非常有帮助的。本章简单介绍了加法运算、位运算,并使用它们实现了位平面分解、图像异或加密、数字水印、脸部打码/解码等实例。

1.图像加法运算

在图像处理过程中,经常需要对图像进行加法运算。可以通过加号运算符“+”对图像进行加法运算,在c++中也可以利用cv::add()对图像进行加法运算。

通常情况下,在灰度图像中,像素用8个比特位(一个字节)来表示,像素值的范围是[0,255]。两个像素值在进行加法运算时,求得的和很可能超过255。上述两种不同的加法运算方式,对超过255的数值的处理方式是不一样的。

加号运算符

使用加号运算符“+”对图像a(像素值为a)和图像b(像素值为b)进行求和运算时,遵循以下规则:

式中,mod()是取模运算,“mod(a+b, 256)”表示计算“a+b的和除以256取余数”。

根据上述规则,两个点进行加法运算时:

● 如果两个图像对应像素值的和小于或等于255,则直接相加得到运算结果。例如,像素值28和像素值36相加,得到计算结果64。

● 如果两个图像对应像素值的和大于255,则将运算结果对256取模。例如255+58=313,大于255,则计算(255+58)% 256=57,得到计算结果57。

当然,上述公式也可以简化为a+b=mod(a+b,256),在运算时无论相加的和是否大于255,都对数值256取模。

【例4.4.1】假设我们有两个8位灰度图像,图像a的像素值为a,图像b的像素值为b。

1.像素值a为28,像素值b为36。

2.像素值a为255,像素值b为58。

#include <iostream>

#include <cmath>

int main() {


// 案例1: 像素值a为28, 像素值b为36

int a1 = 28;

int b1 = 36;

int result1 = a1 + b1; // 结果直接相加

std::cout << "a1 + b1 = " << result1 << std::endl; // 输出64

int result1_mod = result1 % 256; // 对256取模

std::cout << "mod(a1+b1, 256) = " << result1_mod << std::endl; // 输出64 (因为28+36小于或等于255)



案例2: 像素值a为255, 像素值b为58

int a2 = 255;

int b2 = 58;

int result2 = a2 + b2; // 结果直接相加

std::cout << "a2 + b2 = " << result2 << std::endl; // 输出313

int result2_mod = result2 % 256; // 对256取模

std::cout << "mod(a2+b2, 256) = " << result2_mod << std::endl; // 输出57 (因为255+58大于255)

return 0;

}

上述代码演示了如何根据给定的规则对两个图像的像素值进行加法运算。对于每个案例,它首先计算直接相加的结果,然后计算对256取模的结果,以验证规则的正确性。

【例4.4.2】在c++中分别使用加号运算符和opencv库中的函数cv2.add()计算两幅灰度图像的像素值之和,观察处理结果。

#include <opencv2/opencv.hpp>

#include <opencv2/highgui/highgui.hpp>

int main() { // 读取图像

cv::Mat a = cv::imread("lena.bmp", cv::IMREAD_GRAYSCALE);

if (a.empty()) { std::cout << "无法读取图像" << std::endl; return -1; } // 创建图像的副本

cv::Mat b = a.clone(); // 计算图像的和

cv::Mat result1;

cv::add(a, b, result1); // 使用函数cv2.add()计算a和b之和

cv::Mat result2 = a + b; // 使用加号运算符计算a和b之和 // 显示原始图像和结果

cv::namedWindow("Original",cv::WINDOW_NORMAL);

cv::imshow("Original",a);

cv::namedWindow("Result1", cv::WINDOW_NORMAL);

cv::imshow("Result1", result1);

cv::namedWindow("Result2",cv::WINDOW_NORMAL);

cv::imshow("Result2", result2);

cv::waitKey(0);

cv::destroyAllWindows();

return 0;

 }

在本例中,首先读取了图像lena并将其标记为变量a;接下来,使用语句“b=a”将图像lena复制到变量b内;最后,分别使用“+”cv::add()计算a和b之和。

运行程序,得到如图3-1所示的运行结果,其中:

图4-11 【例4.4.2】程序运行结果图

● 左图是原始图像lena。

● 中间的图是使用加号运算符将图像lena自身相加的结果。

● 右图是使用函数cv2.add()将图像lena自身相加的结果。从上述运算结果可以看出

● 使用加号运算符计算图像像素值的和时,将和大于255的值进行了取模处理,取模后大于255的这部分值变得更小了,导致本来应该更亮的像素点变得更暗了,相加所得的图像看起来并不自然。

● 使用函数cv::add()计算图像像素值的和时,将和大于255的值处理为饱和值255。图像像素值相加后让图像的像素值增大了,图像整体变亮。

2.图像加权和

所谓图像加权和,就是在计算两幅图像的像素值之和时,将每幅图像的权重考虑进来,可以用公式表示为:

dst=saturate(src1×α+src2×β+γ)

式中,saturate()表示取饱和值(最大值)。图像进行加权和计算时,要求src1和src2必须大小、类型相同,但是对具体是什么类型和通道没有特殊限制。它们可以是任意数据类型,也可以有任意数量的通道(灰度图像或者彩色图像),只要二者相同即可。

OpenCV 库中提出了一个addWeighted()函数,用于执行两个图像的加权和操作。这个函数可以用来创建一幅新的图像,其中包含了两幅输入图像的加权组合。通常,这在图像融合和混合的应用中非常有用,该函数的语法格式为:

void cv::addWeighted(

    cv::InputArray src1,   // 第一个输入图像

    double alpha,          // 第一个输入图像的权重

    cv::InputArray src2,   // 第二个输入图像

    double beta,           // 第二个输入图像的权重

    double gamma,          // 加权和的可选标量

    cv::OutputArray dst,  // 输出图像

    int dtype = -1        // 输出图像的数据类型,默认为-1(与输入相同)

);

其中,参数alpha和beta是src1和src2所对应的系数,它们的和可以等于1,也可以不等于1。该函数实现的功能是dst = src1×alpha + src2×beta + gamma。需要注意,式中参数gamma的值可以是0,但是该参数是必选参数,不能省略。可以将上式理解为“结果图像=图像1×系数1+图像2×系数2+亮度调节量”。

参数说明:

  1. src1:第一个输入图像(可以是 cv::Mat 类型或类似的数据结构)。
  2. alpha:第一个输入图像的权重,一个双精度浮点数。
  3. src2:第二个输入图像。
  4. beta:第二个输入图像的权重,也是一个双精度浮点数。
  5. gamma:加权和的可选标量,通常是一个双精度浮点数。
  6. dst:输出图像,这里将存储加权和的结果。
  7. dtype:输出图像的数据类型,默认为-1,表示与输入图像的数据类型相同。

【例4.4.3】使用函数cv::addWeighted()对两幅图像进行加权混合,观察处理结果。根据题目要求,编写程序如下:

#include <opencv2/opencv.hpp>

int main() {

// 读取图像

cv::Mat a = cv::imread("boat.bmp");

cv::Mat b = cv::imread("lena.bmp"); // 检查图像是否正确读取

if (a.empty() || b.empty()) {

std::cout << "无法读取图像文件!" << std::endl;

return -1;

}

// 计算加权和

cv::Mat result;

cv::addWeighted(a, 0.6, b, 0.4, 0, result); // 显示图像

cv::namedWindow("boat", cv::WINDOW_NORMAL);

cv::imshow("boat", a);

cv::namedWindow("lena", cv::WINDOW_NORMAL);

cv::imshow("lena", b);

cv::namedWindow("result", cv::WINDOW_NORMAL);

cv::imshow("result", result); // 等待按键,然后关闭窗口

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

return 0;

}

本程序使用cv2.addWeighted()函数,对图像boat和图像lena分别按照0.6和0.4的权重进行混合。运行程序,得到如图4-12所示的结果,其中:

● 左图是原始图像boat。

● 中间的图是原始图像lena。

● 右图是图像boat和图像lena加权混合后的结果图像。

图4-12 【例4.4.3】程序的运行结果

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

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

相关文章

CG Magic分享3dmax渲染太亮问题如何解决?

3D Max软件渲染时&#xff0c;渲染问题较多也是正常的&#xff0c;对于行业小白来说&#xff0c;渲染问题多也是能理解的&#xff0c;因为&#xff0c;小编经常在问答中&#xff0c;看到一些网友提问&#xff0c;3dmax渲染太亮怎么办&#xff1f; 3dmax渲染太亮了怎么回事&…

如何定位和优化程序CPU、内存等性能之巅

摘要 性能优化指在不影响系统运行正确性的前提下&#xff0c;使之运行得更快&#xff0c;完成特定功能所需的时间更短&#xff0c;或拥有更强大的服务能力。本文将介绍性能优化的基本概念以及如何定位和优化程序中的CPU、内存和IO瓶颈。 引言 随着计算机系统的日益复杂和应用…

有哪些windows录屏软件?

有哪些windows录屏软件&#xff1f;随着技术的发展&#xff0c;使用Windows录屏软件已成为一种非常方便的方式&#xff0c;可以帮助人们记录和分享他们在计算机上的操作过程。例如&#xff0c;您可以使用录屏软件记录您在编辑文档或演示新产品时的屏幕操作&#xff0c;并将其用…

BIOS知识枝桠——RAID 磁盘阵列

文章目录 前言一、RAID介绍二、RAID等级分类1.RAID02.RAID13.RAID24.RAID3和RAID45.RAID5和RAID66.RAID77.RAID10 BIOS下组建RAID 前言 假设存在多块磁盘&#xff0c;如果不组建阵列&#xff0c;磁盘与磁盘之间是没有任何关系的。磁盘A和B&#xff0c;放在A中的文件与B磁盘没有…

自学Python笔记总结(更新中……)

自学Python笔记总结 网址数据类型类型查看类型&#xff0c;使用type内置类标识符 输出输入语句format函数的语法及用法数据类型的转换运算符算数运算符赋值运算符的特殊场景拆包 比较运算符逻辑运算符 与 短路位运算符运算符优先级 程序流程控制分支语句pass 占位 循环语句 whi…

可应用于电脑主板等产品上的精密基准电路WL431 输出电压可设定 响应速度快

WL431为三端可调节精密基准源。通过两个外接电阻&#xff0c;输出电压可在Vref约2.5 V )到36V连续调节。该电路输出阻抗小(0.2Q)。 开启特性好&#xff0c;在许多应用场合&#xff0c;它能较好地替换齐纳极管。 主要特点&#xff1a;● 温度系数 50pmC ● 在…

荣耀开发者大会2023 · 一张图读懂智慧人机交互分论坛

荣耀智慧人机交互&#xff0c;以用户意图理解为主的智慧交互&#xff0c;平台级AI使能主动理解用户意图&#xff0c;服务找人能力全面升级&#xff01; 荣耀智慧门能精准理解用户交互意图&#xff0c;覆盖100头部应用&#xff0c;支持文本、图片等元素类型随心拖拽&#xff0c…

自媒体必备的8个素材网站,免费可商用。

自媒体必备的8个素材网站&#xff0c;视频、音效、音频、图片等素材非常齐全&#xff0c;免费下载&#xff0c;无需担心侵权&#xff0c;赶紧收藏起来吧~ 视频素材 1、菜鸟图库 https://www.sucai999.com/video.html?vNTYwNDUx 菜鸟图库可以找到设计、办公、图片、视频、音频…

基于树莓派5(Raspberry Pi 5)的高性能工业平板电脑升级版!

​ 上海晶珩继推出首个搭载 Raspberry Pi 5 的平板电脑ED-HMI3010系列后&#xff0c;又推出了具备高性能和多功能特性的 Raspberry Pi 5 的平板电脑ED-HMI3020系列。ED-HMI3020支持选择7英寸和10.1英寸两种尺寸的触摸屏&#xff0c;可选配 M.2 NVMe SSD 存储扩展&#xff0c;提…

new mars3d.graphic.PolygonEntity({计算平面几何中心点及贴地效果展示

1.Mars3d提供了几何图形相关点位的计算方法polyutil&#xff1a; PolyUtil - V3.7.0 - Mars3D API文档 2.通过api可以算出相关经纬度坐标&#xff0c;实现相关中心点的展示 &#xff1a; 功能示例(Vue版) | Mars3D三维可视化平台 | 火星科技 3.相关实现代码&#xff1a; fu…

HCIP的静态路由复习

VRP设置用户名密码登录 [R1]aaa [R1-aaa]local-user TMG password cipher huawei #创建一个名TMG的用户&#xff0c;密码huawei Info: Add a new user.[R1-aaa]local-user TMG privilege level 15 #设置权限 [R1-aaa]local-user TMG service-type terminal …

个性化定制的知识付费小程序,为用户提供个性化的知识服务

明理信息科技知识付费saas租户平台 随着知识经济的兴起&#xff0c;越来越多的人开始重视知识付费&#xff0c;并希望通过打造自己的知识付费平台来实现自己的知识变现。本文将介绍如何打造自己的知识付费平台&#xff0c;并从定位、内容制作、渠道推广、运营维护四个方面进行…

恒温器探针样品座

恒温器探针样品座是一种用采用可移动探针完成恒温器电缆和被测样品的电学连接&#xff0c;避免了每次样品电引线的焊接&#xff0c;探针可移动&#xff0c;5mm--20mm大小的样品均可适用&#xff0c;探针可以安装6个&#xff0c;标准配置探针数量为4个。 恒温器探针样品座由T型…

安装tesseract

Tesseract OCR是一款由HP实验室开发由Google维护的开源OCR引擎&#xff0c;在字符识别领域发挥着举足轻重的作用。除了使用软件自带的中英文识别库&#xff0c;我们可以使用Tesseract OCR训练属于自己的字库。 下载地址&#xff1a;https://digi.bib.uni-mannheim.de/tesseract…

自动化革命:大象机器人的Mercury A1机械臂

引言 大象机器人的Mercury系列&#xff0c;是面向工业自动化和智能制造的新型机械臂产品线。这些机械臂不仅在设计上创新&#xff0c;还在材料选择上使用了碳纤维、铝合金和工程塑料等轻质强韧材料&#xff0c;搭载高精度谐波减速器。Mercury系列的推出&#xff0c;反映了大象机…

【CSS】解决height = line-height 文字不垂直居中(偏上、偏下)的问题

解决办法1&#xff1a; 查看 font-family 属性&#xff0c;确认是否是因为字体而导致的不垂直居中问题。 其他小知识&#xff1a; 基线就是小写x字母的下边缘(线) 就是我们常说的 基线。line-height 属性设置的行高也就是定义的两行文字基线之间的距离! 参考文章&#xff1a;…

为什么单片机上的程序不怎么使用malloc,而PC上经常使用?

为什么单片机上的程序不怎么使用malloc&#xff0c;而PC上经常使用&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「单片机的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿…

数字保险箱:揭秘迅软DSE企业加密系统,助您信息安全无忧!

在当今时代&#xff0c;数据泄露危机和各种网络攻击已成为企事业单位所面临的首要威胁。在这个背景下&#xff0c;企业加密系统如同一把强大的“保护伞”&#xff0c;为海量企业提供了至关重要的防护。那么&#xff0c;究竟是什么原因&#xff0c;使得企业加密系统能够成为抵抗…

【React源码 - Diff算法】

介绍 在React学习中&#xff0c;Diff算法(协调算法)&#xff0c;想必我们并不陌生&#xff0c;简单来说就是一个对比新老节点寻找差异&#xff0c;然后找出最小的一个变化集&#xff0c;最后对这个最小变化集进行最小的DOM操作&#xff0c;本文将从源码来分析在React(17.0.2)中…

uniapp 实战 -- 创建 uni-admin 项目,部署到 uniCloud 前端网页托管(免费云空间)

创建 uni-admin 项目 可见 只能创建一个超级管理员&#xff0c;创建过后&#xff0c;登录页将不再显示 注册管理员账号 部署到 uniCloud 前端网页托管 部署成功&#xff0c;访问地址可预览效果&#xff01; https://static-mp-7b65169e-151f-4fbb-a5ba-2125d4f56e3f.next.bs…