Opencv繪制HSV顏色直方圖
一. 使用Opencv繪制HSV顏色直方圖
所用的函數
cvCvtColor
可在: 使用Opencv將RGB顏色空間轉換到HSV顏色空間/灰度圖 文章中查找相關介紹
所使用的結構體:
CvHistogram
以及函數:
cvCalcHist
CvCreateHist
cvGetMinMaxHistValue
cvConvertScale
cvReleaseHist
可在: 使用Opencv繪制灰度直方圖/對比 文章中查找對應的函數介紹
1. 開始編寫代碼
準備一張實驗圖
如有需要,自行保存到本地,JPG格式!
1.1 打開測試圖
1.2 創建三個用來分別繪制H,S,V的直方圖
//打開測試圖
IplImage * image = cvLoadImage("D:\\2.jpg", 1); //將本地測試圖導入到程序堆中
if (image == NULL){ //判斷是否打開成功
printf("錯誤:無法打開該圖像,圖像文件路徑不正確!");
return -1;
}
1.3 RGB顏色空間到HSV顏色空間轉換
//創建一張空白圖像用于存儲轉換成HSV顏色空間后的圖像
IplImage *image1 = cvCreateImage(cvSize(image->width, image->height), image->depth, image->nChannels); //注意圖像必須和輸入圖像的size,顏色位深度,通道一致
cvZero(image1); //清空image_data數據
//顏色空間轉換
cvCvtColor(image, image1, CV_BGR2HSV);//CV_BGR2HSV
1.4 創建存儲HSV通道圖像
//創建存儲HSV通道圖像
IplImage *image_h = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必須是單通道圖像
IplImage *image_s = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必須是單通道圖像
IplImage *image_v = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必須是單通道圖像
1.5 分離通道
//分離通道
cvSplit(image, image_h, image_s, image_v, NULL); //注意Opencv中hsv沒有順序問題
1.6 創建通道直方圖//創建H通道的直方圖
int arr_size_h = 255; //定義一個變量用于表示直方圖行寬
float hranges_arr_h[] = { 0, 180 }; //圖像方塊范圍數組
float *phranges_arr_h = hranges_arr_h; //cvCreateHist參數是一個二級指針,所以要用指針指向數組然后傳參
CvHistogram *hist_h = cvCreateHist(1, &arr_size_h, CV_HIST_ARRAY, &phranges_arr_h, 1); //創建一個一維的直方圖,行寬為255,多維密集數組,方塊范圍為0-180,bin均化
//創建S通道的直方圖
int arr_size_s = 255; //定義一個變量用于表示直方圖行寬
float hranges_arr_s[] = { 0, 255 }; //圖像方塊范圍數組
float *phranges_arr_s = hranges_arr_s; //cvCreateHist參數是一個二級指針,所以要用指針指向數組然后傳參
CvHistogram *hist_s = cvCreateHist(1, &arr_size_s, CV_HIST_ARRAY, &phranges_arr_s, 1); //創建一個一維的直方圖,行寬為255,多維密集數組,方塊范圍為0-255,bin均化
//創建V通道的直方圖
int arr_size_v = 255; //定義一個變量用于表示直方圖行寬
float hranges_arr_v[] = { 0, 255 }; //圖像方塊范圍數組
float *phranges_arr_v = hranges_arr_v; //cvCreateHist參數是一個二級指針,所以要用指針指向數組然后傳參
CvHistogram *hist_v = cvCreateHist(1, &arr_size_v, CV_HIST_ARRAY, &phranges_arr_v, 1); //創建一個一維的直方圖,行寬為255,多維密集數組,方塊范圍為0-255,bin均化
1.7 計算通道直方圖大小
//計算H通道的直方圖大小
cvCalcHist(&image_h, hist_h, 0, 0);
//計算S通道的直方圖大小
cvCalcHist(&image_s, hist_s, 0, 0);
//計算V通道的直方圖大小
cvCalcHist(&image_v, hist_v, 0, 0);
1.8 直方圖縮小
//H通道的直方圖縮小
float max_val_h; //用于存儲獲取到的最大值
cvGetMinMaxHistValue(hist_h, 0, &max_val_h, 0, 0); //獲取直方圖最大值
cvConvertScale(hist_h->bins, hist_h->bins, max_val_h ? 180 / max_val_h : 0., 0); //按比例縮小直方圖
//S通道的直方圖縮小
float max_val_s; //用于存儲獲取到的最大值
cvGetMinMaxHistValue(hist_s, 0, &max_val_s, 0, 0); //獲取直方圖最大值
cvConvertScale(hist_s->bins, hist_s->bins, max_val_s ? 255 / max_val_s : 0., 0); //按比例縮小直方圖
//V通道的直方圖縮小
float max_val_v; //用于存儲獲取到的最大值
cvGetMinMaxHistValue(hist_v, 0, &max_val_v, 0, 0); //獲取直方圖最大值
cvConvertScale(hist_v->bins, hist_v->bins, max_val_v ? 255 / max_val_v : 0., 0); //按比例縮小直方圖
1.9 繪制直方圖//創建一個空白圖像用于繪制直方圖
IplImage *histimg = cvCreateImage(cvSize(320, 200), 8, 3);
cvZero(histimg); //清空histimag-imagedata數據
//開始繪制H通道的直方圖
int bin_h;
bin_h = histimg->width / arr_size_h; //得到開始繪制點位置
for (int i = 0; i < arr_size_h; i++)
{
double val = (cvGetReal1D(hist_h->bins, i)*histimg->height / 360);//獲取矩陣元素值,并轉換為對應高度
CvScalar color = CV_RGB(255, 0, 0);
cvRectangle(histimg, cvPoint(i*bin_h, histimg->height), cvPoint((i + 1)*bin_h, (int)(histimg->height - val)), color, 1, 8, 0);
}
//創建一個空白圖像用于繪制直方圖
IplImage *sistimg = cvCreateImage(cvSize(320, 200), 8, 3);
cvZero(sistimg); //清空histimag-imagedata數據
//開始繪制S通道的直方圖
int bin_s;
bin_s = sistimg->width / arr_size_s; //得到開始繪制點位置
for (int i = 0; i < arr_size_s; i++)
{
double val = (cvGetReal1D(hist_s->bins, i)*sistimg->height / 255);//獲取矩陣元素值,并轉換為對應高度
CvScalar color = CV_RGB(0, 255, 0);
cvRectangle(sistimg, cvPoint(i*bin_s, sistimg->height), cvPoint((i + 1)*bin_s, (int)(sistimg->height - val)), color, 1, 8, 0);
}
//創建一個空白圖像用于繪制直方圖
IplImage *vistimg = cvCreateImage(cvSize(320, 200), 8, 3);
cvZero(vistimg); //清空histimag-imagedata數據
//開始繪制V通道的直方圖
int bin_v;
bin_v = vistimg->width / arr_size_v; //得到開始繪制點位置
for (int i = 0; i < arr_size_v; i++)
{
double val = (cvGetReal1D(hist_v->bins, i)*vistimg->height / 255);//獲取矩陣元素值,并轉換為對應高度
CvScalar color = CV_RGB(0, 0, 255);
cvRectangle(vistimg, cvPoint(i*bin_v, vistimg->height), cvPoint((i + 1)*bin_v, (int)(vistimg->height - val)), color, 1, 8, 0);
}
2.0 顯示圖像
//顯示圖像
cvNamedWindow("image_hsv",0);
cvNamedWindow("H",0);
cvNamedWindow("S",0);
cvNamedWindow("V",0);
cvShowImage("image_hsv", image1);
cvShowImage("H", histimg);
cvShowImage("S", sistimg);
cvShowImage("V", vistimg);
cvWaitKey(0);//message
運行結果:完整代碼:
//打開測試圖
IplImage * image = cvLoadImage("D:\\3.jpg", 1); //將本地測試圖導入到程序堆中
if (image == NULL){ //判斷是否打開成功
printf("錯誤:無法打開該圖像,圖像文件路徑不正確!");
return -1;
}
//RGB顏色空間到HSV顏色空間
//創建一張空白圖像用于存儲轉換成HSV顏色空間后的圖像
IplImage *image1 = cvCreateImage(cvSize(image->width, image->height), image->depth, image->nChannels); //注意圖像必須和輸入圖像的size,顏色位深度,通道一致
cvZero(image1); //清空image_data數據
//顏色空間轉換
cvCvtColor(image, image1, CV_BGR2HSV);//CV_BGR2HSV
//創建存儲HSV通道圖像
IplImage *image_h = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必須是單通道圖像
IplImage *image_s = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必須是單通道圖像
IplImage *image_v = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必須是單通道圖像
//分離通道
cvSplit(image, image_h, image_s, image_v, NULL); //注意Opencv中hsv沒有順序問題
//創建H通道的直方圖
int arr_size_h = 255; //定義一個變量用于表示直方圖行寬
float hranges_arr_h[] = { 0, 180 }; //圖像方塊范圍數組
float *phranges_arr_h = hranges_arr_h; //cvCreateHist參數是一個二級指針,所以要用指針指向數組然后傳參
CvHistogram *hist_h = cvCreateHist(1, &arr_size_h, CV_HIST_ARRAY, &phranges_arr_h, 1); //創建一個一維的直方圖,行寬為255,多維密集數組,方塊范圍為0-180,bin均化
//創建S通道的直方圖
int arr_size_s = 255; //定義一個變量用于表示直方圖行寬
float hranges_arr_s[] = { 0, 255 }; //圖像方塊范圍數組
float *phranges_arr_s = hranges_arr_s; //cvCreateHist參數是一個二級指針,所以要用指針指向數組然后傳參
CvHistogram *hist_s = cvCreateHist(1, &arr_size_s, CV_HIST_ARRAY, &phranges_arr_s, 1); //創建一個一維的直方圖,行寬為255,多維密集數組,方塊范圍為0-255,bin均化
//創建V通道的直方圖
int arr_size_v = 255; //定義一個變量用于表示直方圖行寬
float hranges_arr_v[] = { 0, 255 }; //圖像方塊范圍數組
float *phranges_arr_v = hranges_arr_v; //cvCreateHist參數是一個二級指針,所以要用指針指向數組然后傳參
CvHistogram *hist_v = cvCreateHist(1, &arr_size_v, CV_HIST_ARRAY, &phranges_arr_v, 1); //創建一個一維的直方圖,行寬為255,多維密集數組,方塊范圍為0-255,bin均化
//計算H通道的直方圖大小
cvCalcHist(&image_h, hist_h, 0, 0);
//計算S通道的直方圖大小
cvCalcHist(&image_s, hist_s, 0, 0);
//計算V通道的直方圖大小
cvCalcHist(&image_v, hist_v, 0, 0);
//H通道的直方圖縮小
float max_val_h; //用于存儲獲取到的最大值
cvGetMinMaxHistValue(hist_h, 0, &max_val_h, 0, 0); //獲取直方圖最大值
cvConvertScale(hist_h->bins, hist_h->bins, max_val_h ? 180 / max_val_h : 0., 0); //按比例縮小直方圖
//S通道的直方圖縮小
float max_val_s; //用于存儲獲取到的最大值
cvGetMinMaxHistValue(hist_s, 0, &max_val_s, 0, 0); //獲取直方圖最大值
cvConvertScale(hist_s->bins, hist_s->bins, max_val_s ? 255 / max_val_s : 0., 0); //按比例縮小直方圖
//V通道的直方圖縮小
float max_val_v; //用于存儲獲取到的最大值
cvGetMinMaxHistValue(hist_v, 0, &max_val_v, 0, 0); //獲取直方圖最大值
cvConvertScale(hist_v->bins, hist_v->bins, max_val_v ? 255 / max_val_v : 0., 0); //按比例縮小直方圖
//創建一個空白圖像用于繪制直方圖
IplImage *histimg = cvCreateImage(cvSize(320, 200), 8, 3);
cvZero(histimg); //清空histimag-imagedata數據
//開始繪制H通道的直方圖
int bin_h;
bin_h = histimg->width / arr_size_h; //得到開始繪制點位置
for (int i = 0; i < arr_size_h; i++)
{
double val = (cvGetReal1D(hist_h->bins, i)*histimg->height / 360);//獲取矩陣元素值,并轉換為對應高度
CvScalar color = CV_RGB(255, 0, 0);
cvRectangle(histimg, cvPoint(i*bin_h, histimg->height), cvPoint((i + 1)*bin_h, (int)(histimg->height - val)), color, 1, 8, 0);
}
//創建一個空白圖像用于繪制直方圖
IplImage *sistimg = cvCreateImage(cvSize(320, 200), 8, 3);
cvZero(sistimg); //清空histimag-imagedata數據
//開始繪制S通道的直方圖
int bin_s;
bin_s = sistimg->width / arr_size_s; //得到開始繪制點位置
for (int i = 0; i < arr_size_s; i++)
{
double val = (cvGetReal1D(hist_s->bins, i)*sistimg->height / 255);//獲取矩陣元素值,并轉換為對應高度
CvScalar color = CV_RGB(0, 255, 0);
cvRectangle(sistimg, cvPoint(i*bin_s, sistimg->height), cvPoint((i + 1)*bin_s, (int)(sistimg->height - val)), color, 1, 8, 0);
}
//創建一個空白圖像用于繪制直方圖
IplImage *vistimg = cvCreateImage(cvSize(320, 200), 8, 3);
cvZero(vistimg); //清空histimag-imagedata數據
//開始繪制V通道的直方圖
int bin_v;
bin_v = vistimg->width / arr_size_v; //得到開始繪制點位置
for (int i = 0; i < arr_size_v; i++)
{
double val = (cvGetReal1D(hist_v->bins, i)*vistimg->height / 255);//獲取矩陣元素值,并轉換為對應高度
CvScalar color = CV_RGB(0, 0, 255);
cvRectangle(vistimg, cvPoint(i*bin_v, vistimg->height), cvPoint((i + 1)*bin_v, (int)(vistimg->height - val)), color, 1, 8, 0);
}
//顯示圖像
cvNamedWindow("image_hsv",0);
cvNamedWindow("H",0);
cvNamedWindow("S",0);
cvNamedWindow("V",0);
cvShowImage("image_hsv", image1);
cvShowImage("H", histimg);
cvShowImage("S", sistimg);
cvShowImage("V", vistimg);
cvWaitKey(0);//message
智能推薦
OpenCV直方圖的繪制
OpenCV直方圖的繪制 1.直方圖的繪制 直方圖是通過將整個變量值范圍劃分為小的值范圍,然后計算每個間隔中落入多少個值來創建的。 使用calcHist函數計算直方圖,函數原型: 參數說明 /* * 輸入圖像 * 輸入圖像數 * 數字通道尺寸 * 可選的 掩碼矩陣 * 存儲計算結果 * 直方圖 維度(圖像 取值的 空間維度) * 要計算的 區間數(每個像素值一個區間) * 輸入變量的范圍, 可能的...
opencv 繪制直方圖
一、話說直方圖 說到直方圖,同學們一定會想到統計學里的直方圖(沒有想起來的抓緊去翻下中學數學課本)。所謂直方圖啊,就是把一大坨東西分成好幾部分(橫坐標),然后看看每一部分有多少(縱坐標)。比如說康娜醬的班里要做個人愛好的統計,喜歡跳繩的有5人,喜歡唱歌的有8人,喜歡讀書的有6人,超喜歡康娜醬的有1人(才川同學了解一下)。那么圖像中的直方圖又是個啥子呢?喜歡攝影的同學一定見過。圖像中常見的直方圖是亮...
OpenCV Matplotlib繪制直方圖
繪制直方圖有兩種方法: 使用Matplotlib中的繪圖函數 使用OpenCV自帶的繪圖函數 使用OpenCV自帶函數繪制直方圖比較麻煩,這個不做介紹 Matplotlib中有直方圖繪制函數:matplotlib.pyplot.hist()它可以直接統計并繪制直方圖 單通道–灰度圖 多通道–彩圖 從上邊的直方圖你可以推斷出藍色曲線靠右側的最多(很明顯這些就是天空)...
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 以上述例子,判斷一個生產出...