直方图匹配算法,又称直方图规定化。简单说,就是根据某函数、或者另外一张图片的引导,使得原图改变。
感觉解释的最好的是:http://www.360doc.com/content/13/1106/16/10724725_327179043.shtml
完整代码:github (里面同时包含OSTU / 大津算法、直方图均衡化等算法,还包括两种测试图片)。
因为我个人兴趣爱好(放P就是老师逼的。。。),不允许使用 OpenCV 封装好的直方图函数。根据实例讲解,了解了直方图匹配算法底层的操作(多说一句,这个例子可以是我见过最好的直方图匹配算法讲解,也是很难见的此算法的例子,必读)。
注:实例讲解中 0->3 的意义是,原图中灰度级为 0 的像素点全部转化为原图中的 3 灰度级。
上代码(其中,srcImg 是原图,dstImg 是需要匹配的图,flag 标记两者是 RGB 图还是灰度图):
cv::Mat ycMatchHist(cv::Mat srcImg, cv::Mat dstImg, int flag)
{
// ****** 如果是 RGB 图片则转为灰度图片操作 ******
Mat out(srcImg);
if (flag == YC_RGB)
{
cvtColor(srcImg, out, CV_BGR2GRAY);
}
else if (flag == YC_GRAY)
{
}
int grayLevel[colvl];
for(int i=0; i
(nrow, ncol);
grayArr[tag]++;
}
tmp = 0;
for(int i=0; i
(nrow, ncol); grayArr[tag]++; } tmp = 0; for(int i=0; i
abs(srcCdfArr[i] - dstCdfArr[j])) { minMap = abs(srcCdfArr[i] - dstCdfArr[j]); minTag = j; } } histMap[i] = minTag; } for(size_t nrow = 0; nrow < out.rows; nrow++) for(size_t ncol = 0; ncol < out.cols; ncol++) { int tag = out.at
(nrow, ncol); out.at
(nrow, ncol) = histMap[tag]; } return out; }
实验结果如下:
原图为
;
需要匹配的图是
;
最终输出的是图
。
匹配图片的灰度累积直方图为:
;
最终输出的灰度累积直方图为:
两者很接近了,证明匹配算法是可行的(当然如果我说错了,欢迎打脸,共同进步哈哈~)