【OpenCV學習筆記】二十二、直方圖計算及繪製(二)

直方圖計算及繪製(二)

1.直方圖均衡化——equalizeHist()

2.直方圖對比——compareHist()

3.完成了幾個應用:灰度圖像直方圖均衡化、彩色圖像直方圖均衡化、直方圖對比、反向投影(待補)。

先上ppt:






















代碼:

1.灰度圖像直方圖均衡化

///灰度圖像直方圖均衡化
#include "opencv2/opencv.hpp"
using namespace cv;
#include <iostream>
using namespace std;
int main()
{
	//1.灰度直方圖均衡化
	Mat srcImg = imread("06.jpg",CV_LOAD_IMAGE_GRAYSCALE);//直方圖均衡化需爲8位單通道圖像
	Mat dstImg;
	equalizeHist(srcImg,dstImg);
	imshow("srcImg",srcImg);
	imshow("dstImg",dstImg);
	//2.畫出源圖srcImg和目標圖像dstImg的直方圖
	//2.1計算直方圖
	int nimages = 1;//圖像的個數
	int channels = 0;//需要統計通道的索引
	Mat mask = Mat();
	Mat histImg_src;//存放srcImg輸出的直方圖
	Mat histImg_dst;//存放dstImg輸出的直方圖
	int dims = 1;//需要計算的直方圖的維度
	int histSize = 256;//計算的直方圖的分組數
	float range[] = { 0, 256 };//表示直方圖每一維度的取值範圍[0,256)
	const float* ranges[] = { range };//參數形式需要,表示每一維度數值的取值範圍
	calcHist(&srcImg, nimages, &channels, mask, histImg_src, dims, &histSize, ranges);//計算srcImg直方圖
	calcHist(&dstImg, nimages, &channels, mask, histImg_dst, dims, &histSize, ranges);//計算dstImg直方圖
	//2.2繪製直方圖
	//2.2.1繪製srcImg的直方圖
	double minValue = 0;
	double maxValue = 0;
	minMaxLoc(histImg_src, &minValue, &maxValue);//得到計算出的直方圖中的最小值和最大值
	int width = histSize;//定義繪製直方圖的寬度,令其等於histSize
	int height = 400;//定義繪製直方圖的高度
	Mat histShow_src = Mat::zeros(Size(width, height), CV_8UC3);//寬爲histSize,高爲height
	for (int i = 0; i < histSize; i++)//遍歷histImg
	{
		float binValue = histImg_src.at<float>(i);//得到histImg中每一分組的值
		cout << "i: " << i << " ,binValue: " << binValue << endl;
		float realValue = (binValue / maxValue)*height;//歸一化數據,縮放到圖像的height之內
		cout << "i: " << i << " ,realValue: " << realValue << endl;
		//用直線方法繪製直方圖,注意兩端點座標的計算
		line(histShow_src, Point(i, height - 1), Point(i, height - 1 - realValue), Scalar(255, 0, 0), 1);
	}
	namedWindow("srcHist", CV_WINDOW_NORMAL);
	imshow("srcHist", histShow_src);
	//2.2.2繪製dstImg的直方圖
	double minValue_dst = 0;
	double maxValue_dst = 0;
	minMaxLoc(histImg_dst, &minValue_dst, &maxValue_dst);//得到計算出的直方圖中的最小值和最大值
	Mat histShow_dst = Mat::zeros(Size(width, height), CV_8UC3);//寬爲histSize,高爲height
	for (int i = 0; i < histSize; i++)//遍歷histImg
	{
		float binValue = histImg_dst.at<float>(i);//得到histImg中每一分組的值
		cout << "i: " << i << " ,binValue: " << binValue << endl;
		float realValue = (binValue / maxValue_dst)*height;//歸一化數據,縮放到圖像的height之內
		cout << "i: " << i << " ,realValue: " << realValue << endl;
		//用直線方法繪製直方圖,注意兩端點座標的計算
		line(histShow_dst, Point(i, height - 1), Point(i, height - 1 - realValue), Scalar(255, 0, 0), 1);
	}
	namedWindow("dstHist",CV_WINDOW_NORMAL);
	imshow("dstHist", histShow_dst);
	waitKey(0);
	return 0;
}
運行結果:


2.彩色圖像直方圖均衡化

///彩色圖像直方圖均衡化
#include "opencv2/opencv.hpp"
using namespace cv;
#include <iostream>
using namespace std;
int main()
{
	Mat srcImg = imread("horse.png",CV_LOAD_IMAGE_COLOR);
	Mat dstImg;
	//1.BGR通道分離——split()
	vector<Mat> channels;
	split(srcImg,channels);
	Mat channelBlue = channels.at(0);
	Mat channelGreen = channels.at(1);
	Mat channelRed = channels.at(2);
	//2.對BGR通道分別進行直方圖均衡化——equalizeHist()
	equalizeHist(channelBlue, channelBlue);
	equalizeHist(channelGreen, channelGreen);
	equalizeHist(channelRed, channelRed);
	//3.BGR通道融合——merge()
	merge(channels,dstImg);
	namedWindow("srcImg",CV_WINDOW_NORMAL);
	imshow("srcImg", srcImg);
	namedWindow("dstImg", CV_WINDOW_NORMAL);
	imshow("dstImg", dstImg);
	waitKey(0);
	return 0;
}
運行結果:


