赞
踩
目录
3.4Bhattacharyya distance 巴氏距离
图像直方图均衡化的实现:
直方图均衡化API:
直方图均衡化案例
- void MyApi::histogramEqualize(Mat& image)
- {
- Mat gray_image,dst;
- cvtColor(image, gray_image, COLOR_BGR2GRAY);
- imshow("灰度图", gray_image);
- equalizeHist(gray_image, dst);
- imshow("直方图均衡化后图像", dst);
- }
上图分别是原图、灰度图、直方图均衡化后的图
- void MyApi::histogram_cal(Mat& image)
- {
- //1.把多通道的图像分离单通道
- vector<Mat> bgr_planes;
- split(image, bgr_planes);
- //imshow("单个通道",bgr_planes[0]);//我们可以输出bgr中的b通道的图像
-
- //2.计算直方图
- int histSize = 256;
- float range[] = { 0,256 };
- const float* histRanges = {range};
- Mat b_hist, g_hist, r_hist;
- calcHist(&bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRanges, true, false);
- calcHist(&bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRanges, true, false);
- calcHist(&bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRanges, true, false);
-
- //归一化:为了避免有些像素值的统计值很大,因此为了方便观察归一化到一定的范围内
- int hist_h = 400;
- int hist_w = 512;
- int bin_w = hist_w / histSize;
- Mat histImage(hist_w, hist_h, CV_8UC3, Scalar(0, 0, 0));
- normalize(b_hist, b_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
- normalize(g_hist, g_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
- normalize(r_hist, r_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
-
- //绘制直方图
- for (int i = 1; i < histSize; i++)
- {
- line(histImage, Point((i - 1) * bin_w, hist_h - cvRound(b_hist.at<float>(i - 1))),
- Point((i)*bin_w, hist_h - cvRound(b_hist.at<float>(i))), Scalar(255, 0, 0), 2, LINE_AA);
- line(histImage, Point((i - 1) * bin_w, hist_h - cvRound(g_hist.at<float>(i - 1))),
- Point((i)*bin_w, hist_h - cvRound(g_hist.at<float>(i))), Scalar(0, 255, 0), 2, LINE_AA);
- line(histImage, Point((i - 1) * bin_w, hist_h - cvRound(r_hist.at<float>(i - 1))),
- Point((i)*bin_w, hist_h - cvRound(r_hist.at<float>(i))), Scalar(0, 0, 255), 2, LINE_AA);
- }
- imshow("彩色图像直方图", histImage);
- }
对于输入的两张图像计算得到直方图H1与H2,归一化到相同的尺度空间(图像大小要一致)然后可以通过计算H1与H2之间的距离得到两个直方图的相似程度,进而比较图像本身的相似程度。openCV提供了比较方法有四种:
opencv4中compareHist中的method是改为如下:
相关性比较(HISTCMP_CORREL)值越接近1,相关性越高;越接近0,相关性越低;
卡方比较(HISTCMP_CHISQR)值越小越接近,为0时相似度最高;
巴氏距离(HISTCMP_BHATTACHARYYA),完全匹配为 0,完全不匹配为1
源文件函数如下:
- string convertToString(double d)//double类型转为string类型
- {
- ostringstream os;
- if (os << d)
- return os.str();
- return "invalid convertsion";
- }
-
- void MyApi::histogram_comp(Mat& image, Mat& test1, Mat& test2)
- {
- //图像颜色空间转到HSV空间
- cvtColor(image, image, COLOR_BGR2HSV);
- cvtColor(test1, test1, COLOR_BGR2HSV);
- cvtColor(test2, test2, COLOR_BGR2HSV);
-
- //设置两个灰度等级
- int h_bins = 50;
- int s_bins = 60;
- int histSize[] = {h_bins,s_bins};
-
- float h_ranges[] = { 0, 180 };
- float s_ranges[] = { 0, 256 };
- const float* ranges[] = {h_ranges,s_ranges};
- int channels[] = { 0,1 };
-
- MatND hist_image;
- MatND hist_test1;
- MatND hist_test2;
-
- //计算直方图
- calcHist(&image, 1, channels, Mat(), hist_image, 2, histSize, ranges, true, false);
- normalize(hist_image, hist_image, 0, 1, NORM_MINMAX, -1, Mat());
-
- calcHist(&test1, 1, channels, Mat(), hist_test1, 2, histSize, ranges, true, false);
- normalize(hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat());
-
- calcHist(&test2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, false);
- normalize(hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat());
-
- //相互比较
- double imageimgae = compareHist(hist_image, hist_image, HISTCMP_CORREL);
- double imagetest1 = compareHist(hist_image, hist_test1, HISTCMP_CORREL);
- double imagetest2 = compareHist(hist_image, hist_test2, HISTCMP_CORREL);
- double test1test2 = compareHist(hist_test1, hist_test2, HISTCMP_CORREL);
- printf("test1与test2比较的相关性指标为:%f", test1test2);
-
- putText(image, convertToString(imageimgae), Point(50, 50), FONT_HERSHEY_COMPLEX,
- 1, Scalar(0, 0, 255), 2, LINE_AA);
- putText(test1, convertToString(imagetest1), Point(50, 50), FONT_HERSHEY_COMPLEX,
- 1, Scalar(0, 0, 255), 2, LINE_AA);
- putText(test2, convertToString(imagetest2), Point(50, 50), FONT_HERSHEY_COMPLEX,
- 1, Scalar(0, 0, 255), 2, LINE_AA);
-
- namedWindow("image", WINDOW_AUTOSIZE);
- namedWindow("test1", WINDOW_AUTOSIZE);
- namedWindow("test2", WINDOW_AUTOSIZE);
-
- imshow("image", image);
- imshow("test1", test1);
- imshow("test2", test2);
-
- }
测试函数如下:
- #include<opencv2/opencv.hpp>
- #include<iostream>
- #include"myApi.h"
- using namespace cv;
- using namespace std;
-
- int main(int argc, char** argv) {
- Mat src = imread("F:\\testImage\\test.png");
- if (src.empty()) {
- printf("could not load image...");
- return -1;
- }
- //如果图像过于大,不能完全显示整张图像可以使用namedWindow()可以实现对图像的自由缩放
- //namedWindow("input_window", WINDOW_FREERATIO);
- //imshow("input_window", src);
- Mat test1 = imread("F:\\testImage\\test1.png");
- Mat test2 = imread("F:\\testImage\\test2.png");
-
- MyApi ma;
- ma.histogram_comp(src,test1,test2);
-
- waitKey(0);
- return 0;
- }
从左到右分别是image与test1比较的相似性、与test2比较的相似性、与image比较的相似性
mixChannels()参数说明:
void mixChannels(
const Mat* src, //输入数组或向量矩阵,所有矩阵的大小和深度必须相同。
size_t nsrcs, //矩阵的数量
Mat* dst, //输出数组或矩阵向量,大小和
深度必须与src[0]相同
size_t ndsts,//矩阵的数量
const int* fromTo,//指定被复制通道与要复制到的位置组成的索引对
size_t npairs //fromTo中索引对的数目
);
- #define INPUT_TITLE "Input Image"
- #define OUTPUT_TITLE "Back Projection"
- #define HIST_TITLE "Histogram"
-
- #include<iostream>
- #include<opencv2\opencv.hpp>
-
- using namespace std;
- using namespace cv;
-
-
-
- /*———————————本代码所需变量定义及初始化——————————— */
- Mat src, hsv_src, hue, backProjectionImg;
- int bins = 12;
- int nchannels[] = { 0,0 };
-
- /*—————————————本代码所需函数声明————————————— */
- void Hist_And_BackProjection(int, void*);
-
-
- int main() {
- /*—————————————全局变量的赋值————————————— */
- //1.图像载入
- src = imread("D:/hand.jpg");
- if (!src.data)
- {
- cout << "ERROR : could not load image.\n";
- return -1;
- }
- //2.将图像转化为HSV图像
- cvtColor(src, hsv_src, CV_BGR2HSV);
-
- //3.创建一个图像
- hue.create(hsv_src.size(), hsv_src.depth());
-
- //窗口命名
- namedWindow(INPUT_TITLE, CV_WINDOW_AUTOSIZE);
- namedWindow(OUTPUT_TITLE, CV_WINDOW_AUTOSIZE);
- namedWindow(HIST_TITLE, CV_WINDOW_AUTOSIZE);
-
- //从输入图像中拷贝某通道到输出图像中特定的通道
- mixChannels(&hsv_src, 1, &hue, 1, nchannels, 1);
-
- //动态调整直方图的 bins ,并做反向投影
- createTrackbar("Histogram Bins", INPUT_TITLE, &bins, 180, Hist_And_BackProjection);
- Hist_And_BackProjection(0, 0);
-
- imshow(INPUT_TITLE, src);
-
- waitKey(0);
- return 0;
- }
-
-
- /*—————————————本代码所需函数实现————————————— */
- void Hist_And_BackProjection(int, void*) {
-
- //局部变量
- float range[] = { 0,180 };
- const float *histRanges = { range };
- int hist_h = 400;
- int hist_w = 400;
- int bin_w = hist_w / bins;
- Mat h_hist;
- Mat histImage(hist_w, hist_h, CV_8UC3, Scalar(0, 0, 0));
-
- //直方图计算及归一化处理
- calcHist(&hue, 1, 0, Mat(), h_hist, 1, &bins, &histRanges, true, false);
- normalize(h_hist, h_hist, 0, 255, NORM_MINMAX, -1, Mat());
-
- //直方图反向投影
- calcBackProject(&hue, 1, 0, h_hist, backProjectionImg, &histRanges, 1, true);
-
- //画直方图分部图
- for (int i = 0; i < bins; i++)
- {
- /*rectangle(histImage,
- Point((i - 1)*bin_w, (hist_h - cvRound(h_hist.at<float>(i - 1)*(400 / 255)))),
- Point(i*bin_w, (hist_h - cvRound(h_hist.at<float>(i)*(400 / 255)))),
- Scalar(0, 0, 255),
- -1);*/
-
- rectangle(histImage,
- Point((i - 1)*bin_w, (hist_h - cvRound(h_hist.at<float>(i - 1)*(400 / 255)))),
- Point(i*bin_w, hist_h),
- Scalar(0, 0, 255),
- -1);
- }
-
- imshow(OUTPUT_TITLE, backProjectionImg);
- imshow(HIST_TITLE, histImage);
-
- }
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。