openCV學習筆記十三:直方圖計算及繪制
標簽: openCV直方圖計算及繪制 openCV 機器視覺
直方圖是對數據進行統計的一種方式,可以直觀表現圖像某屬性數值的一種方式。
1.計算直方圖——calcHist()
void calcHist(const Mat* arrays, int narrays, const int* channels, InputArray mask, SparseMat&hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=
false );
arrays。輸入的圖像的指針,可以是多幅圖像,所有的圖像必須有同樣的深度(CV_8U or CV_32F)。同時一副圖像可以有多個channes。
narrays。輸入的圖像的個數。
channels。用來計算直方圖的channes的數組。比如輸入是2副圖像,第一副圖像有0,1,2共三個channel,第二幅圖像只有0一個channel,
那么輸入就一共有4個channes,如果int channels[3] = {3, 2, 0},那么就表示是使用第二副圖像的第一個通道和第一副圖像的第2和第0個通道來計
算直方圖。
mask。掩碼。如果mask不為空,那么它必須是一個8位(CV_8U)的數組,并且它的大小的和arrays[i]的大小相同,值為1的點將用來計算
直方圖。
hist。計算出來的直方圖
dims。計算出來的直方圖的維數。
histSize。在每一維上直方圖的個數。簡單把直方圖看作一個一個的豎條的話,就是每一維上豎條的個數。
ranges。用來進行統計的范圍。比如
float rang1[] = {0, 20};
float rang2[] = {30, 40};
const float *rangs[] = {rang1, rang2};那么就是對0,20和30,40范圍的值進行統計。
uniform。每一個豎條的寬度是否相等。
2.完成了三種直方圖的繪制:一維灰度直方圖;一維灰度直方圖(不均勻);BGR三色直方圖;
// A code block
var foo = 'bar';
一維灰度直方圖代碼如下
#include <cv.h>
#include <highgui.h>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
Mat srcImg = imread("1.jpg", CV_LOAD_IMAGE_GRAYSCALE);
int nimages = 1;//圖像的個數
int channels = 0;//需要統計通道的索引
Mat mask = Mat();
Mat histImg;//存放輸出的直方圖
int dims = 1;//需要計算的直方圖的維度
int histSize = 256;//計算的直方圖的分組數
float range[] = { 0, 256 };//表示直方圖每一維度的取值范圍[0,256)
const float* ranges[] = { range };//參數形式需要,表示每一維度數值的取值范圍
calcHist(&srcImg,nimages,&channels,mask,histImg,dims,&histSize,ranges);//計算直方圖
//2.繪制直方圖
double minValue = 0;
double maxValue = 0;
minMaxLoc(histImg,&minValue,&maxValue);//得到計算出的直方圖中的最小值和最大值
int width = histSize;//定義繪制直方圖的寬度,令其等于histSize
int height = 400;//定義繪制直方圖的高度
Mat dstImg = Mat::zeros(Size(width,height),CV_8UC3);//寬為histSize,高為height
for (int i = 0; i < histSize;i++)//遍歷histImg
{
float binValue = histImg.at<float>(i);//得到histImg中每一分組的值
}
imshow("srcImg",srcImg);
imshow("Histogram", dstImg);
waitKey(0);
cout <<"i: "<<i<<" ,binValue: "<<binValue<< endl;
float realValue = (binValue / maxValue)*height;//歸一化數據,縮放到圖像的height之內
cout << "i: " << i << " ,realValue: " << realValue << endl; //用直線方法繪制直方圖,注意兩端點坐標的計算
line(dstImg, Point(i, height - 1), Point(i, height - 1 - realValue), Scalar(255,0,0), 1);
return 0;
}
運行結果如下:
// A code block
var foo = 'bar';
一維灰度直方圖(不均勻)代碼如下
#include <cv.h>
#include <highgui.h>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
///一維灰度直方圖(不均勻)
//1.計算直方圖
Mat srcImg = imread("1.jpg", CV_LOAD_IMAGE_GRAYSCALE);
int nimages = 1;//圖像的個數
int channels = 0;//需要統計通道的索引
Mat mask = Mat(); Mat histImg;//存放輸出的直方圖
int dims = 1;//需要計算的直方圖的維度
int histSize = 5;//計算的直方圖的分組數
float range[] = { 0, 50,100,150,200,256 };//表示直方圖每一維度的取值范圍
const float* ranges[] = { range };//參數形式需要,表示每一維度數值的取值范圍 //計算直方圖,注意最后的直方圖是否均勻的標識符置為false
calcHist(&srcImg, nimages, &channels, mask, histImg, dims, &histSize, ranges,false);
//2.繪制直方圖
double minValue = 0;
double maxValue = 0;
minMaxLoc(histImg, &minValue, &maxValue);//得到計算出的直方圖中的最小值和最大值
int width = 400;//定義繪制直方圖的寬度
int height = 400;//定義繪制直方圖的高度
Mat dstImg = Mat::zeros(Size(width, height), CV_8UC3);//寬為histSize,高為height
for (int i = 0; i < histSize; i++)//遍歷histImg
{
float binValue = histImg.at<float>(i);//得到histImg中每一分組的值
cout << "i: " << i << " ,binValue: " << binValue << endl;
float realValue = (binValue / maxValue)*height;//歸一化數據,縮放到圖像的height之內
cout << "i: " << i << " ,realValue: " << realValue << endl; //用矩形方法繪制直方圖,注意左上點和右下點坐標的計算
rectangle(dstImg,Point(40*i,height-1-realValue),Point(40*i+20,height-1),Scalar(255,0,0),-1);
}
imshow("srcImg", srcImg);
imshow("Histogram", dstImg);
waitKey(0);
return 0;
}
運行結果如下:
// A code block
var foo = 'bar';
BGR三色直方圖代碼
#include <cv.h>
#include <highgui.h>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
///BGR三色直方圖繪制
//1.計算BGR三個通道的直方圖
Mat srcImg = imread("1.jpg",CV_LOAD_IMAGE_COLOR);
int nimages = 1;//圖像的個數
Mat mask = Mat();
int dims = 1;//需要計算的直方圖的維度
int histSize = 256;//計算的直方圖的分組數
float range[] = { 0, 256 };
const float* ranges[] = { range };//參數形式需要,表示直方圖每一維度的取值范圍
Mat histImg_B;//存放輸出的藍色通道的直方圖
int channels_B = 0;//藍色通道的索引
calcHist(&srcImg, nimages, &channels_B, mask, histImg_B, dims, &histSize, ranges);//計算藍色通道直方圖
Mat histImg_G;//存放輸出的綠色通道的直方圖
int channels_G = 1;//綠色通道的索引
calcHist(&srcImg, nimages, &channels_G, mask, histImg_G, dims, &histSize, ranges);//計算綠色通道直方圖
Mat histImg_R;//存放輸出的紅色通道的直方圖
int channels_R = 2;//紅色通道的索引
calcHist(&srcImg, nimages, &channels_R, mask, histImg_R, dims, &histSize, ranges);//計算紅色通道直方圖
//2.繪制BGR三個通道的直方圖
double minValue_B = 0;
double maxValue_B = 0;
minMaxLoc(histImg_B,&minValue_B,&maxValue_B);//得到藍色通道直方圖中的最小值和最大值
double minValue_G = 0;
double maxValue_G = 0;
minMaxLoc(histImg_G, &minValue_G, &maxValue_G);//得到綠色通道直方圖中的最小值和最大值
double minValue_R = 0; double maxValue_R = 0;
minMaxLoc(histImg_R, &minValue_R, &maxValue_R);//得到紅色通道直方圖中的最小值和最大值
int width = histSize;//定義繪制直方圖的寬度,令其等于histSize
int height = 400;//定義繪制直方圖的高度
Mat dstImg = Mat::zeros(Size(3*histSize,height),CV_8UC3);//寬為3*histSize,高為height
for (int i = 0; i < histSize;i++)//遍歷histImg
{ //繪制藍色通道直方圖
float binValue_B = histImg_B.at<float>(i);//得到histImg中每一分組的值
cout <<"i: "<<i<<" ,binValue_B: "<<binValue_B<< endl;
float realValue_B = (binValue_B / maxValue_B)*height;//歸一化數據,縮放到圖像的height之內
cout << "i: " << i << " ,realValue_B: " << realValue_B << endl; //用直線方法繪制直方圖,注意兩端點坐標的計算
line(dstImg, Point(i, height - 1), Point(i, height - 1 - realValue_B), Scalar(255,0,0), 1); //繪制綠色通道直方圖
float binValue_G = histImg_G.at<float>(i);//得到histImg中每一分組的值
cout << "i: " << i << " ,binValue_G: " << binValue_G << endl;
float realValue_G = (binValue_G / maxValue_G)*height;//歸一化數據,縮放到圖像的height之內
cout << "i: " << i << " ,realValue_G: " << realValue_G << endl; //用直線方法繪制直方圖,兩端點橫坐標在之前的基礎上加上histSize
line(dstImg, Point(i + histSize, height - 1), Point(i + histSize, height - 1 - realValue_G), Scalar(0, 255, 0), 1); //繪制紅色通道直方圖
float binValue_R = histImg_R.at<float>(i);//得到histImg中每一分組的值
cout << "i: " << i << " ,binValue_R: " << binValue_R << endl;
float realValue_R = (binValue_R / maxValue_R)*height;//歸一化數據,縮放到圖像的height之內
cout << "i: " << i << " ,realValue_R: " << realValue_R << endl; //用直線方法繪制直方圖,兩端點橫坐標在之前的基礎上加上2*histSize
line(dstImg, Point(i + 2 * histSize, height - 1), Point(i + 2 * histSize, height - 1 - realValue_R), Scalar(0, 0, 255), 1);
}
namedWindow("srcImg", CV_WINDOW_NORMAL);//定義一個窗口,CV_WINDOW_NORMAL大小可調整
imshow("srcImg", srcImg);
namedWindow("BGR Histogram", CV_WINDOW_NORMAL);//定義一個窗口,CV_WINDOW_NORMAL大小可調整
imshow("BGR Histogram", dstImg);
waitKey(0);
return 0;
}
運行結果如下:
智能推薦
OpenCV Java 圖像直方圖均衡化及直方圖繪制
什么是直方圖均衡化 直方圖均衡化通常用來增加圖像的全局對比度,尤其是當圖像的有用數據的對比度相當接近的時候。通過這種方法,亮度可以更好地在直方圖上分布。這樣就可以用于增強局部的對比度而不影響整體的對比度,直方圖均衡化通過有效地擴展常用的亮度來實現這種功能。 這種方法對于背景和前景都太亮或者太暗的圖像非常有用,這種方法尤其是可以帶來X光圖像中更好的骨骼結構顯示以及曝光過度或者曝光不足照片中更好的細節...
openCV學習筆記(十)-- 直方圖
1.什么是直方圖? 舉個例子: 2.直方圖均衡化 代碼: 3.計算直方圖及繪制直方圖 具體使用: 在完成以上步驟后,就可以通過API畫出一個分別對于BGR三通道的直方圖 4.直方圖比較 具體直方圖對比步驟: 具體代碼: 5.直方圖反向映射 https://blog.csdn.net/keith_bb/article/details/70154219...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
猜你喜歡
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...
Linux C系統編程-線程互斥鎖(四)
互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...
統計學習方法 - 樸素貝葉斯
引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...