jashliao 用 VC++ 實現 fanfuhan OpenCV 教學017 ~ opencv-017-計算/顯示 彩色/灰階 對應的直方圖
jashliao 用 VC++ 實現 fanfuhan OpenCV 教學017 ~ opencv-017-計算/顯示 彩色/灰階 對應的直方圖
資料來源: https://fanfuhan.github.io/
https://fanfuhan.github.io/2019/03/28/opencv-017/
GITHUB:https://github.com/jash-git/fanfuhan_ML_OpenCV
https://github.com/jash-git/jashliao-implements-FANFUHAN-OPENCV-with-VC
★前言:
★主題:
圖片直方圖:
圖像像素值的特徵、細節、細節豐富、旋轉、縮放不變性等特點,廣泛地深入處理的各個領域,特別是圖像圖像的高分辨率特徵、基於 顏色的圖像檢索以及圖像分類、背部投影。常見的分為
灰階直方圖
顏色(彩色)直方圖
bins是指直方值取值的大小範圍,對於直方像素取值在0~2555之間的,最少有256個bin,此外還可以有16、32、48、128等,256除以bin的大小應該是罐子 倍。
OPENCV計算直方圖函數(calcHist),其介紹如下所列:
void calcHist( const Mat* images, int nimages,const int* channels, InputArray mask,OutputArray hist, int dims, const int* histSize,const float** ranges, bool uniform=true, bool accumulate=false );
1.輸入的圖像數組
2.輸入數組的個數
3.通道數
4.掩碼
5.直方圖
6.直方圖維度
7.直方圖每個維度的尺寸數組
8.每一維數組的範圍
9.直方圖是否是均勻
10.配置階段不清零
★C++
// VC_FANFUHAN_OPENCV017.cpp : 定義主控台應用程式的進入點。 // /* // Debug | x32 通用屬性 | C/C++ | | 一般 | | 其他 Include 目錄 -> C:\opencv\build\include | | 連結器 | |一一般 | | 其他程式庫目錄 -> C:\opencv\build\x64\vc15\lib | | |一輸入 | | 其他相依性 -> opencv_world411d.lib;%(AdditionalDependencies) // Releas | x64 組態屬性 | C/C++ | | 一般 | | 其他 Include 目錄 -> C:\opencv\build\include | | 連結器 | |一般 | | 其他程式庫目錄 -> C:\opencv\build\x64\vc15\lib | | |一輸入 | | 其他相依性 -> opencv_world411.lib;%(AdditionalDependencies) */ #include "stdafx.h" #include <iostream> #include <opencv2/opencv.hpp> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> using namespace std; using namespace cv; void showHistogram(InputArray src, cv::String StrTitle); void pause() { printf("Press Enter key to continue..."); fgetc(stdin); } int main() { Mat src = imread("../../images/test.png"); if (src.empty()) { cout << "could not load image.." << endl; pause(); return -1; } else { imshow("input", src); showHistogram(src,"Histogram"); Mat src_gray; cvtColor(src, src_gray, COLOR_BGR2GRAY); imshow("input_gray", src_gray); showHistogram(src_gray,"Histogram_gray"); waitKey(0); } return 0; } void showHistogram(InputArray src, cv::String StrTitle) { bool blnGray = false; if (src.channels() == 1) { blnGray = true; } // 三通道/單通道 直方圖 紀錄陣列 vector<Mat> bgr_plane; vector<Mat> gray_plane; // 定义参数变量 const int channels[1] = { 0 }; const int bins[1] = { 256 }; float hranges[2] = { 0, 255 }; const float *ranges[1] = { hranges }; Mat b_hist, g_hist, r_hist,hist; // 计算三通道直方图 if (blnGray) { split(src, gray_plane); calcHist(&gray_plane[0], 1, 0, Mat(), hist, 1, bins, ranges); } else { split(src, bgr_plane); calcHist(&bgr_plane[0], 1, 0, Mat(), b_hist, 1, bins, ranges); calcHist(&bgr_plane[1], 1, 0, Mat(), g_hist, 1, bins, ranges); calcHist(&bgr_plane[2], 1, 0, Mat(), r_hist, 1, bins, ranges); } /* * 显示直方图 */ int hist_w = 512; int hist_h = 400; int bin_w = cvRound((double)hist_w / bins[0]); Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3); // 归一化直方图数据 if (blnGray) { normalize(hist, hist, 0, histImage.rows, NORM_MINMAX, -1); } else { normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1); normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1); normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1); } // 绘制直方图曲线 for (int i = 1; i < bins[0]; ++i) { if (blnGray) { line(histImage, Point(bin_w * (i - 1), hist_h - cvRound(hist.at<float>(i - 1))), Point(bin_w * (i), hist_h - cvRound(hist.at<float>(i))), Scalar(255, 255, 255), 2, 8, 0); } else { 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); } } imshow(StrTitle, histImage); }
★Python
import cv2 as cv import numpy as np from matplotlib import pyplot as plt def custom_hist(gray): h, w = gray.shape hist = np.zeros([256], dtype=np.int32) for row in range(h): for col in range(w): pv = gray[row, col] hist[pv] += 1 y_pos = np.arange(0, 256, 1, dtype=np.int32) plt.bar(y_pos, hist, align='center', color='r', alpha=0.5) plt.xticks(y_pos, y_pos) plt.ylabel('Frequency') plt.title('Histogram') # plt.plot(hist, color='r') # plt.xlim([0, 256]) plt.show() def image_hist(image): cv.imshow("input", image) color = ('blue', 'green', 'red') for i, color in enumerate(color): hist = cv.calcHist([image], [i], None, [256], [0, 256]) plt.plot(hist, color=color) plt.xlim([0, 256]) plt.show() src = cv.imread("../images/test.png") cv.namedWindow("input", cv.WINDOW_AUTOSIZE) gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY) cv.imshow("input", gray) #custom_hist(gray) image_hist(src) cv.waitKey(0) cv.destroyAllWindows()
★結果圖:
★延伸說明/重點回顧:
One thought on “jashliao 用 VC++ 實現 fanfuhan OpenCV 教學017 ~ opencv-017-計算/顯示 彩色/灰階 對應的直方圖”
[彩色照片/圖片太暗改善 強化]
彩色影象的直方圖均衡化–基於OpenCV中EqualizeHist_Demo實現
https://www.itread01.com/content/1547194142.html
Python圖像處理介紹-彩色圖像的直方圖處理
https://mp.weixin.qq.com/s/z60MvDl8qoojZWokDsTWyQ
相關文章備份
GIHUB: https://github.com/jash-git/Jash-good-idea-20201029-001