OpenCV學習心得(8) -- 直方圖的顯示

原创 2012年03月22日 16:55:22

轉載請注明出處與作者

這裡只討論1維的直方圖

void calcHist(const Mat* arrays, int narrays, const int* channels, InputArray mask, OutputArray hist,

       int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false )

這個函數可以用來計算直方圖.

arrays 源Mat數組的指針

narrays  源Mat數組中Mat的個數

channels 這是一個int型指針,它指向一個數組,為哪些channel需要被計算.當arrays 為多個Mat的時候,channel index是從0開始向下連續計算的.這個數組的大小應該與dims相同.

mask 必須是8-bit 圖像遮罩矩陣,大小與源Mat相同,非0元素對應的源Mat中的點表示為需要計算的點.如果為空則表示所有點都需要計算.

hist 輸出的直方圖矩陣.注意這只是一個數值統計矩陣,並非圖像.

dims 直方圖的維度,必須是正整數,並且不能大於CV_MAX_DIMS.

histSize 表示在計算直方圖的時候要分成多少個塊來計算.最終結果的hist矩陣的行數(rows)就是這個histSize.也就是將要統計的值分成histSize 個區域,像素點落在其中哪個區域,哪個區域的值就增加.

ranges 這是一個指針數組,數組中的每一個元素都是一個指針,這個指針指向一個多元素的數組.這個參數數用來確定histSize 個塊中的每一個塊的數值範圍.

下面詳細說明一下histSize和ranges的關係:

可以這樣認為:histSize和ranges都是數組,histSize數組中存放的是整數,ranges數組中存放的是數組型指針. histSize和ranges這兩個數組的維數應該是一樣的,都等於直方圖的維度dims .也就是說每一個histSize元素都對應一個ranges元素.

當uniform=true的時候,ranges[i]中 只要有2個值(也就是一個區間)就可以了,函數會根據histSize[i] 的數量對這個區間進行等分.

當uniform=false的時候,ranges[i]中要有histSize[i] +1個元素.這histSize[i] +1個元素正好分割成histSize[i]個區間.

當源矩陣中的元素值落在對應區間中,則對應區間的值增加.

accumulate為累加設置,當為true的時候不會清空hist中已經存在的數據,而是在其基礎上進行累加.當為false的時候則從0開始計算.


最後得到一個dims列,每列histSize[i] 行的矩陣.這個矩陣就是我們要得到的直方圖hist.


如何將直方圖矩陣中的數據以圖表的方式顯示出來呢?

方法就是事先準備一個Mat并對其進行初始化,初始化包括設定寬度,高度,type和背景圖像(也就是要填充一個背景,可以用圖片或純色).然後使用OpenCV的劃綫函數在其上進行劃綫或寫文字...然後顯示出來即可.

劃綫的時候一定要先將直方圖中的數值縮放到圖像大小再劃綫.(可以畫線也可以畫矩形)


	//!得到一個channel的一維直方圖.
	//!channelIndex 為channel的序號,從0開始,blockcount為需要將range中的值分成多少個區塊來統計,最終得出的直方圖會有blockcount個點.
	//!range_low為圖像數據範圍的最小值,range_up為圖像數據範圍的最大值,這個範圍之外的數據將不被統計.
	static bool GetHistogram_SingleChannel(const cv::Mat &src,cv::Mat &hist,int channelIndex,int blockcount,float range_low,float range_up);
	//將直方圖矩陣中的數據轉換為圖像.
	//type 圖像類型 0=線型 1=矩形
	//imgsize 圖像大小,如果為空則根據直方圖矩陣中的行數來確定(線型為行數,矩形為行數*2),高度為256.color為線或矩形的顏色(默認為黑色),backcolor為背景填充的顏色(默認為白色).
	static bool GetHistogramImage(const cv::Mat& hist, cv::Mat &image,int type,cv::Size imgsize,cv::Scalar *color=NULL,cv::Scalar *backcolor=NULL);
	//!統計源Mat中的直方圖并將其轉換為圖形.
	//!channelIndex 為channel的序號 ,type 圖像類型 0=線型 1=矩形
	//!color為線或矩形的顏色(默認為黑色),backcolor為背景填充的顏色(默認為白色)
	bool GetHistogram(int channelIndex=0,int type=0,RGBQUAD *color=NULL,RGBQUAD *backcolor=NULL);

