OpenCvSharp 学习笔记24--直方图比较

一,直方图比较方法概述:

对输入的两张图像计算得到直方图H1和H2,归一化到相同的尺度空间(如果比较的两个图像的大小不一致,计算直方图后得到的像素频次不一致,无法比较,必须归一化到相同的尺度空间才可以比较) 然后通过计算H1和H2的之间的距离得到两个直返图的相似程度进而比较图像本身的相似程度.OpenCV提供的比较方法有四种:

1:Correlation 相关性比较:
d c o r r e l ( H 1 , H 2 ) = ∑ I ( H 1 ( I ) − H ˉ 1 ) ( H 2 ( H ) − H ˉ 2 ) ∑ I ( H 1 ( I ) − H ˉ 1 ) 2 ∑ ( H 2 ( I ) − H ˉ 2 ) 2 d_{correl}(H_1,H_2)=\frac{\sum_I(H_1(I)-\bar H_1)(H_2(H)-\bar H_2)}{\sqrt {\sum_I{(H_1(I)-\bar H_1)^2 \sum(H_2(I)- \bar H_2)^2}}} dcorrel(H1,H2)=I(H1(I)Hˉ1)2(H2(I)Hˉ2)2 I(H1(I)Hˉ1)(H2(H)Hˉ2)

H ˉ \bar H Hˉ :是均值 H ˉ k = ∑ J H K ( J ) N \bar H_k=\frac{\sum_JH_K(J)}{N} Hˉk=NJHK(J) N : N: N:为直方图区间(bins)的个数。
H 1 ; H 2 H_1 ;H_2 H1;H2 :比较的两个直方图数据集(梯度范围一致)

分子: H 1 H_1 H1 的直方图每个值 减去它的均值, H 2 H_2 H2 的直方图每个值 减去它的均值 得到两个值相乘,再求总和
分母: 和分子计算方式差不多,求的是方差总和,然后再开平方。

结论: 大相关性系数要比小相关性系数匹配的好。完全匹配的相关性系数为1,而完全 不匹配会得到 -1。而 0 对应着两个分布没有关系(随机组合)。

2:Chi- Square 卡方比较:

d C h i − S q u a r e ( H 1 , H 2 ) = ∑ I ( H 1 ( I ) − H 2 ( I ) ) 2 H 1 ( I ) d_{Chi- Square}(H_1,H_2)=\sum_I \frac{(H_1(I)-H_2(I))^2}{H_1(I)} dChiSquare(H1,H2)=IH1(I)(H1(I)H2(I))2

H 1 , H 2 H_1,H_2 H1,H2:表示两个直方图数据集,梯度范围一致)。 I I I :直方图bins级别中的每一个值。
由上面的公式可以推到处:低分值表示直方图匹配的很好。如果两幅图像一样则 为 0 。而完全不匹配的值无下限(依赖直方图的大小)。

3:Intersection 交集法:
直方图交集法,简单基于两个直方图的交集,该方法对两个直方图中的共同部分求和。

d I n t e r s e c t i o n ( H 1 , H 2 ) = ∑ I min ⁡ ( H 1 ( I ) , H 2 ( I ) ) d_{Intersection }(H_1,H_2)=\sum_I \min(H_1(I),H_2(I)) dIntersection(H1,H2)=Imin(H1(I),H2(I))
H 1 , H 2 H_1,H_2 H1,H2:表示两个直方图数据集,梯度范围一致)。

这个公式比较简单。对于该度量方法,高分值意味着匹配较好,如果两个直方图都进行了归一化,完全匹配对应的值是1 ,完全不匹配对应的值是 0 。

4:Bhattacharyya distance method 巴氏距离:
是对两个分布重叠度的一种度量方法。
d c o r r e l ( H 1 , H 2 ) = 1 − ∑ I H 1 ( I ) ∗ H 2 ( I ) H ˉ 1 H ˉ 2 N 2 d_{correl}(H_1,H_2)={\sqrt {1-\frac{\sum_I \sqrt {H_1(I)*H_2(I)}}{\sqrt{\bar H_1 \bar H_2 N^2}}}} dcorrel(H1,H2)=1Hˉ1Hˉ2N2 IH1(I)H2(I)
H 1 , H 2 H_1,H_2 H1,H2:表示两个直方图数据集,梯度范围一致)。
H ˉ \bar H Hˉ :是均值
N : N: N:为直方图区间(bins)的个数。

结论: 匹配效果越好 ,值越小。效果越差,值越大。完全匹配是 0 ,而完全不匹配是1。

二 ,使用步骤和API:

  1. 首先把图像从RGB色彩空间转换到HSV色彩空间
  2. 计算图像的直方图,然后归一化到 ( 0 ~ 1) 之间
  3. 使用上面介绍的4中方法比较 ,API: Cv2.CompareHist

