W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
在本教程中,您將學(xué)習(xí)如何:
我們可以保持落在每個(gè)范圍內(nèi)的像素?cái)?shù)量。將其應(yīng)用于上述示例,我們得到下面的圖像(x軸表示bins和軸y表示每個(gè)像素的數(shù)目)。
如果你想計(jì)算兩個(gè)功能怎么辦?在這種情況下,您生成的直方圖將是一個(gè)3D圖(其中x和y將為和 ,而z將每個(gè)組合的計(jì)數(shù)。這同樣適用于更多的功能(當(dāng)然會(huì)變得更棘手)。
為了簡(jiǎn)單起見(jiàn),OpenCV實(shí)現(xiàn)了函數(shù)cv :: calcHist,它計(jì)算一組數(shù)組(通常是圖像或圖像平面)的直方圖。它最多可以操作32個(gè)維度。我們將在下面的代碼中看到它!
#include "opencv2/highgui.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
Mat src, dst;
String imageName( "../data/lena.jpg" ); // by default
if (argc > 1)
{
imageName = argv[1];
}
src = imread( imageName, IMREAD_COLOR );
if( src.empty() )
{ return -1; }
vector<Mat> bgr_planes;
split( src, bgr_planes );
int histSize = 256;
float range[] = { 0, 256 } ;
const float* histRange = { range };
bool uniform = true; bool accumulate = false;
Mat b_hist, g_hist, r_hist;
calcHist( &bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate );
calcHist( &bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate );
calcHist( &bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate );
// Draw the histograms for B, G and R
int hist_w = 512; int hist_h = 400;
int bin_w = cvRound( (double) hist_w/histSize );
Mat histImage( hist_h, hist_w, CV_8UC3, Scalar( 0,0,0) );
normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
normalize(r_hist, r_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(b_hist.at<float>(i-1)) ) ,
Point( bin_w*(i), hist_h - cvRound(b_hist.at<float>(i)) ),
Scalar( 255, 0, 0), 2, 8, 0 );
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at<float>(i-1)) ) ,
Point( bin_w*(i), hist_h - cvRound(g_hist.at<float>(i)) ),
Scalar( 0, 255, 0), 2, 8, 0 );
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at<float>(i-1)) ) ,
Point( bin_w*(i), hist_h - cvRound(r_hist.at<float>(i)) ),
Scalar( 0, 0, 255), 2, 8, 0 );
}
namedWindow("calcHist Demo", WINDOW_AUTOSIZE );
imshow("calcHist Demo", histImage );
waitKey(0);
return 0;
}
Mat src,dst;
src = imread( argv[1], 1 );
if( !src.data )
{ return -1; }
vector<Mat> bgr_planes;
split( src, bgr_planes );
我們的輸入是要分割的圖像(這種情況下有三個(gè)通道),輸出是Mat的向量)
建立箱數(shù)(5,10 ...):
int histSize = 256; //from 0 to 255
設(shè)置值的范圍(如我們所說(shuō),在0到255之間)
float range[] = { 0, 256 } ; //the upper boundary is exclusive
const float* histRange = { range };
我們希望我們的箱子具有相同的尺寸(均勻),并在開(kāi)始時(shí)清除直方圖,所以:
bool uniform = true ; bool accumulate = false ;
最后,我們創(chuàng)建Mat對(duì)象來(lái)保存直方圖。創(chuàng)建3(每個(gè)planes一個(gè)):
Mat b_hist,g_hist,r_hist;
我們繼續(xù)使用OpenCV函數(shù)cv :: calcHist計(jì)算直方圖:
calcHist(&bgr_planes [0],1,0,Mat(),b_hist,1,&histSize,&histRange,uniform,accumulate);
calcHist(&bgr_planes [1],1,0,Mat(),g_hist,1,&histSize,&histRange,uniform,accumulate);
calcHist(&bgr_planes [2],1,0,Mat(),r_hist,1,&histSize,&histRange,uniform,accumulate);
其中的論點(diǎn)是:
// Draw the histograms for R, G and B
int hist_w = 512; int hist_h = 400;
int bin_w = cvRound( (double) hist_w/histSize );
Mat histImage( hist_h, hist_w, CV_8UC3, Scalar( 0,0,0) );
normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
此函數(shù)接收這些參數(shù):
for( int i = 1; i < histSize; i++ )
{
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at<float>(i-1)) ) ,
Point( bin_w*(i), hist_h - cvRound(b_hist.at<float>(i)) ),
Scalar( 255, 0, 0), 2, 8, 0 );
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at<float>(i-1)) ) ,
Point( bin_w*(i), hist_h - cvRound(g_hist.at<float>(i)) ),
Scalar( 0, 255, 0), 2, 8, 0 );
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at<float>(i-1)) ) ,
Point( bin_w*(i), hist_h - cvRound(r_hist.at<float>(i)) ),
Scalar( 0, 0, 255), 2, 8, 0 );
}
我們使用表達(dá)式:
b_hist.at < float >(i)
其中 i 表示尺寸。如果它是一個(gè)二維直方圖,我們將使用如下:
b_hist.at<float>( i, j )
最后我們顯示直方圖,等待用戶退出:
namedWindow("calcHist Demo", WINDOW_AUTOSIZE );
imshow("calcHist Demo", histImage );
waitKey(0);
return 0;
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: