C++ OpenCV繪制簡易直方圖DrawHistImg
需求說明
在對圖像進(jìn)行處理時,經(jīng)常會有這類需求:想要觀察圖像的直方圖分布,例如灰度圖中0-255區(qū)間數(shù)值的分布情況,從而可以進(jìn)行后續(xù)的操作,如閾值分割二值化、直方圖均衡化等等。本文設(shè)計(jì)了一個能繪制簡易直方圖的簡單函數(shù)DrawHistImg,可以幫助大家快速掌握繪制的原理,可以根據(jù)自己的創(chuàng)意對其進(jìn)行改善和補(bǔ)充。
下面介紹具體實(shí)現(xiàn)流程。
具體流程
1)取圖像的灰度圖,并遍歷統(tǒng)計(jì)0-255各個灰度值所出現(xiàn)的次數(shù)。
cv::Mat src = imread("test.jpg", 0); cv::Mat hist = cv::Mat::zeros(1, 256, CV_32FC1); for (int i = 0; i < src.rows; ++i) { for (int j = 0; j < src.cols; ++j) { hist.at<float>(0, src.at <uchar>(i, j))++; } }
2)定義直方圖圖像histImage,并初始化一些參數(shù)。其中bins是數(shù)值最大值,即255;scale為每個灰度值所對應(yīng)的直方圖寬度;histHeight為直方圖高度最大值,也是直方圖圖像的寬。
cv::Mat histImage = cv::Mat::zeros(540, 1020, CV_8UC1); const int bins = 255; int scale = 4; int histHeight = 540;
3)利用minMaxLoc函數(shù)得出哪個灰度值的出現(xiàn)次數(shù)最高,為歸一化做準(zhǔn)備。
double maxValue; cv::Point2i maxLoc; cv::minMaxLoc(hist, 0, &maxValue, 0, &maxLoc);
4)遍歷hist中每個灰度值,并根據(jù)其出現(xiàn)次數(shù)繪制直方圖,height是歸一化后的高度。
for (int i = 0; i < bins; i++) { float binValue = (hist.at<float>(i)); int height = cvRound(binValue * histHeight / maxValue); cv::rectangle(histImage, cv::Point(i * scale, histHeight), cv::Point((i + 1) * scale - 1, histHeight - height), cv::Scalar(255), -1); }
5)函數(shù)執(zhí)行完畢。?
功能函數(shù)
// 繪制簡易直方圖 cv::Mat DrawHistImg(cv::Mat &src) { cv::Mat hist = cv::Mat::zeros(1, 256, CV_32FC1); for (int i = 0; i < src.rows; ++i) { for (int j = 0; j < src.cols; ++j) { hist.at<float>(0, src.at <uchar>(i, j))++; } } cv::Mat histImage = cv::Mat::zeros(540, 1020, CV_8UC1); const int bins = 255; double maxValue; cv::Point2i maxLoc; cv::minMaxLoc(hist, 0, &maxValue, 0, &maxLoc); int scale = 4; int histHeight = 540; for (int i = 0; i < bins; i++) { float binValue = (hist.at<float>(i)); int height = cvRound(binValue * histHeight / maxValue); cv::rectangle(histImage, cv::Point(i * scale, histHeight), cv::Point((i + 1) * scale - 1, histHeight - height), cv::Scalar(255), -1); } return histImage; }
C++測試代碼
#include <iostream> #include <time.h> #include <opencv2/opencv.hpp> using namespace std; using namespace cv; cv::Mat DrawHistImg(cv::Mat &hist); int main() { cv::Mat src = imread("test.jpg", 0); // 繪制均衡化后直方圖 cv::Mat hrI = DrawHistImg(src); imshow("original", src); imshow("hist", hrI); waitKey(0); return 0; } // 繪制簡易直方圖 cv::Mat DrawHistImg(cv::Mat &src) { cv::Mat hist = cv::Mat::zeros(1, 256, CV_32FC1); for (int i = 0; i < src.rows; ++i) { for (int j = 0; j < src.cols; ++j) { hist.at<float>(0, src.at <uchar>(i, j))++; } } cv::Mat histImage = cv::Mat::zeros(540, 1020, CV_8UC1); const int bins = 255; double maxValue; cv::Point2i maxLoc; cv::minMaxLoc(hist, 0, &maxValue, 0, &maxLoc); int scale = 4; int histHeight = 540; for (int i = 0; i < bins; i++) { float binValue = (hist.at<float>(i)); int height = cvRound(binValue * histHeight / maxValue); cv::rectangle(histImage, cv::Point(i * scale, histHeight), cv::Point((i + 1) * scale - 1, histHeight - height), cv::Scalar(255), -1); } return histImage; }
測試效果
圖1 原圖
圖2 灰度圖
圖3 直方圖
如果函數(shù)有什么可以改進(jìn)完善的地方,非常歡迎大家指出,一同進(jìn)步何樂而不為呢~?
以上就是C++ OpenCV繪制簡易直方圖DrawHistImg的詳細(xì)內(nèi)容,更多關(guān)于C++ OpenCV繪制直方圖的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
關(guān)于PCL出現(xiàn)"無法找到?pcl_commond.dll?文件程序無法執(zhí)行"的問題及解決方法
這篇文章主要介紹了PCL出現(xiàn)"無法找到?pcl_commond.dll?文件程序無法執(zhí)行"的問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07C語言之實(shí)現(xiàn)輾轉(zhuǎn)相除法的兩種方式
這篇文章主要介紹了C語言之實(shí)現(xiàn)輾轉(zhuǎn)相除法的兩種方式,具有很好的參考價值,希望對大家有所幫助,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08C++ const的使用及this指針常方法(面試最愛問的this指針)
這篇文章主要介紹了C++ const的使用,this指針,常方法(面試最愛問的this指針),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04