OpenCV图像直方图(16)
  Jk5625xsZPHl 2023年11月02日 63 0

在分析图像、物体和视频信息的时候,我们经常用直方图来表达我们关注的信息。直方图在计算机视觉中应用广泛。例如,通过判断帧与帧之间边缘和颜色的统计量是否出现巨大变化,来检测视频中场景的变换。在数字图像处理中,通常使用的是灰度直方图,灰度直方图是一种计算代价非常小但很有用的工具,它概括了一幅图像的灰度级信息。灰度直方图是图像灰度级的函数,用来描述每个灰度级在图像矩阵中的像素个数或者占有率。直方图分布较广较均匀的图像对比度高,视觉效果好。

API介绍

void calcHist( const Mat* images, int nimages,const int* channels, InputArray mask,OutputArray hist, int dims, const int* histSize,const float** ranges, bool uniform = true, bool accumulate = false );
/*******************************************************************
*			images: 		输入图			
*			nimages:	    输入图个数
*			channels:		统计第几通道
*			mask:			掩膜
*			hist:		    数组存储输出值
*			dims:			输出直方图维度			
*			histSize:		直方图区间
*			ranges:			统计像素区间
*			uniform:	   直方图数组是否归一化处理
*			accumulate:	   多图时是否累计计算
*********************************************************************/
void calcHist( const Mat* images, int nimages, const int* channels, InputArray mask,SparseMat& hist, int dims,const int* histSize, const float** ranges,bool uniform = true, bool accumulate = false );
/*******************************************************************
*			images: 		输入图			
*			nimages:	    输入图个数
*			channels:		统计第几通道
*			mask:			掩膜
*			hist:		    图像存储输出值
*			dims:			输出直方图维度			
*			histSize:		直方图区间
*			ranges:			统计像素区间
*			uniform:	   直方图数组是否归一化处理
*			accumulate:	   多图时是否累计计算
*********************************************************************/
void calcHist( InputArrayOfArrays images,const std::vector<int>& channels,InputArray mask, OutputArray hist,const std::vector<int>& histSize,const std::vector<float>& ranges,bool accumulate = false );
/*******************************************************************
*			images: 		输入图			
*			channels:		变换矩阵
*			mask:			输出图大小
*			hist:		    数组存储输出值
*			histSize:		直方图区间
*			ranges:			统计像素区间
*			accumulate:	   多图时是否累计计算
*********************************************************************/

综合代码

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
class Hist 
{
public:
	Hist(string url = "./mm.jpg") :img(imread(url)) 
	{
		hist["img"] = img;
	}
	void TestCalcHist() 
	{
		split(img, bgr);
		//准备直方图的参数
		Mat Blue, Green, Red;
		const int channerl[] = { 0 };
		const int histSize[] = { 256 };
		float rang[] = { 0,255 };
		const float* ranges[] = { rang };

		calcHist(&bgr[0], 1, channerl, Mat(), Blue, 1, histSize, ranges);
		calcHist(&bgr[1], 1, channerl, Mat(), Green, 1, histSize, ranges);
		calcHist(&bgr[2], 1, channerl, Mat(), Red, 1, histSize, ranges);
		//绘制直方图
		int width = 500;
		int height = 300;
		hist["hist"] = Mat(height, width, CV_8UC3, Scalar(0, 0, 0));
		//归一化处理
		normalize(Blue, Blue, 0, 300, NORM_MINMAX);
		normalize(Green, Green, 0, 300, NORM_MINMAX);
		normalize(Red, Red, 0, 300, NORM_MINMAX);
		//比例问题
		int step = cvRound(float(width) / float(256));   //每一个点的占比
		for (int i = 1; i < 256; i++) 
		{
			line(hist["hist"], Point(step * (i - 1), height - cvRound(Blue.at<float>(i - 1))), Point(step * (i), height - cvRound(Blue.at<float>(i))),Scalar(255,0,0));
			line(hist["hist"], Point(step * (i - 1), height - cvRound(Blue.at<float>(i - 1))), Point(step * (i), height - cvRound(Green.at<float>(i))), Scalar(0, 255, 0));
			line(hist["hist"], Point(step * (i - 1), height - cvRound(Blue.at<float>(i - 1))), Point(step * (i), height - cvRound(Red.at<float>(i))), Scalar(0, 0, 255));
		}
	}

	void Show() 
	{
		for (auto& v : hist) 
		{
			imshow(v.first, v.second);
		}
		waitKey(0);
	}

protected:
	Mat img;
	map<string, Mat> hist;
	vector<Mat> bgr;
};

int main() 
{
	unique_ptr<Hist> p(new Hist);
	p->TestCalcHist();
	p->Show();
	return 0;
}

