在OpenCV中,也可以對三通道的圖像,比如BGR,HSV等計算直方圖。方法和計算單通道圖像直方圖相似,下面的代碼描述了如何計算一個BGR三通道圖像的直方圖,需要注意的是,因為是三通道,每個通道取值都是[0,255],是以bin的數目達到了256*256*256,這時如果使用普通三維矩陣輸出直方圖結果,需要很大的空間,是以我們通常使用稀疏矩陣來儲存輸出結果。因為稀疏矩陣隻儲存非零值,這樣可以節省存儲空間。
int main( int argc, char** argv )
{
Mat src, dst;
/// 打開圖像
src = imread( "../lenna.jpg");
if( !src.data )
{ return -1; }
/// 設定bin數目
int histSize[3];
float hranges[2];
const float* ranges[3];
int channels[3];
// BGR彩色直方圖
// 準備一個color直方圖資料, BGR格式
histSize[0]= histSize[1]= histSize[2]= 256;
hranges[0]= 0.0; // BGR分量的範圍
hranges[1]= 255.0;
ranges[0]= hranges; // BGR三個通道都是0-255範圍
ranges[1]= hranges;
ranges[2]= hranges;
channels[0]= 0; // 三通道
channels[1]= 1;
channels[2]= 2;
//結果直方圖
cv::SparseMat histo(3,histSize,CV_32F);
// 計算直方圖
cv::calcHist(&src,
1, // 僅一副圖像的直方圖
channels, // 使用的channel
cv::Mat(), // 沒有使用mask
histo, // 計算的結果
3, // 3D直方圖
histSize, // bin的數量
ranges // BGR像素的範圍
);
SparseMatConstIterator_<float> it = histo.begin<float>(), it_end = histo.end<float>();
double s = 0;
int dims = histo.dims();
int count=0;
for(; it != it_end; ++it)
{
// 列印出稀疏矩陣的值
const SparseMat::Node* n = it.node();
printf("(");
for(int i = 0; i < dims; i++)
printf("%d%s", n->idx[i], i < dims-1 ? ", " : ")");
printf(": %g\n", it.value<float>());
s += *it;
count++;
}
printf("Element sum is %g\n", s);
printf("element num is %d\n", count);
while(1)
waitKey(0);
return 0;
}
程式運作效果如下,可以看到實際上稀疏矩陣中隻存儲了69579項,也就是圖像隻有69579種顔色。
程式代碼:工程FirstOpenCV19