bool COpenCVImage::GetHistogram_SingleChannel(const cv::Mat &src,cv::Mat &hist,int channelIndex,int blockcount,float range_low,float range_up)
{
	if(src.channels()<=channelIndex || src.depth()!=CV_8U) return false;
	int channels[]={channelIndex};
	int histSize[]={blockcount};
	float hrange[]={range_low,range_up};
	const float *ranges[]={hrange};
	cv::calcHist(&src,1,channels,cv::Mat(),hist,1,histSize,ranges);
	return true;
}
bool COpenCVImage::GetHistogramImage(const cv::Mat& hist, cv::Mat &image,int type,cv::Size imgsize,cv::Scalar *color,cv::Scalar *backcolor)
{
	double maxVal = 0;
	double minVal = 0;
	cv::minMaxLoc(hist, &minVal, &maxVal, 0, 0);
	if(imgsize==cv::Size())
	{
		switch(type)
		{
			case 1://矩形
				{
					imgsize.width=2*hist.rows;
					imgsize.height=256;
					break;
				}
			case 0://連線
			default:
				{
					imgsize.width=hist.rows;
					imgsize.height=256;
				}
		}
	}
	cv::Mat histImg(imgsize, CV_8UC3,(backcolor==NULL? cv::Scalar(255,255,255,0):*backcolor));
	//int hpt = static_cast<int>(0.9*imgsize.height);
	float tmp;
	for(int h=0; h<hist.rows; h++)
	{       
		switch(type)
		{
		    
			case 1://矩形
				{
					float binVal = hist.at<float>(h);
					int rectangle_w= cvRound((imgsize.width/hist.rows+0.5)/2);
					int Point2 = cvRound(binVal*0.9*imgsize.height/maxVal);
					cv::rectangle(histImg,cv::Rect(h*(imgsize.width/hist.rows),imgsize.height-Point2,rectangle_w,Point2),(color==NULL?cvScalar(0,0,0,0):*color));
					//tmp=binVal;
				
					break;
				}
			case 0: //連線
			default:
			{
				if(h==0)
				{
					tmp=hist.at<float>(h);
					continue;
				}
				float binVal = hist.at<float>(h);
				int Point1 = static_cast<int>(tmp*0.9*imgsize.height/maxVal);
				int Point2 = static_cast<int>(binVal*0.9*imgsize.height/maxVal);
				cv::line(histImg, cv::Point(h-1,imgsize.height-Point1),cv::Point(h,imgsize.height-Point2), (color==NULL?cvScalar(0,0,0,0):*color));
			    tmp=binVal;
			}
		}
	}
	image=histImg;
	return true;
}

bool COpenCVImage::GetHistogram(int channelIndex,int type,RGBQUAD *color,RGBQUAD *backcolor)
{
	cv::Mat hist;
	if(!GetHistogram_SingleChannel(m_src(r_roi),hist,channelIndex,256,0.0f,255.0f))
	{
		return false;
	}
	GetHistogramImage(hist,m_src,type,cv::Size(),
		(color==NULL?&cv::Scalar(0,0,0,0):&cv::Scalar(color->rgbBlue,color->rgbGreen,color->rgbRed,color->rgbReserved)),
		(backcolor==NULL?&cv::Scalar(255,255,255,0):&cv::Scalar(backcolor->rgbBlue,backcolor->rgbGreen,backcolor->rgbRed,backcolor->rgbReserved))
		);
    m_modifyed_for_draw=true;
	return true;
}

