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

实战OpenCV之图像的数学运算

基础入门

        在OpenCV中,图像的数学运算是一种基本而强大的工具,可以用于多种图像处理任务,包括:图像增强、图像融合、特征提取等。这些运算包括加法、减法、乘法和除法等基本的数学操作。

        加法运算:可以用来合并两个图像,或者调整图像的亮度。对于两个图像的加法,OpenCV会逐像素地将两个图像对应位置上的像素值相加。对于图像与常数的加法,就是将该常数加到图像的每个像素值上,一般用于跳转图像的亮度。

        减法运算:通常用来突出图像间的差异,如比较同一场景的不同图像以发现变化的部分。对于两个图像的减法,OpenCV会逐像素地将两个图像对应位置的像素值相减。减法运算还可用于从前景图像中减去背景图像,以突出前景物体。

        乘法运算:通常用于图像融合,或者调整图像的亮度和对比度。OpenCV中的图像乘法是逐像素进行的,并且通常需要将结果归一化到0到255之间。

        除法运算:通常用来调整图像的动态范围,或者对比度。由于直接除法可能会导致像素值溢出或者精度丢失,因此通常需要将图像转换为浮点数类型。

        注意:在进行加法和减法运算时,OpenCV会自动处理溢出问题。乘法和除法需要特别注意数据类型转换,以避免精度损失。

接口介绍

        在OpenCV中,加法运算可以使用cv::add函数,其函数原型如下。

void add(const InputArray& src1, const InputArray& src2, OutputArray& dst,const InputArray& mask = noArray(), int dtype = -1);

        各个参数的含义如下。

        src1和src2:输入图像,必须具有相同的尺寸和深度。

        dst:输出图像,与输入图像具有相同的尺寸和深度(除非指定了不同的数据类型)。

        mask:可选的掩模图像,与输入图像具有相同的尺寸,非零值位置将被应用于加法运算。

        dtype:输出图像的数据类型。如果设置为-1,则输出图像的数据类型与输入图像相同。

        减法运算可以使用cv::subtract函数,其参数与cv::add函数基本相同,故这里不再赘述。

        乘法运算可以使用cv::multiply函数,其函数原型如下。

void cv::multiply(const InputArray& src1, const InputArray& src2,OutputArray& dst, double scale = 1, int dtype = -1);

        各个参数的含义如下。

        src1和src2:输入图像,必须具有相同的尺寸和深度。

        dst:输出图像,与输入图像具有相同的尺寸和深度(除非指定了不同的数据类型)。

        scale:乘法结果的缩放因子,通常用于将结果映射到正确的范围。

        dtype:输出图像的数据类型。如果设置为-1,则输出图像的数据类型与输入图像相同。

        除法运算可以使用cv::divide函数,其参数与cv::multiply函数基本相同,故这里不再赘述。

实战解析

        下面的实战代码首先尝试读取两张图片,并将它们存储在Mat类型的变量img1和img2中。如果图片未能成功加载,程序将输出错误信息并终止。接下来,代码检查两张图片的尺寸是否相同。如果不相同,则输出错误信息并终止程序。这是因为,图像的数学运算要求两张图片必须具有相同的尺寸。

        然后,代码执行以下四个数学运算。

        1、加法运算。将两张图片相加,并将结果存储在outputAdd中。

        2、减法运算。从img1中减去img2,并将结果存储在outputSub中。

        3、乘法运算。将两张图片逐像素相乘,并将结果存储在outputMul中。乘法结果需要进行归一化处理,即将结果除以255。

        4、除法运算。为了执行除法运算,首先将两张图片转换为浮点数类型CV_32F。执行除法运算后,再将结果转换回8位整数类型CV_8U,并将结果存储在outputDiv中。

        最后,我们使用imshow函数分别显示了加法、减法、乘法和除法运算的结果。

#include <opencv2/opencv.hpp>
using namespace cv;#include <iostream>
using namespace std;int main()
{Mat img1 = imread("C++.png");Mat img2 = imread("Hello.png");if (img1.empty() || img2.empty()){cout << "Can not open or find the image" << endl;return -1;}// 确保两个图像大小相同if (img1.size() != img2.size()){cout << "Images must be same size" << endl;return -1;}// 加法运算Mat outputAdd;add(img1, img2, outputAdd);// 减法运算Mat outputSub;subtract(img1, img2, outputSub);// 乘法运算Mat outputMul;multiply(img1, img2, outputMul, 1.0 / 255.0);// 除法运算Mat outputDiv;Mat img1Float, img2Float;img1.convertTo(img1Float, CV_32F);img2.convertTo(img2Float, CV_32F);divide(img1Float, img2Float, outputDiv, 1.0);outputDiv.convertTo(outputDiv, CV_8U);// 显示结果imshow("Add", outputAdd);imshow("Subtract", outputSub);imshow("Multiply", outputMul);imshow("Divide", outputDiv);waitKey(0);destroyAllWindows();return 0;
}

        执行上面的示例代码,运行效果可参考下图。


http://www.mrgr.cn/news/12231.html

相关文章:

  • 【Unity输入】Input Manager 和 Input System对比
  • Histolab:病理切片的预处理工具|项目实战
  • VS2022 - 制作自己的C#类库dll,并输出Unity识别的pdb调试信息文件
  • Java重修笔记 第四十三天 Set 集合、HashSet 类
  • 前端手写源码系列(一)—— 手写防抖和节流
  • 【YOLO系列】目标检测简介
  • vue3+el-tale封装(编辑、删除、查看详情按钮一起封装)
  • 【Liunx入门】Liunx换源
  • NASA数据集:MetOp-A ASCAT 第 2 级海洋表面风矢量,针对沿岸海洋进行了优化
  • 【深度学习与NLP】——深度卷积神经网络AlexNet
  • 【微信小程序】导入项目
  • AJAX(4)——XMLHttpRequest
  • C语言程序设计-联系篇
  • Mybatis框架基础
  • OpenCV入门12.2:SURF与SIFT比较及SURF示例
  • 如何在没有屏幕时间密码或 Apple ID 的情况下重置 iPhone
  • 【Tomcat】Tomcat10部署war包无法启动
  • 鸿蒙(API 12 Beta3版)【使用AVScreenCapture录屏取原始码流(C/C++)】视频播放与录制
  • 手写题之链式调用
  • 全方位解析红鲸音视频会议SDK助力系统功能集成