基於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<float>(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。

效果如下:

二、直方圖均衡化

對於一些偏暗、偏亮的圖片,其反映在直方圖上的特徵是灰度值偏向低強度或高強度,這樣的圖片看起來會不夠清晰。如下圖所示:

這種圖片的一個處理方法是進行直方圖均衡。實現代碼如下:

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

效果如下:

三、直方圖比較

直方圖比較是用於比較兩張圖像的相似性。比較的方法有很多,它們的結果不太一致:

  完全匹配 一半匹配 完全不匹配
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,使用最小值,其他方法採用最大值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章