3.直方圖對比

///直方圖對比
#include "opencv2/opencv.hpp"
using namespace cv;
#include <iostream>
using namespace std;
int main()
{
	Mat srcImg1 = imread("A.JPG",CV_LOAD_IMAGE_COLOR);
	Mat srcImg2 = imread("B.JPG", CV_LOAD_IMAGE_COLOR);
	//1.計算srcImg1和srcImg2的直方圖
	int nimages = 1;//圖像的個數
	int channels = 0;//需要統計通道的索引
	Mat mask = Mat();
	Mat histImg1;//存放srcImg1輸出的直方圖
	Mat histImg2;//存放srcImg2輸出的直方圖
	int dims = 1;//需要計算的直方圖的維度
	int histSize = 256;//計算的直方圖的分組數
	float range[] = { 0, 256 };//表示直方圖每一維度的取值範圍[0,256)
	const float* ranges[] = { range };//參數形式需要,表示每一維度數值的取值範圍
	calcHist(&srcImg1, nimages, &channels, mask, histImg1, dims, &histSize, ranges);//計算srcImg1直方圖
	calcHist(&srcImg2, nimages, &channels, mask, histImg2, dims, &histSize, ranges);//計算srcImg2直方圖
	//2.直方圖對比,注意是依據兩源圖像所計算出的直方圖進行相似度對比.
	double num1 = compareHist(histImg1, histImg2, CV_COMP_CORREL);//相關性方法(值越大匹配度越高)
	double num2 = compareHist(histImg1, histImg2, CV_COMP_CHISQR);//卡方測量法(值越小匹配度越高)
	double num3 = compareHist(histImg1, histImg2, CV_COMP_INTERSECT);//直方圖相交法(值越大匹配度越高)
	double num4 = compareHist(histImg1, histImg2, CV_COMP_BHATTACHARYYA);//Bhattacharyya測量法(小)
	cout << "CV_COMP_CORREL(max_best): " << num1 << endl;
	cout << "CV_COMP_CHISQR(min_best): " << num2 << endl;
	cout << "CV_COMP_INTERSECT(max_best): " << num3 << endl;
	cout << "CV_COMP_BHATTACHARYYA(min_best): " << num4 << endl;
	//3.繪製srcImg1和srcImg2的直方圖
	//3.1繪製srcImg1的直方圖
	double minValue = 0;
	double maxValue = 0;
	minMaxLoc(histImg1, &minValue, &maxValue);//得到計算出的直方圖中的最小值和最大值
	int width = histSize;//定義繪製直方圖的寬度,令其等於histSize
	int height = 400;//定義繪製直方圖的高度
	Mat histShow1 = Mat::zeros(Size(width, height), CV_8UC3);//寬爲histSize,高爲height
	for (int i = 0; i < histSize; i++)//遍歷histImg
	{
		float binValue = histImg1.at<float>(i);//得到histImg中每一分組的值		
		float realValue = (binValue / maxValue)*height;//歸一化數據,縮放到圖像的height之內
		//用直線方法繪製直方圖,注意兩端點座標的計算
		line(histShow1, Point(i, height - 1), Point(i, height - 1 - realValue), Scalar(255, 0, 0), 1);
	}
	namedWindow("srcHist1", CV_WINDOW_NORMAL);
	imshow("srcHist1", histShow1);
	//3.2繪製srcImg2的直方圖
	double minValue2 = 0;
	double maxValue2 = 0;
	minMaxLoc(histImg2, &minValue2, &maxValue2);//得到計算出的直方圖中的最小值和最大值
	Mat histShow2 = Mat::zeros(Size(width, height), CV_8UC3);//寬爲histSize,高爲height
	for (int i = 0; i < histSize; i++)//遍歷histImg
	{
		float binValue = histImg2.at<float>(i);//得到histImg中每一分組的值
		float realValue = (binValue / maxValue2)*height;//歸一化數據,縮放到圖像的height之內
		//用直線方法繪製直方圖,注意兩端點座標的計算
		line(histShow2, Point(i, height - 1), Point(i, height - 1 - realValue), Scalar(255, 0, 0), 1);
	}
	namedWindow("srcHist2",CV_WINDOW_NORMAL);
	imshow("srcHist2", histShow2);
	
	namedWindow("srcImg1", CV_WINDOW_NORMAL);
	imshow("srcImg1", srcImg1);
	namedWindow("srcImg2", CV_WINDOW_NORMAL);
	imshow("srcImg2", srcImg2);
	waitKey(0);
	return 0;
}
運行結果:


4.反向投影(未理解,以後補)




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章