Cv2.CompareHist(): 返回比较结果 double 类型。

参数描述
InputArray h1比较的第一个直方图
InputArray h2比较的第二个直方图
HistCompMethods method直方图的比较方法,枚举类型

三, 代码:

static Mat baseMat, src1, src2;
        private static void HistogarmToComparison(string path1, string path2, string path3)
        {
            using (baseMat = new Mat(path1, ImreadModes.AnyColor | ImreadModes.AnyDepth))
            using (src1 = new Mat(path2, ImreadModes.AnyColor | ImreadModes.AnyDepth))
            using (src2 = new Mat(path3, ImreadModes.AnyColor | ImreadModes.AnyDepth))
            {
                //1:从BGR空间转换到HSV色彩空间


                Mat baseHSV = new Mat();
                Mat src1HSV = new Mat();
                Mat src2HSV = new Mat();


                Cv2.CvtColor(baseMat, baseHSV, ColorConversionCodes.BGR2HSV);
                Cv2.CvtColor(src1, src1HSV, ColorConversionCodes.BGR2HSV);
                Cv2.CvtColor(src2, src2HSV, ColorConversionCodes.BGR2HSV);
                //Mat[] mats = new Mat[] { baseHSV, src1HSV, src2HSV };
                Mat[] mats1 = Cv2.Split(baseHSV);
                Mat[] mats2 = Cv2.Split(src1HSV);
                Mat[] mats3 = Cv2.Split(src2HSV);

                //计算直方图并归一化数据

                int bin1 = 50; //灰度等级
                int bin2 = 60;//灰度等级
                int[] histSiz = { bin1, bin2 };

                int[] channels = { 0, 1 };//图像通道数
                Rangef[] rangefs = new Rangef[] //梯度值范围
               {
                    new Rangef(0, 180),
                    new Rangef(0,256)
               };

                Mat baseHist = new Mat(baseMat.Size(), MatType.CV_32FC2);
                Mat src1Hist = new Mat(src1.Size(), MatType.CV_32FC2);
                Mat src2Hist = new Mat(src2.Size(), MatType.CV_32FC2);

                Cv2.CalcHist(mats1, channels, new Mat(), baseHist, 2, histSiz, rangefs, true, false);
                Cv2.Normalize(baseHist, baseHist, 0, 1, NormTypes.MinMax, -1, null);

                Cv2.CalcHist(mats2, channels, new Mat(), src1Hist, 2, histSiz, rangefs, true, false);
                Cv2.Normalize(src1Hist, src1Hist, 0, 1, NormTypes.MinMax, -1, null);

                Cv2.CalcHist(mats3, channels, new Mat(), src2Hist, 2, histSiz, rangefs, true, false);
                Cv2.Normalize(src2Hist, src2Hist, 0, 1, NormTypes.MinMax, -1, null);

                //比较直方图
                double bcomb = Cv2.CompareHist(baseHist, baseHist, HistCompMethods.Correl);
                double s1coms2 = Cv2.CompareHist(src1Hist, src2Hist, HistCompMethods.Correl);
                double bcoms1 = Cv2.CompareHist(baseHist, src1Hist, HistCompMethods.Correl);
                double bcoms2 = Cv2.CompareHist(baseHist, src2Hist, HistCompMethods.Correl);

                Mat mats1Ands2 = new Mat();
                src2.CopyTo(mats1Ands2);

                Cv2.PutText(baseMat, bcomb.ToString(), new Point(30, 30), HersheyFonts.HersheyComplex, 1, new Scalar(0, 255, 0), 2, LineTypes.AntiAlias);

                Cv2.PutText(src1, bcoms1.ToString(), new Point(30, 30), HersheyFonts.HersheyComplex, 1, new Scalar(0, 255, 0), 2, LineTypes.AntiAlias);

                Cv2.PutText(src2, bcoms2.ToString(), new Point(30, 30), HersheyFonts.HersheyComplex, 1, new Scalar(0, 255, 0), 2, LineTypes.AntiAlias);

                Cv2.PutText(mats1Ands2, s1coms2.ToString(), new Point(30, 30), HersheyFonts.HersheyComplex, 1, new Scalar(0, 255, 0), 2, LineTypes.AntiAlias);

                using (new Window("b_com_b :baseMat", WindowMode.Normal, baseMat))
                using (new Window("b_com_s1 :src1", WindowMode.Normal, src1))
                using (new Window("b_com_s2 :src2", WindowMode.Normal, src2))
                using (new Window("s1_com_s2 :mats1Ands2", WindowMode.Normal, mats1Ands2))
                {
                    Cv2.WaitKey(0);
                }

            }
        }

输出比较结果:
在这里插入图片描述

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值