索引地址:系列索引
直方图匹配又称为直方图规定化,是指将一幅图像的直方图变成规定形状的直方图而进行的图像增强方法。即将某幅影像或某一区域的直方图匹配到另一幅影像上。使两幅影像的色调保持一致。可以在单波段影像直方图之间进行匹配,也可以对多波段影像进行同时匹配。两幅图像比对前,通常要使其直方图形式一致。
直方图匹配即将某幅影像或某一区域的直方图匹配到另一幅影像上。使两幅影像的色调保持一致。可以在单波段影像直方图之间进行匹配,也可以对多波段影像进行同时匹配。两幅图像比对前,通常要使其直方图形式一致。
当一幅图像被描述为直方图后,所有的空间信息都丢失了。直方图描述了每个灰度级具有的像素个数,但无法为这些像素在图像中的位置提供任何线索。即便如此,直方图仍有一些有用的性质:
(1)一个特定的图像有唯一的直方图,但两幅图像的直方图相同并不能说明图像相同。
(2)在图像中特定对象的直方图是平移不变的。
(3)在图像中特定对象的直方图是旋转不变的。
(4)如果一幅图像由两个不连接的区域组成,且每个区域的直方图已知,则整幅图像的直方图是两个区域的直方图之和。显然,该结论可以推广到任何数目的不连接区域的情形。
直方图均衡化是在一副图内部保持一致,而直方图匹配是保持两幅图一致。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
|
#include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> using namespace cv; using namespace std; int main() { cv::Mat srcImage = cv::imread("1.png"); cv::Mat dstImage = cv::imread("circles.jpg"); if( !srcImage.data || !dstImage.data ) return 1; cv::resize(dstImage, dstImage,cv::Size(srcImage.rows,srcImage.cols),0,0,INTER_LINEAR); cv::imshow("srcImage", srcImage); cv::imshow("dstImage", dstImage); cv::waitKey(0); float srcCdfArr[256]; float dstCdfArr[256]; int srcAddTemp[256]; int dstAddTemp[256]; int histMatchMap[256]; for (int i = 0; i < 256; i++){ srcAddTemp[i] = 0; dstAddTemp[i] = 0; srcCdfArr[i]= 0; dstCdfArr[i] = 0; histMatchMap[i]=0; } float sumSrcTemp = 0; float sumDstTemp = 0; int nSrcPix = srcImage.cols * srcImage.rows; int nDstPix = dstImage.cols * dstImage.rows; int matchFlag = 0; for(size_t nrow = 0; nrow < srcImage.rows; nrow++) for(size_t ncol = 0; ncol < srcImage.cols; ncol++) { srcAddTemp[(int)srcImage.at<uchar>(nrow, ncol)]++; dstAddTemp[(int)dstImage.at<uchar>(nrow, ncol)]++; } for(int i=0; i<256; i++) { sumSrcTemp += srcAddTemp[i]; srcCdfArr[i] = sumSrcTemp / nSrcPix; sumDstTemp += dstAddTemp[i]; dstCdfArr[i] = sumDstTemp / nDstPix; } for(int i=0; i< 256; i++) { float minMatchPara = 20; for(int j=0; j< 256; j++) { if (minMatchPara > abs(srcCdfArr[i] - dstCdfArr[j])) { minMatchPara = abs(srcCdfArr[i] - dstCdfArr[j]); matchFlag = j; } } histMatchMap[i] = matchFlag; } cv::Mat HistMatchImage = cv::Mat::zeros(srcImage.rows, srcImage.cols, CV_8UC3); cv::cvtColor(srcImage, HistMatchImage, cv::COLOR_BGR2GRAY); for(int i = 0; i < HistMatchImage.rows; i++) for(int j = 0; j < HistMatchImage.cols; j++) { HistMatchImage.at<uchar>(i, j) = histMatchMap[(int)HistMatchImage.at<uchar>(i, j)]; }
cv::imshow("resultImage", HistMatchImage); cv::waitKey(0); return 0; }
|
效果为