c++图像像素计算

       我们知道每张图像都能够用矩阵来表示,矩阵中每个元素的值表示了图像中每个像素值,像素值的大小就对应着图像的亮暗。因此找到矩阵中的最大值,就是找到了图像中灰度值最大的像素,计算矩阵所有元素的平均值就是计算图像像素平均灰度,平均灰度表示图像整体的亮暗程度。

图像像素计算有以下几种:

1、寻找图像中最大像素值和最小像素值

可以利用opencv的minMaxLoc()函数实现

void cv::minMaxLoc(InputArray src,double * minVal,double * maxVal = 0,Point * minLoc = 0,Point * maxLoc = 0,InputArray mask = noArray())
  • src:需要寻找最大值和最小值的图像或者矩阵,要求必须是单通道矩阵
  • minVal:图像或者矩阵中的最小值。
  • maxVal:图像或者矩阵中的最大值。
  • minLoc:图像或者矩阵中的最小值在矩阵中的坐标。
  • maxLoc:图像或者矩阵中的最大值在矩阵中的坐标。
  • mask:掩模,用于设置在图像或矩阵中的指定区域寻找最值。

Point数据类型是用于表示图像的像素坐标,由于图像的像素坐标轴以左上角为坐标原点,水平方向为x轴,垂直方向为y轴,因此Point(x,y)对应于图像的行和列表示为Point(列数,行数)。在OpenCV中对于2D坐标和3D坐标都设置了多种数据类型,针对2D坐标数据类型定义了整型坐标cv::Point2i(或者cv::Point)、double型坐标cv::Point2d、浮点型坐标cv::Point2f,对于3D坐标同样定义了上述的坐标数据类型,只需要将其中的数字“2”变成“3”即可。对于坐标中x、y、z轴的具体数据,可以通过变量的x、y、z属性进行访问,例如Point.x可以读取坐标的x轴数据。
对于多通道矩阵数据,利用cv::Mat::reshape()将多通道变成单通道,或者分别寻找每个通道的最值,然后再进行比较寻找到全局最值。

具体使用案例如下:

#include<iostream>
#include<vector>
#include<string>
#include <opencv2/opencv.hpp>
#include "opencv/highgui.h"using namespace std;
using namespace cv;int main(int argc,char** argv) {cout<<"OpenCv Version: "<<CV_VERSION<<endl;//输出使用的opencv版本号Mat img=imread('1.jpg');//单通道图像Mat imgs=imread("2.jpg");//多通道图像double minVal,maxVal;//用于存放矩阵中的最大值和最小值Point minIdx,maxIdx;//用于存放矩阵中的最大值和最小值的位置/*寻找单通道矩阵中的最值*/minMaxLoc(img,&maxVal,&minVal,&minIdx,&maxIdx);cout << "img中最大值是:" << maxVal << " " << "在矩阵中的位置:" << maxIdx << endl;cout << "img中最小值是:" << minVal << " " << "在矩阵中的位置:" << minIdx << endl;/*寻找多通道矩阵中的最值*/Mat imgs_re=imgs.reshape(1,4);//将多通道矩阵变成单通道矩阵minMaxLoc(imgs_re,&minVal,&maxVal,&minIdx,&maxIdx);cout << "img中最大值是:" << maxVal << " " << "在矩阵中的位置:" << maxIdx << endl;cout << "img中最小值是:" << minVal << " " << "在矩阵中的位置:" << minIdx << endl;return 0;
}
2、计算图像的均值和标准差

如果我们想知道图像的亮暗程度变化,可以求图像的均值来判断。均值越大,说明图像越亮。图像标准差表示图像中明暗变化程度,标准差越大表示图像中明暗变化越明显。

我们可以利用cv::mean()函数用于计算图像的平均值,也可以利用meanStdDev()函数用于同时计算图像的均值和标准方差。

cv::Scalar cv::mean(InputArray src,InputArray mask = noArray())
  • src:待求平均值的图像矩阵。
  • mask:掩模,用于标记求取哪些区域的平均值。


该函数用来求取图像矩阵的每个通道的平均值,函数的第一个参数用来输入待求平均值的图像矩阵,其通道数目可以在1到4之间。需要注意的是,该函数的返回值是一个cv::Scalar类型的变量,函数的返回值有4位,分别表示输入图像4个通道的平均值,如果输入图像只有1个通道,那么返回值的后三位都为0,例如输入该函数一个单通道平均值为1的图像,输出的结果为[1,0,0,0],可以通过cv::Scalar[n]查看第n个通道的平均值。该函数的第二个参数用于控制图像求取均值的范围,在第一个参数中去除第二个参数中像素值为0的像素,当不输入第二个参数时,表示求取第一个参数全部像素的平均值。

