#pragma once using namespace cv; using namespace std; class histogram{ private: int histsize; float range[2]; const float *histrange; int channels[1]; float threshold; public: histogram() { histsize = 256; range[0] = 0; range[1] = 256; histrange = range; channels[0] = 0; threshold = 0; } Mat changeImg(const Mat& img) { //忽略低于边界值的像素值 Mat hsv; cvtColor(img, hsv, CV_BGR2HSV); //转换成HSV vector<Mat> channel; split(hsv, channel); int minVal = 0; int maxVal = 256; float Val = 0; cout << "请输入边界值:" << endl; cin >> Val; for (; minVal < 256; minVal++) { //划定一个值寻找到新的边界范围 if (channel[0].at<uchar>(minVal) > Val) break; channel[0].at<uchar>(minVal) = 0; //把边界之外的像素值忽略 } for (; maxVal >= 0; maxVal--) { if (channel[0].at<uchar>(maxVal) > Val) break; channel[0].at<uchar>(maxVal) = 255; } imshow("channel[0]", channel[0]); Mat result; merge(channel,result); //这里只改变了H通道的值,而输出的是3通道的,所以输出的变化效果不是很明显 return result; } Mat* colhistgram(const Mat & img,const Mat& im) { //计算直方图 Mat result, res; calcHist(&img, 1, channels, Mat(), result, 1, &histsize, &histrange); calcHist(&im, 1, channels, Mat(), res, 1, &histsize, &histrange); Mat *m = new Mat[2]; m[0] = result; m[1] = res; return m; //利用指针同时返回两个值 } Mat colhistgram(const Mat& img) { Mat result; calcHist(&img, 1, channels, Mat(), result, 1, &histsize, &histrange); return result; } void showhistogram(const Mat& img) { //显示直方图 Mat gray; cvtColor(img, gray, CV_BGR2GRAY); //转换成灰度图 Mat result(img.size(), img.depth(), Scalar(0, 0, 0)); //画最后结果的图 colhistgram(gray); int bin_w = img.cols / histsize; //绘制的箱子的宽度与高度 int bin_h = img.rows; for (int i = 0; i < 256; i++) { uchar p = gray.at<uchar>(i); line(result, Point(bin_w*i,bin_h), Point(bin_w*i,bin_h - p), Scalar(123, 123, 0)); } imshow("result",result); } Mat setthreshold(float num) { //设定阈值 threshold = num; } }; class comparatorimg { private: Mat sethist; Mat inputhist; histogram hist; int bins; public: void setbins(int num) { bins = num; } double compatator(const Mat& img, const Mat& im) { //把输入图像和标准参考图像直方图比较,相似累加 //Mat h1, h2; //cvtColor(img, h1, CV_BGR2GRAY); //cvtColor(im, h2, CV_BGR2GRAY); //转为灰度图像对比,值也会相对大很多 //Mat *m = hist.colhistgram(h1, h2); Mat *m = hist.colhistgram(img, im); sethist = m[0]; inputhist = m[1]; return compareHist(sethist, inputhist, CV_COMP_INTERSECT); } };
/* 根据直方图寻找相似图片 */ #include<opencv2\opencv.hpp> #include<iostream> #include"Histogram.h" using namespace cv; using namespace std; int main() { Mat img = imread("D://图片//5.jpg"); Mat img_com = imread("D://图片//0.jpg"); //当此图片大小大于img时相似值是固定的敏感区域的乘积 if (img.empty() || img_com.empty()) return -1; Mat imgROI = img(Rect(0, 0, 120, 100)); comparatorimg h1; histogram h2; double v = h1.compatator(imgROI,img_com); //比较相似度 cout << "相似度为:" << v << endl; Mat tem = h2.changeImg(img); //忽略固定值一下的值处理 imshow("tem",tem); //显示变换后的图像总体效果 h2.showhistogram(tem); //显示变换后的图像的直方图 waitKey(0); destroyAllWindows; return 0; }
运行结果:
灰度比较:
彩色单通道: