基于OpenCvSharp的数字图像处理 - 直方图

创建项目  |  文件与显示  |  像素操作  |  图像彩色类型转换  |  模糊、平滑、去噪  |  锐化、边缘检测  |  二值化  |  形态学  |  位置变换  |  直方图  |  霍夫变换  |  图像优化  |  图像分割

完整示例项目

 

直方图是对图像灰度信息的一个统计结果,直方图的分布能够反映图像的某些特征,可用于图像匹配。

一、直方图

提取图像直方图的代码如下:

Mat src = new Mat(img_lenna, ImreadModes.Grayscale);
Mat hist = new Mat();
Cv2.CalcHist(new Mat[] { src }, new int[] { 0 }, new Mat(), hist, 1, new int[] { 256 }, new Rangef[] { new Rangef(0, 256) });
Cv2.Normalize(hist, hist);

Mat result = new Mat(new OpenCvSharp.Size(256, 500), MatType.CV_8UC1, new Scalar(255));
for (int i = 0; i < 256; i++)
{
    float v = hist.Get(i);
    int len = (int)(v * 500);
    if (len != 0)
    {
        Cv2.Line(result, i, 499, i, 500 - len, new Scalar(0));
    }
}
result.SaveImage(img_result);

需要注意的是,由于图像大小各异,一般我们会对直方图进行归一化处理,让每个灰度比例之和为1。

效果如下:

基于OpenCvSharp的数字图像处理 - 直方图_第1张图片

二、直方图均衡化

对于一些偏暗、偏亮的图片,其反映在直方图上的特征是灰度值偏向低强度或高强度,这样的图片看起来会不够清晰。如下图所示:

基于OpenCvSharp的数字图像处理 - 直方图_第2张图片

这种图片的一个处理方法是进行直方图均衡。实现代码如下:

Mat src = new Mat(img_dark, ImreadModes.Grayscale);
Mat result = new Mat();
Cv2.EqualizeHist(src, result);
result.SaveImage(img_result);

效果如下:

基于OpenCvSharp的数字图像处理 - 直方图_第3张图片

三、直方图比较

直方图比较是用于比较两张图像的相似性。比较的方法有很多,它们的结果不太一致:

  完全匹配 一半匹配 完全不匹配
Correl 1 0.7 -1
Chisqr 0 0.67 2
Intersect 1 0.5 0
Bhattacharyya 0 0.55 1
EMD 0 0.5 1

比较代码如下:

Mat p1 = new Mat(img_p1, ImreadModes.Grayscale);
Mat p2 = new Mat(img_p2, ImreadModes.Grayscale);

Mat hist1 = new Mat();
Cv2.CalcHist(new Mat[] { p1 }, new int[] { 0 }, new Mat(), hist1, 1, new int[] { 256 }, new Rangef[] { new Rangef(0, 256) });
Mat hist2 = new Mat();
Cv2.CalcHist(new Mat[] { p2 }, new int[] { 0 }, new Mat(), hist2, 1, new int[] { 256 }, new Rangef[] { new Rangef(0, 256) });

Cv2.Normalize(hist1, hist1);//比较前先进行归一化
Cv2.Normalize(hist2, hist2);

double near = Cv2.CompareHist(hist1, hist2, HistCompMethods.Bhattacharyya);

四、模板匹配

模板匹配实质也是直方图的比较,它是逐像素扫描,找出模板在原图中匹配度最高的区域。代码如下:

Mat src = new Mat(img_lenna, ImreadModes.Grayscale);
Mat templ = new Mat(img_template, ImreadModes.Grayscale);

Mat result = new Mat();
Cv2.MatchTemplate(src, templ, result, TemplateMatchModes.SqDiff);
Cv2.MinMaxLoc(result, out OpenCvSharp.Point minLoc, out OpenCvSharp.Point maxLoc);

minLoc、maxLoc是最优匹配区域和最差匹配区域所在的位置,根据匹配的方法使用不一样,采用最大值还是最小值会有些不一样。如果是SqDiff和SqDiffNormed,使用最小值,其他方法采用最大值。

你可能感兴趣的:(数字图像处理,OpenCvSharp,OpenCV,图像处理,C#,直方图)