void cv::meanStdDev(InputArray src,OutputArray mean,OutputArray stddev,InputArray mask = noArray())
  • src:待求平均值的图像矩阵。
  • mean:图像每个通道的平均值,参数为Mat类型变量。
  • stddev:图像每个通道的标准方差,参数为Mat类型变量。
  • mask:掩模,用于标记求取哪些区域的平均值和标准方差。

该函数的第一个参数与前面mean()函数第一个参数相同,都可以是1-4通道的图像,不同之处在于该函数没有返回值,图像的均值和标准方差输出在函数的第二个和第三个参数中,区别于mean()函数,用于存放平均值和标准方差的是Mat类型变量,变量中的数据个数与第一个参数通道数相同,如果输入图像只有一个通道,该函数求取的平均值和标准方差变量中只有一个数据。
具体使用案例如下:

#include<iostream>
#include<vector>
#include<string>
#include <opencv2/opencv.hpp>
#include "opencv/highgui.h"using namespace std;
using namespace cv;int main(int argc,char** argv) {cout<<"OpenCv Version: "<<CV_VERSION<<endl;Mat img=imread("3.jpg");//单通道图像或矩阵Mat imgs=imread("4.jpg");//多通道图像或矩阵cout << "/* 用meanStdDev同时求取图像的均值和标准方差 */" << endl;Scalar myMean;myMean=mean(imgs);cout<<"imgs均值 = "<<myMean<<endl;cout<<"imgs第一个通道的均值 = "<<myMean[0]<<" "<<"imgs第二个通道的均值 = "<<myMean[1]<<endl;cout << "/* 用meanStdDev同时求取图像的均值和标准方差 */" << endl;Mat myMeanMat,myStddevMat;meanStdDev(img,myMeanMat,myStddevMat);cout << "img均值=" << myMeanMat << " " << endl;cout << "img标准方差=" << myStddevMat << endl << endl;meanStdDev(imgs,myMeanMat,myStddevMat);cout << "img均值=" << myMeanMat << " " << endl;cout << "img标准方差=" << myStddevMat << endl << endl;return 0;
}
3、两张图像比较运算

opencv提供了求取两张图像每一位像素较大或者较小灰度值的max()、min()函数,这两个函数分别比较两个图像中每一位元素灰度值的大小,保留较大(较小)的灰度值。

void cv::max(InputArray src1,InputArray src2,OutputArray dst) 
void cv::min(InputArray src1,InputArray src2,OutputArray dst)
  • src1:第一个图像矩阵,可以是任意通道数的矩阵。
  • src2:第二个图像矩阵,尺寸和通道数以及数据类型都需要与src1一致。
  • dst:保留对应位置较大(较小)灰度值后的图像矩阵,尺寸、通道数和数据类型与src1一致

该函数的功能相对来说比较简单,就是比较图像每个像素的大小,按要求保留较大值或者较小值,最后生成新的图像。

具体案例如下:

#include<iostream>
#include<vector>
#include<string>
#include <opencv2/opencv.hpp>
#include "opencv/highgui.h"using namespace std;
using namespace cv;int main(int argc,char** argv) {cout<<"OpenCv Version: "<<CV_VERSION<<endl;//对两张彩色图像进行比较运算Mat img1=imread("l.png");Mat img2=imread("2.jpg");if(img0.empty()||img1.empty()){cout<<"请确认图像文件名称是否正确"<<endl;return -1;}Mat comMin,comMax;max(img1,img2,comMax);min(img1,img2,comMin);imshow("comMin",comMin);imshow("comMax",comMax);//与掩模进行比较运算Mat src1=Mat::zeros(Size(512,512),CV_8UC3);Rect rect(100,100,300,300);//起点(100,100)长300,宽300的矩形src1(rect)=Scalar(255,255,255);//生成一个300*300的掩模Mat comsrc1,comsrc2;min(img1,src1,comsrc1);imshow("comsrc1",comsrc1);Mat src2=Mat(512,512,CV_8UC3,Scalar(0,0,255));//生成一个显示红色的低通掩模min(img1,src2,comsrc2);imshow("comsrc2",comsrc2);//对两张图片灰度图像进行比较运算Mat img1g,img2g,comMing,comMaxg;cvtColor(img1,img1g,COLOR_BGR2GRAY);cvtColor(img2,img2g,COLOR_BGR2GRAY);max(img1g,img2g,comMaxg);max(img1g,img2g,comMaxg);imshow("comMing",comMing);imshow("comMaxg",comMaxg);return 0;
}
4、图片逻辑运算

