OpenCV 学习笔记2 C++

1.图像直方图

直方图(Histogram)是图像处理中常用的工具,它表示图像中每个像素强度值的分布情况。在OpenCV中,可以使用 cv::calcHist 函数来计算图像的直方图。

图像直方图是一种展示图像像素强度分布的统计图表。它显示了图像中每个像素强度值的频率,有助于分析图像的亮度、对比度和色调等特征。以下是图像直方图的一些主要作用:

1.亮度和对比度分析: 直方图可以用于分析图像的整体亮度和对比度。通过观察直方图的形状,可以了解图像中亮度的分布情况,从而调整图像的亮度和对比度,使其更符合需求。

2.图像增强: 直方图均衡化是一种常见的图像增强方法,通过调整图像的直方图,使其更均匀地分布在整个灰度范围内,从而增强图像的细节和对比度。

3.颜色分析: 对于彩色图像,可以对每个颜色通道分别绘制直方图,以了解图像中各个颜色通道的分布情况。这对于颜色校正和调整非常有帮助。

4.阈值选择: 直方图可以帮助选择图像的二值化阈值。通过观察直方图的波峰和波谷,可以找到合适的阈值,将图像转换为二值图像。

5.检测图像质量问题: 异常的直方图形状可能指示图像质量问题,例如曝光不足或曝光过度。通过检查直方图,可以识别并纠正这些问题。

