Opencv灰度直方图

灰度直方图是一个帮助分析图像很有力的工具

  灰度直方图这个程序主要有几个函数和结构体先说一下:

  1.  CreateHIst

         CvHistogram* cvCreateHist( int dims, int* sizes, int type,  float** ranges=NULL, int uniform=1 );

          dims代表直方图是几维的,本程序是一个一维直方图,即bins只由x坐标索引

         sizes 代表有多少个bins

         type有两种类型一是稠密数组CV_HIST_ARRAY和稀疏数组CV_HIST_TREE,这里由于是一维直方图我们选择稠密数组

         ranges代表了bins中值得取值范围,这里我们的灰度值为0-255,所以选取0-255

         uniform归一化标识,默认为1,标识x方向被等分为sizes个bins

  2. CalcHist

        void cvCalcHist( IplImage** image, CvHistogram* hist, int accumulate=0, const CvArr* mask=NULL );

代码如下:

#include"stdio.h"
#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>

#define cvQueryHistValue_1D( hist, idx0 )  ((float)cvGetReal1D( (hist)->bins, (idx0)))  

IplImage* DrowHist(CvHistogram* hist,float scaleX = 1,float scaleY = 1)
{
	float Max = 0;
	cvGetMinMaxHistValue(hist,0,&Max,0,0); //获得最大值
	

	IplImage* imghist = cvCreateImage(cvSize(256*scaleX,64*scaleY),8,1);  //根据屏幕大小自动调整
	cvZero(imghist); 

	for(int i = 0;i<255;i++)
	{
		float histValue = cvQueryHistValue_1D(hist,i);  //取值
		float nextValue = cvQueryHistValue_1D(hist,i+1);

		//以4个点来描边
		CvPoint pt1 = cvPoint(i*scaleX,64*scaleY);
		CvPoint pt2 = cvPoint((i+1)*scaleX,64*scaleY);
		CvPoint pt3 = cvPoint((i+1)*scaleX,64*scaleY-(nextValue/Max)*64*scaleY);
		CvPoint pt4 = cvPoint(i*scaleX,64*scaleY-(histValue/Max)*64*scaleY);

		int numPts = 5;
		CvPoint pts[5];
		pts[0] = pt1;
		pts[1] = pt2;
		pts[2] = pt3;
		pts[3] = pt4;
		pts[4] = pt1;

		cvFillConvexPoly(imghist,pts,numPts,cvScalar(255));//多边形填充
		 
	}
	return imghist;
}
int main()
{
	IplImage* img = cvLoadImage("E:\\1.bmp");
	cvNamedWindow("1");
	cvShowImage("1",img);
	

	int dims = 1;
	int size = 256;
	float b_range[] = {0,255};
	float *ranges[] = {b_range};
	//二维可用下面方式表示
	//float r_range[] = {0,255};
	//float * ranges[] = {b_range,r_range};

	CvHistogram* hist ; //创建直方图
	hist = cvCreateHist(dims,&size,CV_HIST_ARRAY,ranges,1);//dims表示几维,size表示要观察的像素最大值,CV..表示密集型 ranges表示每个通道的范围 ,0表示均等分配
	
	cvClearHist(hist);//防止系统分配的随机值影响

	IplImage* imgR = cvCreateImage(cvGetSize(img),8,1);
	IplImage* imgG = cvCreateImage(cvGetSize(img),8,1);
	IplImage* imgB = cvCreateImage(cvGetSize(img),8,1);

	cvSplit(img,imgB,imgG,imgR,NULL);//把图像按bgr方式分割

	cvCalcHist(&imgB,hist,0,0); //统计图像的像素点 
	IplImage* histB = DrowHist(hist); //画直方图
	cvClearHist(hist);
	

	cvCalcHist(&imgG,hist,0,0);
	IplImage* histG =  DrowHist(hist);   
	cvClearHist(hist);

	cvCalcHist(&imgR,hist,0,0);
	IplImage* histR = DrowHist(hist); 
	cvClearHist(hist);

	cvNamedWindow("b");
	cvShowImage("b",histB);

	cvNamedWindow("g");
	cvShowImage("g",histG);

	cvNamedWindow("r");
	cvShowImage("r",histR);

	cvWaitKey(0);
	return 0;
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
OpenCV灰度直方图是一种用于显示图像中像素强度频率的图形表示方法。它是一种用于分析图像中灰度级别分布的常见工具,可以用于图像处理、计算机视觉和模式识别等领域。 在OpenCV中,可以使用cv::calcHist()函数计算灰度直方图。该函数需要输入图像和一个表示直方图的数组。直方图数组的大小取决于灰度级别数,例如8位图像有256个灰度级别,因此直方图数组大小应该为256。 以下是计算灰度直方图的示例代码: ```cpp cv::Mat image = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE); // 读取灰度图像 int histSize = 256; // 灰度级别数 float range[] = { 0, 256 }; // 灰度级别范围 const float* histRange = { range }; bool uniform = true, accumulate = false; cv::Mat hist; cv::calcHist(&image, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange, uniform, accumulate); int hist_w = 512, hist_h = 400; int bin_w = cvRound((double)hist_w / histSize); cv::Mat histImage(hist_h, hist_w, CV_8UC1, cv::Scalar(0)); normalize(hist, hist, 0, histImage.rows, cv::NORM_MINMAX, -1, cv::Mat()); for (int i = 1; i < histSize; i++) { cv::line(histImage, cv::Point(bin_w*(i - 1), hist_h - cvRound(hist.at<float>(i - 1))), cv::Point(bin_w*(i), hist_h - cvRound(hist.at<float>(i))), cv::Scalar(255), 2, 8, 0); } cv::imshow("灰度直方图", histImage); cv::waitKey(); ``` 此代码将显示在灰度图像中计算的直方图,可以使用normalize()函数将其归一化,并使用cv::line()函数将其绘制为图像。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码敌敌畏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值