OpenCV還提供了一個直方圖均衡化的函數

void equalizeHist(InputArray src, OutputArray dst)

可以進行直方圖均衡化.

bool COpenCVImage::equalizeHist()
{
	if(m_src.channels()!=1 || m_src.depth()!=CV_8U) return false;
	cv::equalizeHist(m_src(r_roi),m_src(r_roi));
	m_modifyed_for_draw=true;
	return true;
}


机器学习-1 初步认识机器学习、监督学习和非监督学习

一直对机器学习大数据方面的技术感兴趣,平时也在持续关注相关信息。但是,经过很长一段时间之后,发现,这种碎片化的学习只能停留在浅尝辄止,知道、听说过和了解的基础上,很难对技术有一个系统化的认识、全面而深...
  • u013279509
  • u013279509
  • 2017年02月21日 10:36
  • 407

文件上传控件Uploadify

原文:Uploadify is a jQuery plugin that integrates a fully-customizable multiple file upload utility on...
  • liu1pan2min3
  • liu1pan2min3
  • 2016年05月17日 08:18
  • 848

Oracle 學習心得

一、定位 oracle分两大块,一块是开发,一块是管理。开发主要是写写存储过程、触发器什么的,还有就是用Oracle的Develop工具做form。有点类似于程序员,需要有较强的逻辑思维和创造能力,...
  • rk542190440
  • rk542190440
  • 2013年06月23日 21:03
  • 333

圖形特效與文字顯示

摘要 使用 XNA Framework 設計遊戲程式的時候可以利用 SpriteBatch 類別提供的功能顯示遊戲的內容供使用者檢視,SpriteBatch 類別提供了豐富的功能協助遊戲程式繪製...
  • sai339911
  • sai339911
  • 2013年11月09日 20:22
  • 1087

SQLite學習心得分享<一>

~*~~*~~*~~*~~*~~*本文主要是分享自己學習SQLite數據庫語言過程中的一些基礎知識,運用技巧,僅供參考,參考過程如有錯誤望不吝賜教*~~*~~*~~*~~*~~*~...
  • LeoChen_LC
  • LeoChen_LC
  • 2017年07月15日 11:30
  • 269

直方圖比較(compareHist)

直方圖是影像內容的一個重要特性,兩個直方圖的相似程度,也可以看成是兩張影像的相似程度,OpenCV用compareHist()函式進行直方圖比較,讓我們以量化的方式,得到兩個直方圖的相似程度,comp...
  • Liuqz2009
  • Liuqz2009
  • 2017年03月08日 10:37
  • 197

5家机器学习的创业公司

Alpine data Labs:Greenplum的子公司(EMC是其投资者之一),主要研究方向是预测分析,其软件可以嵌入到公司内部的数据存储中(无论是Hadoop还是其它任意流行的数据库)。通过绘...
  • wozaijsdx
  • wozaijsdx
  • 2013年08月16日 14:39
  • 791

直方圖等化(equalizeHist)

我們可透過拉伸直方圖,使直方圖覆蓋所有強度範圍,這種方法的確能提高影像對比度,但是在多數情況,影像模糊不是因為過窄的強度範圍,而是某區間的像素強度比例過高,這時可以製作一個映射表,使得調整之後的影像,...
  • Liuqz2009
  • Liuqz2009
  • 2017年03月08日 10:29
  • 121

图像检索:CIE Lab三维直方图+卡方距离

图像检索:Lab三维直方图+卡方距离
  • wxcdzhangping
  • wxcdzhangping
  • 2014年08月04日 17:08
  • 3068

surfaceview-自定義畫圖或顯示圖片

package com.example.mysurfaceview; import android.os.Bundle; import android.app.Activity; import a...
  • yqj234
  • yqj234
  • 2016年06月28日 19:20
  • 252
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:OpenCV學習心得(8) -- 直方圖的顯示
举报原因:
原因补充:

(最多只允许输入30个字)