opencv为两个图像像素之间逻辑运算与、或、异或以及非运算提供了bitwise_and()、bitwise_or()、bitwise_xor()和bitwise_not()四个函数,在进行逻辑计算时,一定要保证两个图像矩阵之间的尺寸、数据类型和通道数相同,多个通道进行逻辑运算时不同通道之间是独立进行的。

具体案例如下:

#include <opencv2\opencv.hpp>
#include <iostream>
#include <vector>using namespace std;
using namespace cv;int main()
{Mat img = imread("lena.png");if (img.empty()){cout << "请确认图像文件名称是否正确" << endl;return -1;}//创建两个黑白图像Mat img0 = Mat::zeros(200, 200, CV_8UC1);Mat img1 = Mat::zeros(200, 200, CV_8UC1);Rect rect0(50, 50, 100, 100);img0(rect0) = Scalar(255);//将起点50,50,长宽100的矩形框区域像素值置为255,白色Rect rect1(100, 100, 100, 100);img1(rect1) = Scalar(255);imshow("img0", img0);imshow("img1", img1);//进行逻辑运算Mat myAnd, myOr, myXor, myNot, imgNot;bitwise_not(img0, myNot);bitwise_and(img0, img1, myAnd);bitwise_or(img0, img1, myOr);bitwise_xor(img0, img1, myXor);bitwise_not(img, imgNot);imshow("myAnd", myAnd);imshow("myOr", myOr);imshow("myXor", myXor);imshow("myNot", myNot);imshow("img", img);imshow("imgNot", imgNot);waitKey(0);return 0;}

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

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

相关文章

feign遇到的问题

调用fegin接口报错&#xff1a; 请求地址/dept/findProjectDept,发生未知异常. org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.lang.RuntimeException: java.io.IOException: UT000036: Connec…

递归算法:二叉树前序、中序、后序遍历解析与递归思想深度剖析

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《linux深造日志》 《高效算法》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 一、二叉树的遍历1.1 链式结构二叉树的创建1.1 二叉树结构图 二、 前序遍历代码演示&#xff1a;2.1 前序遍历递…

苏宁易购商品详情API:电商实时数据

一、引言 在当前的电商行业中&#xff0c;数据是最为宝贵的资源之一。如何获取实时、准确的数据&#xff0c;对于电商业务的运营和优化至关重要。作为中国领先的电商平台之一&#xff0c;苏宁易购提供了丰富的API接口&#xff0c;其中包括商品详情API&#xff0c;以便第三方开…

STL stack练习

CSTL之stack栈容器 - 数据结构教程 - C语言网CSTL之stack栈容器1.再谈栈回顾一下之前所学的栈&#xff0c;栈是一种先进后出的数据结构&#xff0c;而实现方式需要创建多个结构体&#xff0c;通过链式的方式进行实现&#xff0c;这是标准的栈的思路&#xff0c;而在STL中栈可以…

odoo17核心概念——env

env在odoo中是一个非常重要的概念&#xff0c;它是一个全局变量&#xff0c;保存了odoo运行环境的重要信息&#xff0c;env分为前端和后端 一、环境(env) 1、前端的env 在web\static\src\env.js中定义&#xff0c;包含两个重要的对象&#xff1a; 全局数据总线bus&#xff…

一键在线获取APP公钥、包名、签名及备案信息方法介绍

​ 目录 一键在线获取APP公钥、包名、签名及备案信息方法介绍 摘要 引言 一键获取APP包信息 操作步骤 ​编辑 解析报告 总结 致谢 关键词 参考资料 声明 摘要 本文介绍了一款在线APP解析工具&#xff0c;可以一键获取APP的公钥、包名、签名等基础信息&#xff0c;…

Python教程:对于初学者,几个易懂的装饰器示例用法

装饰器是Python中的一个高级功能&#xff0c;它可以用来扩展或修改一个函数或方法的功能&#xff0c;而不需要修改其原始代码。装饰器本质上是一个函数&#xff0c;它接受一个函数作为参数&#xff0c;并返回一个新的函数对象。 装饰器通常用于添加与函数功能无关的额外功能&a…

矩阵秩的公式小结

文章目录 矩阵秩的公式说明公式 矩阵秩的公式 说明 解释下了公式时,注意矩阵的行数列数由三秩相等原理,向量组的秩往往转换为矩阵的秩来研究 线性方程组 A x b \bold{Axb} Axb或 A X B \bold{AXB} AXB型方程有解定理 R ( A ) ⩽ R ( A , B ) R(\bold{A})\leqslant{R(\bold{…

java中IO与NIO有什么不同

目录 1. 阻塞与非阻塞 2. 缓冲区&#xff08;Buffer&#xff09; 3. 选择器&#xff08;Selector&#xff09; 4. 面向流与面向缓冲 5. 非阻塞IO Java中的IO&#xff08;Input/Output&#xff09;和NIO&#xff08;New I/O&#xff09;都是用于处理输入和输出的API&#x…

LeetCode 647回文子串 517最长回文子序列 | 代码随想录25期训练营day57

动态规划算法14 LeetCode 647 回文子串 2023.12.20 题目链接代码随想录讲解[链接] int countSubstrings(string s) {//暴力搜索&#xff0c;前两层遍历确定子字符串的起始和末尾位置//第三层循环判断当前子字符串是否为回文串/*int result 0;for (int i 0; i < s.size…

灰盒测试简要学习指南!

在本文中&#xff0c;我们将了解什么是灰盒测试、以及为什么要使用它&#xff0c;以及它的优缺点。 在软件测试中&#xff0c;灰盒测试是一种有用的技术&#xff0c;可以确保发布的软件是高性能的、安全的并满足预期用户的需求。这是一种从外部测试应用程序同时跟踪其内部操作…

2023 英特尔On技术创新大会直播 | 窥探未来科技的边界

2023 英特尔On技术创新大会直播 | 窥探未来科技的边界 写在最前面观后感其他有趣的专题课程 写在最前面 嘿&#xff0c;你是不是对科技和创新充满好奇&#xff1f;2023 英特尔 On 技术创新大会线上活动邀请你一起探索最前沿的科技世界&#xff01; 这不仅是一场普通的聚会&…

golang开发--beego入门

Beego 是一个基于 Go 语言的开源框架&#xff0c;用于构建 Web 应用程序和 API。它采用了一些常见的设计模式&#xff0c;以提高开发效率、代码可维护性和可扩展性。 一&#xff0c;MVC设计模式 Beego 框架采用了经典的 MVC&#xff08;Model-View-Controller&#xff09;设计…

Linux 上Redis 升级

背景&#xff1a; 随着我Ruby on Rails 的版本升级&#xff0c;sidekiq的升级&#xff0c;我的redis已经不能很好的支持了&#xff0c;当我启动sidekiq时出现如下报错&#xff1a; redis-client requires Redis 6 with HELLO command available (redis://127.0.0.1:6379/0) 意…

程序员的23大IONIO面试问题及答案

文章目录 1. 什么是IO流&#xff1f;2.java中有几种类型的流&#xff1f;3.字节流和字符流哪个好&#xff1f;怎么选择&#xff1f;4.读取数据量大的文件时&#xff0c;速度会很慢&#xff0c;如何选择流&#xff1f;5. IO模型有几种&#xff1f;6.阻塞IO &#xff08;blocking…

如何用Excel制作一张能在网上浏览的动态数据报表

前言 如今各类BI产品大行其道&#xff0c;“数据可视化”成为一个热门词汇。相比价格高昂的各种BI软件&#xff0c;用Excel来制作动态报表就更加经济便捷。今天小编就将为大家介绍一下如何使用葡萄城公司的纯前端表格控件——SpreadJS来实现一个Excel动态报表&#xff1a; 实…

华为鸿蒙操作系统简介及系统架构分析(2)

接前一篇文章&#xff1a;华为鸿蒙操作系统简介及系统架构分析&#xff08;1&#xff09; 本文部分内容参考&#xff1a; 鸿蒙系统学习笔记(一) 鸿蒙系统介绍 特此致谢&#xff01; 上一回对于华为的鸿蒙操作系统&#xff08;HarmonyOS&#xff09;进行了介绍并说明了其层次化…

C语言——高精度乘法

一、引子 高精度乘法相较于高精度加法和减法有更多的不同&#xff0c;加法和减法是一位对应一位进行操作的&#xff0c;而乘法是一个数的每一位对另一个数的每一位进行操作&#xff0c;需要的计算步骤更多。 二、核心算法 void Calculate(int num1[], int num2[], int numres…

代理IP解决了哪些问题?如何切换IP地址?

代理IP主要解决了以下问题&#xff1a; 1. 隐私保护&#xff1a;通过代理IP&#xff0c;用户可以隐藏自己的真实IP地址&#xff0c;增强网络匿名性&#xff0c;保护个人信息不被泄露。 2. 地理位置限制&#xff1a;某些网站或服务可能会根据用户的IP地址实施地域限制。使用代…

Linux使用javac编译报错-bash: javac: command not found

如果在Linux上使用javac编译时出现错误"bash: javac: command not found"&#xff0c;这通常意味着您的系统没有正确安装Java开发工具包&#xff08;JDK&#xff09;。 请按照以下步骤检查和解决该问题&#xff1a; 首先&#xff0c;确保已安装Java开发工具包&…