void TestDemo::histogram_demo(Mat& image)
{//创建一个白色底板的图像Mat img = Mat::zeros(Size(512,512),CV_8UC3);img = Scalar(255,255,255);//绘制直方图Mat gray;cvtColor(img,gray,COLOR_BGR2GRAY);//将图像转化为灰度图int histSize=256;//直方图尺寸float range[]={0,256};//像素值范围const float* histRange={range};Mat hist;//we compute the histogram from the 0-th channelint channels[]={0,1};calcHist(&gray,1,channels,Mat(),hist,1,&histSize,&histRange,true,false);//计算直方图 Mat()不使用mask  true->the histogram is uniform//第一个1代表Number of source images      第二个1代表Histogram dimensionality that must be positive and not greater than CV_MAX_DIMS (equal to 32 in the current OpenCV version).//hist :Output histogram, which is a dense or sparse dims -dimensional arrayint hist_w = 512;int hist_h = 400;int bin_w = cvRound((double)hist_w/histSize);// 直方图每条的宽度,cvRound 取整Mat histImage(hist_h,hist_w,CV_8UC3,Scalar(255,255,255));//Mat 高宽    创建直方图图像normalize(hist,hist,0,histImage.rows,NORM_MINMAX,-1,Mat());//直方图归一化for(int i=1;i<histSize;i++){line(histImage,Point(bin_w*(i-1),hist_h-cvRound(hist.at<float>(i-1))),Point(bin_w*(i),hist_h-cvRound(hist.at<float>(i))),Scalar(0,0,0),2,LINE_8,0);//绘制直方图}namedWindow("histogram_demo",WINDOW_AUTOSIZE);imshow("histogram_demo",histImage);}

2.二维直方图

二维直方图是在图像处理中用于描述两个变量(通常是图像的两个通道)之间关系的直方图。在图像处理中,最常见的是彩色图像的二维直方图,其中横轴和纵轴分别表示两个颜色通道。

以下是二维直方图的一些主要特点和应用:

1 颜色分布: 对于彩色图像,二维直方图可以显示不同颜色通道之间的关系。例如,对于RGB图像,横轴和纵轴可以分别表示红色和绿色通道,通过颜色在直方图中的分布,可以了解图像中不同颜色的占比。

2 色调相关性: 二维直方图可以用于分析图像中颜色通道之间的相关性。通过观察直方图的形状,可以了解图像中颜色的相关性,从而更好地理解图像的色调。

3 色彩校正: 通过分析二维直方图,可以识别和调整图像中不同通道的色彩偏差。这对于颜色校正非常有帮助,确保图像的颜色表现准确。

4 图像分割: 二维直方图在图像分割中有广泛的应用。通过选择合适的阈值,可以将图像分割成不同的区域,从而实现物体的检测和识别。

5 通道选择: 通过分析二维直方图,可以确定哪些颜色通道对于特定任务最为重要。这对于图像特征提取和图像识别非常有帮助。

minMaxLoc
minMaxLoc()函数 是 OpenCV 库中的一个函数,用于找到一个多维数组中的最小值和最大值,以及它们的位置。

void minMaxLoc(InputArray src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, InputArray mask=noArray());
src:输入数组或者向量,必须包含至少一个元素。
minVal:可选的输出参数,用于存储最小值的实际值。如果不需要这个值,可以设为0。
maxVal:可选的输出参数,用于存储最大值的实际值。如果不需要这个值,可以设为0。
minLoc:可选的输出参数,用于存储最小值的位置。如果不需要这个值,可以设为0。
maxLoc:可选的输出参数,用于存储最大值的位置。如果不需要这个值,可以设为0。
mask:可选的掩码,其大小和类型必须与 src 相同。如果指定了此参数,那么函数只查找具有非零掩码值的元素。
void TestDemo::histogram_2d_demo(Mat& image)
{//绘制二维直方图Mat hsv;cvtColor(image,hsv,COLOR_BGR2HSV);//将图像转换为HSV图// Quantize the hue to 30 levels// and the saturation to 32 levelsint hbins =30,sbins=32;//H、S通道直方图尺寸int histSize[] = {hbins,sbins};// hue varies from 0 to 179, see cvtColorfloat hranges[] = {0,180};//H通道像素值范围// saturation varies from 0 (black-gray-white) to// 255 (pure spectrum color)float sranges[] = {0,256};//S通道像素值范围const float* ranges[] = {hranges,sranges};MatND hist;// we compute the histogram from the 0-th and 1-st channelsint channels[] = {0,1};calcHist(&hsv,1,channels,Mat(),// do not use maskhist,2,histSize,ranges,true,// the histogram is uniformfalse);//计算二维直方图double maxVal = 0;minMaxLoc(hist,0,&maxVal,0,0);int scale = 10;Mat histImg = Mat::zeros(sbins*scale,hbins*10,CV_8SC3);for(int h =0;h<hbins;h++){for(int s = 0;s<sbins;s++){float binVal = hist.at<float>(h,s);int intensity = cvRound(binVal * 255 / maxVal);rectangle(histImg,Point(h*scale,s*scale),Point((h+1)*scale-1,(s+1)*scale - 1),Scalar::all(intensity),FILLED);}}namedWindow("histogram_2d_demo",WINDOW_FREERATIO);imshow("histogram_2d_demo",histImg);}

在这里插入图片描述

3.直方图均衡化

图像直方图均衡化是一种用于增强图像对比度的方法,通过调整图像的灰度分布,使得各个灰度级均匀分布,从而提高图像的视觉效果。下面详细讲解一下图像直方图均衡化的原理和步骤:
原理:

灰度直方图: 图像的灰度直方图表示了图像中各个灰度级的分布情况,即每个灰度级的像素数量。累积分布函数(CDF): CDF 是灰度直方图的累积形式,表示每个灰度级以下的像素累积数量。均衡化变换: 均衡化变换的目标是将图像的灰度分布映射到均匀分布,即让 CDF 尽可能平滑。

步骤:

计算灰度直方图: 对图像进行灰度化,统计各个灰度级的像素数量。计算累积分布函数(CDF): 利用灰度直方图计算各个灰度级的累积概率。均衡化变换: 利用均衡化变换公式,对每个灰度级进行映射。生成均衡化后的图像: 根据均衡化变换,生成均衡化后的图像。
void TestDemo::equalizeHist_demo(Mat& image)
{Mat equalizedImage;Mat gray;cvtColor(image,gray,COLOR_BGR2GRAY);// applyColorMap(gray,bgr,COLORMAP_JET);equalizeHist(gray,equalizedImage);// cvtColor(equalizedImage,bgr,COLOR_GRAY2BGR);namedWindow("equalizeHist_demo",WINDOW_FREERATIO);imshow("equalizeHist_demo",equalizedImage);}

在这里插入图片描述

4.图像卷积

图像卷积是图像处理中的一种基本操作,它通过在图像上滑动一个卷积核(也称为滤波器或窗口),对图像的每个像素进行加权和的操作。这一过程可以用来实现一系列的图像处理任务,如模糊、锐化、边缘检测等。下面是图像卷积的基本原理和步骤:
原理:

卷积核: 卷积核是一个小矩阵,包含了一组权重值。卷积操作时,卷积核在图像上滑动,与图像中的每个像素进行加权和的计算。加权和计算: 对于图像中的每个像素,卷积核与图像的对应区域进行逐元素相乘,然后将所有乘积结果相加,得到最终的加权和。滑动操作: 卷积核在图像上滑动,对每个像素都进行加权和的计算,得到新的图像。

步骤:

定义卷积核: 确定卷积核的大小和权重。图像填充: 可选的步骤,对图像进行填充,以保留边缘信息。卷积操作: 卷积核在图像上滑动,对每个像素进行加权和的计算。输出结果: 得到卷积后的图像,即输出结果。
void TestDemo::convolution_demo(Mat& image)
{//创建一个白色底板的图像Mat img = Mat::zeros(Size(512,512),CV_8UC3);img = Scalar(255,255,255);//图像卷积操作Mat kernel = (Mat_<float>(3,3)<<0,-1,0,-1,5,-1,0,-1,0);//创建卷积核   图像锐化Mat dst;filter2D(image,dst,-1,kernel);//图像卷积//when ddepth=-1, the output image will have the same depth as the sourcenamedWindow("convolution_demo",WINDOW_FREERATIO);imshow("convolution_demo",dst);
}

在这里插入图片描述

5.高斯滤波

高斯滤波(Gaussian Blur)是一种常用的图像模糊技术,它使用高斯函数对图像进行卷积,从而实现图像平滑处理。高斯滤波的主要目的是去除图像中的高频噪声,使图像更加平滑,减少细节信息,常用于图像预处理、边缘检测前的图像平滑等任务。
高斯滤波的原理:

高斯函数: 高斯函数是一种数学函数,通常用于表示正态分布。在图像处理中,高斯函数用于生成一个二维的高斯核(卷积核)。卷积操作: 高斯核在图像上滑动,对图像中的每个像素进行加权和的计算。不同位置的像素受到的权重由高斯函数的形状决定,距离中心越远的像素权重越小。权重计算: 高斯函数的形状由标准差(σ)决定,标准差越大,权重分布越广。权重计算采用二维高斯函数的值,将其归一化,得到最终的权重。

高斯滤波的步骤:

定义高斯核: 定义一个二维高斯核,指定标准差。图像卷积: 将高斯核与图像进行卷积操作。输出结果: 得到经过高斯模糊处理后的图像。
void TestDemo::guassian_blur_demo(Mat& image)
{//定义高斯核大小和标准差int kernel_size =35;double sigma = 35;//高斯模糊Mat dst;GaussianBlur(image,dst,Size(kernel_size,kernel_size),sigma);//GaussianBlur参数为输入图像、输出图像、高斯核大小、标准差namedWindow("gaussian_blur_demo",WINDOW_FREERATIO);imshow("gaussian_blur_demo",dst);}

在这里插入图片描述

6.双边滤波

双边滤波是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空间与信息和灰度相似性,达到保边去噪的目的,具有简单、非迭代、局部处理的特点。之所以能够达到保边去噪的滤波效果是因为滤波器由两个函数构成:一个函数是由几何空间距离决定滤波器系数,另一个是由像素差值决定滤波器系数。

void bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT )

. InputArray src: 输入图像,可以是Mat类型,图像必须是8位或浮点型单通道、三通道的图像。
. OutputArray dst: 输出图像,和原图像有相同的尺寸和类型。
. int d: 表示在过滤过程中每个像素邻域的直径范围。如果这个值是非正数,则函数会从第五个参数sigmaSpace计算该值。
. double sigmaColor: 颜色空间过滤器的sigma值,这个参数的值月大,表明该像素邻域内有月宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
. double sigmaSpace: 坐标空间中滤波器的sigma值,如果该值较大,则意味着颜色相近的较远的像素将相互影响,从而使更大的区域中足够相似的颜色获取相同的颜色。当d>0时,d指定了邻域大小且与sigmaSpace五官,否则d正比于sigmaSpace.
. int borderType=BORDER_DEFAULT: 用于推断图像外部像素的某种边界模式,有默认值BORDER_DEFAULT.
void TestDemo::bilateral_filter_demo(Mat& image)
{//定义参数int diameter = 20 ; //像素领域的直径double sigma_color = 175.0;// 颜色空间标准差double sigma_space = 175.0;// 空间的标准差//高斯双边滤波Mat dst;bilateralFilter(image,dst,diameter,sigma_color,sigma_space);//显示结果namedWindow("bilateral_filter_demo",WINDOW_AUTOSIZE);imshow("bilateral_filter_demo",dst);
}

在这里插入图片描述

7.实时人脸检测

CascadeClassifier是opencv下objdetect模块中用来做目标检测的级联分类器的一个类;简而言之是滑动窗口机制+级联分类器的方式;

 C++: bool CascadeClassifier::load(const string& filename)
void CascadeClassifier::detectMultiScale(const Mat& image, vector<Rect>& objects, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size())
cascade – Haar classifier cascade (OpenCV 1.x API only). It can be loaded from XML or YAML file using Load(). When the cascade is not needed anymore, release it using cvReleaseHaarClassifierCascade(&cascade).
image – Matrix of the type CV_8U containing an image where objects are detected.
objects – Vector of rectangles where each rectangle contains the detected object.
scaleFactor – Parameter specifying how much the image size is reduced at each image scale.
minNeighbors – Parameter specifying how many neighbors each candiate rectangle should have to retain it.
flags – Parameter with the same meaning for an old cascade as in the function cvHaarDetectObjects. It is not used for a new cascade.
minSize – Minimum possible object size. Objects smaller than that are ignored.
maxSize – Maximum possible object size. Objects larger than that are ignored.
void TestDemo::face_detect_demo()
{//加载人脸检测器模型cv::CascadeClassifier face_cascade;if(!face_cascade.load("/home/liutao/opencv-3.4.7/data/haarcascades/haarcascade_frontalface_default.xml")){std::cerr<<" Error loading face cascade model!"<<std::endl;return;}//在这里添加进行人脸检测的代码//例如 ,可以在摄像头捕获的每一帧上进行人脸检测cv::VideoCapture capture(0);//打开默认摄像头if(!capture.isOpened()){std::cerr<<"Error opening camera!"<<std::endl;return ;}cv::Mat frame;while(capture.read(frame)){//转换图像为灰度图Mat gray;cvtColor(frame,gray,COLOR_BGR2GRAY);equalizeHist(gray,gray);//直方图均衡化提高对比度//进行双边滤波Mat dst;bilateralFilter(gray,dst,20,150,150);//进行人脸检测std::vector<cv::Rect>faces;face_cascade.detectMultiScale(dst,faces,1.1,3,0,cv::Size(30,30));flip(frame,frame,1);//在图像上标记检测到的人脸for(const auto& face :faces){cv::rectangle(frame,face,cv::Scalar(255,0,0),2);//用蓝色矩形标记人脸}//显示结果cv::imshow("Face Detection Demo",frame);//检测按键,按下ESC键退出循环if(cv::waitKey(30)==27){break;}}}

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

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

相关文章

ES学习日记(十一)-------Java操作ES之基本操作

前言 此篇博客还是一些基础操作&#xff0c;没什么可写的&#xff0c;需要的同学直接抄作业进行测试就可以 上一节写了连接和测试新增操作,这一节写java操作ES的基本操作,也就是增删改查,在这里补充一点知识,我们之前用了指定的索引进行指定添加 有一个情况是,如果我们指定了…

企微自建应用开发-注意事项

1、错误48002 api forbidden&#xff0c;接口无权限 1.1添加ip白名单&#xff0c;ip地址以企微返回值为准 1.2按照规则添加相应权限&#xff0c;例如&#xff1a;【联系我】二维码接口 2、错误60011 no privilege to access/modify contact/party/agent 2.2修改应用可见范围&am…

文件下载本地

1、不管什么格式的文件都需要转为字节数组 byte[] 2、再转为各种格式文件的的输出流 3、再转为文件输出流写入本地 注意File生成目录 FileOutputStream为具体全称。

C++ | Leetcode C++题解之第19题删除链表的倒数第N个结点

题目&#xff1a; 题解&#xff1a; class Solution { public:ListNode* removeNthFromEnd(ListNode* head, int n) {ListNode* dummy new ListNode(0, head);ListNode* first head;ListNode* second dummy;for (int i 0; i < n; i) {first first->next;}while (fi…

【产品】ADW300 无线计量仪表 用于计量低压网络的三相有功电能

1 概述 ADW300 无线计量仪表主要用于计量低压网络的三相有功电能&#xff0c;具有体积小、精度高、功能丰富等优点&#xff0c;并且可选通讯方式多&#xff0c;可支持 RS485 通讯和 Lora、2G、NB、4G 等无线通讯方式&#xff0c;增加了外置互感器的电流采样模式&#xff0c;从…

机器学习-09-图像处理

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中图像处理技术。 参考 02图像知识 色彩基础知识整理-色相、饱和度、明度、色调 图像特征提取&#xff08;VGG和Resnet特征提取卷积过程详解&#xff09; Python图像处理入门 【人工智能】PythonOpenCV…

Redis高级-分布式缓存RDB原理

分布式缓存 1.1.2.RDB原理 bgsave开始时会fork主进程得到子进程&#xff0c;子进程共享主进程的内存数据。完成fork后读取内存数据并写入 RDB 文件。 fork采用的是copy-on-write技术&#xff1a; 当主进程执行读操作时&#xff0c;访问共享内存&#xff1b;当主进程执行写操…

idea中输入法被锁定如何清除

今天遇到一个问题&#xff1f;idea中输入法被锁定了&#xff0c;无论怎么切换输入法&#xff0c;切换中英文&#xff0c;在idea中输出的均为英文内容&#xff0c;该如何解决呢&#xff1f;&#xff08;idea官网&#xff1a;JetBrains: 软件开发者和团队的必备工具&#xff09; …

SQLite Android 绑定(十八)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLite 在Android安装与定制方案&#xff08;十七&#xff09; 下一篇&#xff1a;SQLite—系列文章目录 ​ 应用程序编程 加载共享库 在使用任何与 SQLite 相关的方法或对象之前&#xff0c;本机 SQLite 必…

ABAP ADBC_QUERY 测试代码

项目中使用的接口取数采用的是DBLink的方式&#xff0c;对方提供的表名太长&#xff0c;超过标准程序ADBC_QUERY的参数长度&#xff0c;于是写了一份简单的测试代码用来测试连接和取数。 DBCO配置&#xff1a; 测试程序&#xff1a; 程序源码&#xff1a; *&------------…

实验五 智能手机互联网程序设计(微信程序方向)实验报告

请完成数值比较任务&#xff1b; 二、实验步骤与结果&#xff08;给出对应的代码或运行结果截图&#xff09; index.js Page({ /** * 页面的初始数据 */ data: { num1:0, num2:0, num3:"" }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { },…

14款DevOps/SRE工具,助力提升运维效率

简介 随着平台工程的兴起&#xff0c;DevOps 和 SRE 不断发展&#xff0c;带来了新一代工具&#xff0c;旨在提高软件开发和运维的效率、可扩展性和可靠性。 在本篇文章中&#xff0c;我们将深入探讨一些最具发展前景的工具&#xff0c;它们正在塑造持续集成与部署、监控与可观…

【c语言】自定义类型:结构体详解

目录 自定义类型&#xff1a;结构体 结构体类型的声明 结构体变量的创建和初始化 结构的特殊声明 结构的自引用 结构体内存对齐 对其规则 为什么存在内存对齐&#xff1f; 修改默认对⻬数 结构体传参 结构体实现位段 位段的内存分配 位段的跨平台问题 位段的应用…

SpringBoot实现RabbitMQ的通配符交换机(SpringAMQP 实现Topic交换机)

文章目录 pomyml生产者消费者 Topic类型的Exchange与Direct相比&#xff0c;都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routing key 的时候使用通配符&#xff01; Routingkey 一般都是有一个或多个单词组成&#xff0c;多个单词…

2024年思维100春季线上比赛倒计时9天,来看看官方样题

今天是2024年4月11日&#xff0c;距离2024年春季思维100活动第一阶段的线上比赛4月20日还有9天。今年思维100活动的考试重点是什么呢&#xff1f;虽然主办方未公布&#xff0c;我们可以从主办方发布的参考题目中来推测今年的考试重点&#xff0c;并且按照这个来举一反三&#x…

基于GAN的多变量时间序列污染训练集异常检测

论文地址&#xff1a;https://ieeexplore.ieee.org/document/9618824 论文源码&#xff1a;https://github.com/sxxmason/FGANomaly 期刊&#xff1a;IEEE Transactions on Knowledge and Data Engineering 多元时间序列异常检测在结构健康监测、智能运维、量化交易等诸多实际…

谷粒商城实战(012 业务-商城业务)

Java项目《谷粒商城》架构师级Java项目实战&#xff0c;对标阿里P6-P7&#xff0c;全网最强 总时长 104:45:00 共408P 此文章包含第203p-第p210的内容 介绍 这段除了210集都是商城业务&#xff0c;无太多可学习的&#xff0c;可跳过这7集&#xff0c;直接看第2100集 一个页…

CentOS 7.9安装过程的一些小插曲

首先请允许我推荐一下这款制作U盘启动盘的软件 Rufus - 轻松创建 USB 启动盘Rufus: Create bootable USB drives the easy wayhttps://rufus.ie/zh/ Rufus 是一款格式化和创建 USB 启动盘的辅助工具。 本软件适用于以下场景&#xff1a; 需要将可引导 ISO (Windows、Linux、UE…

Django之rest_framework(二)

格式后缀 为了使我们的响应不再硬连接到单个内容类型这一事实,我们可以将API格式后缀添加到API之后。使用格式后缀为我们提供了明确引用给定格式的URL,譬如:http://example.com/api/items/4.json 官网:2 - Requests and responses - Django REST framework views:在函数…

大厂Java笔试题之求一个整数转换为二进制后所有位上1的个数

题目&#xff1a;给定一个整数&#xff0c;求这个整数转换成二进制以后&#xff0c;所有位上1的个数&#xff08;数字大小不超过32位数字的范围&#xff09;。比如8这个整数&#xff0c;转换成二进制是00001000&#xff0c;那么就是输出1。public class Demo5 {public static v…