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

这篇具有很好参考价值的文章主要介绍了C++结合OpenCV:图像的加法运算。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、图像运算

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

1.图像加法运算

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

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

加号运算符

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

C++结合OpenCV:图像的加法运算,SpireCV,c++,opencv,计算机视觉

式中,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所示的运行结果,其中:

C++结合OpenCV:图像的加法运算,SpireCV,c++,opencv,计算机视觉

图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加权混合后的结果图像。

C++结合OpenCV:图像的加法运算,SpireCV,c++,opencv,计算机视觉

图4-12 【例4.4.3】程序的运行结果文章来源地址https://www.toymoban.com/news/detail-802525.html

到了这里,关于C++结合OpenCV:图像的加法运算的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【图像处理OpenCV(C++版)】——2.2 OpenCV之矩阵运算详解(全)

    前言 : 😊😊😊 欢迎来到本博客 😊😊😊 🌟🌟🌟 本专栏主要结合OpenCV和C++来实现一些基本的图像处理算法并详细解释各参数含义,适用于平时学习、工作快速查询等,随时更新。 😊😊😊 具体食用方式:可以点击本专栏【OpenCV快速查找(更新中)】–搜索你要查询的算子

    2024年02月03日
    浏览(68)
  • 我在Vscode学OpenCV 基本的加法运算

    链接:《我在Vscode学OpenCV 处理图像》 属性— API 形状 img.shape 图像大小 img.size 数据类型 img.dtype  shape:如果是彩色图像,则返回包含行数、列数、通道数的数组;如果是二值图像或者灰度图像,则仅返回行数和列数。通过该属性的返回值是否包含通道数,可以判断一幅图像

    2024年02月05日
    浏览(47)
  • C++中键盘响应结合OpenCV库进行图像灰度图、HSV图转换和亮度调整

    QuickDemo.cpp quick_opencv.h main.cpp 按键esc退出程序。 注意必须点击原图上再输入1或2或3才有响应。

    2024年02月20日
    浏览(64)
  • 【Python/Opencv】图像权重加法函数:cv2.addWeighted()详解

    在OpenCV图像加法cv2.add函数详解详细介绍了图像的加法运算。 除了这种加法外,OpenCV还提供了带权重的加法,即两副图像的像素通道值相加时各自按一定的权重比例取值来相加。 假设有2个图像矩阵src1和src2,在两个图像融合时,各自的权重分别为alpha和beta,则二者融合后的目

    2024年02月15日
    浏览(85)
  • opencv -12 图像运算之按 《位或》 运算(图像融合&图像修复和去除)

    或运算的规则是,当参与或运算的两个逻辑值中有一个为真时,结果就为真。其逻辑关系可以类比为如图 所示的并联电路,两个开关中只要有任意一个闭合时,灯就会亮。 3-5 对参与或运算的算子的不同情况进行了说明,表中使用“or”表示或运算。 按位或运算是指将数值转

    2024年02月16日
    浏览(54)
  • OpenCv 图像的算数运算

    1. 图像加法 函数 cv.add(img1, img2) 参数中的img1 和 img2 应该是相同的深度和类型, 或者第二个图像可以是像素值 代码示例: 可以注意到,如果二者的和大于最大像素值255那么opencv会将其自动置为255. 合成实例: 可以发现 add 函数就是普通的像素值相加 2.图像混合 cv.addWeighted(img

    2024年02月03日
    浏览(35)
  • OpenCV 笔记(4):图像的算术运算、逻辑运算

    图像的本质是一个矩阵,所以可以对它进行一些常见的算术运算,例如加、减、乘、除、平方根、对数、绝对值等等。除此之外,还可以对图像进行逻辑运算和几何变换。 我们先从简单的图像加、减、逻辑运算开始介绍。后续会有专门的内容介绍图像的几何变换等。 图像的

    2024年02月06日
    浏览(46)
  • OpenCV——图像按位运算

    OpenCV——图像按位运算由CSDN点云侠原创,爬虫自重。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。   OpenCV4 针对两个图像之间的“与”、“或”、“异或”、以及“非”运算分别提供了 bitwise_and() 、 bitwise_or() 、 bitwise_xor() 、 bitwise_not() 函数。图

    2024年02月01日
    浏览(39)
  • opencv -11 图像运算之按位逻辑运算(图像融合&图像修复和去除)

    按位逻辑运算是一种对图像进行像素级别的逻辑操作的方法,使用OpenCV的按位逻辑运算函数可以对图像进行位与(AND)、位或(OR)、位非(NOT)和位异或(XOR)等操作。 通俗点就是将像素点的十进制值转成二进制 来运算 以下是一些常见的按位逻辑运算的应用场景: 图像融

    2024年02月17日
    浏览(43)
  • 【OpenCV入门】第五部分——图像运算

    当计算机处理图像时,有些内容需要处理,有些内容不需要处理。能够覆盖原始图像,仅暴露原始图像“感兴趣区域”(ROI)的模板图像就叫做 掩模 。 掩模 (mask),也叫做掩码,在程序中用二值图像来表示:0值(纯黑)区域表示被遮盖的部分,255值(纯白)区域表示暴露

    2024年02月10日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包