正如第4篇文章所说的图像直方图在特征提取方面有着很重要的作用,本文将举两个实际工程中非常实用的例子来说明图像直方图的应用。
一、直方图的反向映射。
我们以人脸检测举例,在人脸检测中,我们第一步往往需要先提取图像中皮肤区域来缩小人脸的检测范围,这一般获得皮肤的颜色范围还需要定义阈值并不断的调整,实际中参数太多而不容易控制。
这里我们就可以考虑用直方图的反射映射。
1,收集人脸皮肤样本。
2,拼合样本并计算其颜色直方图。
3,将得到的样本颜色直方图反射映射到待检测的图片中,然后进行阈值化即可。
这里为了简单起见,我们只用两张人脸样本,实际中可以进一步扩展。
在提取样本皮肤的直方图时,我们需要对这些样本图像做一些处理,比如把头发、眼睛等部位去除,我们这里使用一个mask即可。
由于我们要计算彩色直方图像,为了简化色彩,我们还需要对颜色降维,相关函数在本系列文章中已经有介绍了。
int main() { Mat face=imread("../face.png"); // 样本 Mat ImgSrc=imread("../img.png"); // 待检测的图像 //图像降维 colorReduce(face,face,32); colorReduce(ImgSrc,ImgSrc,32); // 计算颜色直方图 const int channels[3]={0,1,2}; const int histSize[3]={256,256,256}; float hranges[2]={0,255}; const float* ranges[3]={hranges,hranges,hranges}; MatND hist; calcHist(&face,1,channels,Mat(),hist,3,histSize,ranges); // 直方图归一化 normalize(hist,hist,1.0); // 直方图反向映射 Mat result; calcBackProject(&ImgSrc,1,channels,hist,result,ranges,255); // 将结果进行阈值化 threshold(result,result,255*(0.05),255,THRESH_BINARY