OpenCV图像直方图(16)_直方图

OpenCV图像金字塔

图像金字塔有两种,

  • 高斯金字塔:高斯金字塔用来向下采样
  • 拉普拉斯金字塔:图像底层图像重建上层未采样图像

在数据图像处理中,就是数据残差,可以对图像进行最大程度的还原,配合高斯金字塔—起使用。

高斯金字塔

高斯金字塔是由底部的最大分辨率图像逐次向下采样得到的一系列图像。最下面的图像分辨率最高,越往上图像分辨率越低。高斯金字塔的向下采样过程是:对于给定的图像先做一次高斯平滑处理,也就是使用一个卷积核对图像进行卷积操作,再对图像采样,去除图像中的偶数行和偶数列,然后就得到一幅图片,对这幅图片再进行上述操作,就可以得到高斯金字塔。

OpenCV图像直方图(16)_OpenCV_02

拉普拉斯金字塔

拉普拉斯金字塔与高斯金字塔正好相反,高斯金字塔通过底层图像构建上层图像,而拉普拉斯是通过上层小尺寸的图像构建下层大尺寸的图像。主要应用于图像融合,即是通过残差来还原原图。

图像向上采样是由小图像不断放大的过程。它将图像在每个方向上扩大为原图像的⒉倍,新增的行和列均用0来填充,并使用与“向下采样”相同的卷积核乘以4,再与放大后的图像进行卷积运算,以获得“新增像素”的新值。所有元素都被规范化为4,而不是1。值得注意的是,放大后的图像比原始图像要模糊。

OpenCV图像直方图(16)_#include_03

API介绍

//向下采样
void pyrDown( InputArray src, OutputArray dst,const Size& dstsize = Size(), int borderType = BORDER_DEFAULT );
/*******************************************************************
*			src: 			输入图			
*			dst:			输出图
*			dstsize:		卷积核大小
*			borderType:		边界模式
*********************************************************************/
//向上采样
void pyrUp( InputArray src, OutputArray dst,const Size& dstsize = Size(), int borderType = BORDER_DEFAULT );
/*******************************************************************
*			src: 			输入图			
*			dst:			输出图
*			dstsize:		卷积核大小
*			borderType:		边界模式
*********************************************************************/

综合代码

#include <iostream>
#include <string>
#include <map>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
class Pyr 
{
public:
	Pyr() :img(imread("20.jpg")) 
	{
		pyr["img"] = img;
	}
	void TestPyrDown() 
	{
		pyrDown(img, pyr["d1"]);
		pyrDown(pyr["d1"], pyr["d2"]);
		pyrDown(pyr["d2"], pyr["d3"]);
	}
	void TestPyrUp() 
	{
		pyrUp(img, pyr["u1"]);
		pyrUp(pyr["u1"], pyr["u2"]);
		//pyrUp(pyr["u2"], pyr["u3"]);
	}
	void Show() 
	{
		int i = 0;
		for (auto& v : pyr) 
		{
			imshow(v.first, v.second);
			moveWindow(v.first, i++ * 100, 100);
		}
		waitKey(0);
	}
protected:
	Mat img;
	map<string, Mat> pyr;
};

int main() 
{
	unique_ptr<Pyr> p(new Pyr);
	p->TestPyrUp();
	p->TestPyrDown();
	p->Show();
	return 0;
}

OpenCV图像直方图(16)_直方图_04

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  gBkHYLY8jvYd   2023年12月06日   48   0   0 #includecii++
  gBkHYLY8jvYd   2023年11月19日   27   0   0 #includecic++
  gBkHYLY8jvYd   2023年11月19日   14   0   0 #includeios数据
  gBkHYLY8jvYd   2023年11月19日   23   0   0 #include子树结点
  gBkHYLY8jvYd   2023年11月19日   22   0   0 #includei++数据
  gBkHYLY8jvYd   2023年11月19日   23   0   0 #include数组ci
  gBkHYLY8jvYd   2023年12月10日   17   0   0 #include邻域灰度图像
  gBkHYLY8jvYd   2023年12月10日   22   0   0 #include数组i++
  gBkHYLY8jvYd   2023年12月06日   19   0   0 #includeios数据
  gBkHYLY8jvYd   2023年12月08日   20   0   0 #includecii++
  gBkHYLY8jvYd   2023年11月19日   19   0   0 #includeiosci
  gBkHYLY8jvYd   2023年11月14日   28   0   0 #includei++升序
  gBkHYLY8jvYd   2023年11月22日   21   0   0 #include十进制高精度
  gBkHYLY8jvYd   2023年11月22日   25   0   0 #includeiosci
Jk5625xsZPHl