/**
 * Copyright (c) 2017-present, CV4J Contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.cv4j.core.hist;

import com.cv4j.exception.CV4JException;

public class CompareHist {

    /**
     * 0 到 1 之间取值
     * @param source
     * @param target
     * @return
     */
    public double bhattacharyya(int[] source, int[] target) {
        if(source.length != target.length) {
            throw new CV4JException("number of histogram bins is not same...");
        }
        int len = source.length;
        double[] mixedData = new double[len];
        // start to normalize the histogram data
        double[] hist1 = new double[len];
        double[] hist2 = new double[len];
        double sum1=0, sum2=0;
        for (int i = 0; i < len; i++)
        {
            sum1 += source[i];
            sum2 += target[i];
        }
        for (int i = 0; i < len; i++)
        {
            hist1[i] = source[i] / sum1;
            hist2[i] = target[i] / sum2;
        }

        for(int i=0; i<len; i++ ) {
            mixedData[i] = Math.sqrt(hist1[i] * hist2[i]);
        }

        // The values of Bhattacharyya Coefficient ranges from 0 to 1,
        double similarity = 0;
        for(int i=0; i<mixedData.length; i++ ) {
            similarity += mixedData[i];
        }

        // The degree of similarity
        return similarity;
    }

    public double covariance(int[] source, int[] target) {
        if(source.length != target.length) {
            throw new CV4JException("number of histogram bins is not same...");
        }
        int len = source.length;
        double[] mixedData = new double[len];
        // start to normalize the histogram data
        double[] hist1 = new double[len];
        double[] hist2 = new double[len];
        double sum1=0, sum2=0;
        for (int i = 0; i < len; i++)
        {
            sum1 += source[i];
            sum2 += target[i];
        }
        for (int i = 0; i < len; i++)
        {
            hist1[i] = source[i] / sum1;
            hist2[i] = target[i] / sum2;
        }
        double m1 = sum1 / len;
        double m2 = sum2 / len;

        for(int i=0; i<len; i++ ) {
            mixedData[i] = (hist1[i] - m1)*(hist2[i]-m2);
        }

        // The values of Bhattacharyya Coefficient ranges from 0 to 1,
        double similarity = 0;
        for(int i=0; i<mixedData.length; i++ ) {
            similarity += mixedData[i];
        }

        // The degree of similarity
        return similarity / len;
    }

    /**
     * -1 到 1 之间取值
     * @param source
     * @param target
     * @return
     */
    public double ncc(int[] source, int[] target) {
        if(source.length != target.length) {
            throw new CV4JException("number of histogram bins is not same...");
        }
        int len = source.length;
        double[] mixedData = new double[len];
        // start to normalize the histogram data
        double[] hist1 = new double[len];
        double[] hist2 = new double[len];
        double sum1=0, sum2=0;
        for (int i = 0; i < len; i++)
        {
            sum1 += source[i];
            sum2 += target[i];
        }
        for (int i = 0; i < len; i++)
        {
            hist1[i] = source[i] / sum1;
            hist2[i] = target[i] / sum2;
        }
        double m1 = sum1 / len;
        double m2 = sum2 / len;
        sum1 = 0;
        sum2 = 0;
        double sum3 = 0;
        for(int i=0; i<len; i++ ) {
            sum3 += ((hist1[i] - m1)*(hist2[i]-m2));
            sum1 += ((hist1[i] - m1)*(hist1[i]-m1));
            sum2 += ((hist2[i] - m2)*(hist2[i]-m2));
        }
        double ncc = 0.0;
        ncc = sum3 / Math.sqrt(sum1*sum2);
        return ncc;
    }
}

@@ -2200,92 +2200,8 @@
 ata%0A
-        double%5B%5D hist1 = new double%5Blen%5D;%0A        double%5B%5D hist2 = new double%5Blen%5D;%0A
     
@@ -2219,32 +2219,32 @@
 sum1=0, sum2=0;%0A
+
         for (int
@@ -2351,148 +2351,9 @@
   %7D%0A
-        for (int i = 0; i %3C len; i++)%0A        %7B%0A            hist1%5Bi%5D = source%5Bi%5D / sum1;%0A            hist2%5Bi%5D = target%5Bi%5D / sum2;%0A        %7D
 %0A
+
     
@@ -2477,21 +2477,22 @@
 a%5Bi%5D = (
-hist1
+source
 %5Bi%5D - m1
@@ -2490,29 +2490,30 @@
 e%5Bi%5D - m1)*(
-hist2
+target
 %5Bi%5D-m2);%0A   
@@ -3209,92 +3209,8 @@
 ata%0A
-        double%5B%5D hist1 = new double%5Blen%5D;%0A        double%5B%5D hist2 = new double%5Blen%5D;%0A
     
@@ -3360,148 +3360,9 @@
   %7D%0A
-        for (int i = 0; i %3C len; i++)%0A        %7B%0A            hist1%5Bi%5D = source%5Bi%5D / sum1;%0A            hist2%5Bi%5D = target%5Bi%5D / sum2;%0A        %7D
 %0A
+
     
@@ -3536,29 +3536,30 @@
   sum3 += ((
-hist1
+source
 %5Bi%5D - m1)*(h
@@ -3557,21 +3557,22 @@
  - m1)*(
-hist2
+target
 %5Bi%5D-m2))
@@ -3595,21 +3595,22 @@
 m1 += ((
-hist1
+source
 %5Bi%5D - m1
@@ -3612,21 +3612,22 @@
  - m1)*(
-hist1
+source
 %5Bi%5D-m1))
@@ -3650,21 +3650,22 @@
 m2 += ((
-hist2
+target
 %5Bi%5D - m2
@@ -3667,21 +3667,22 @@
  - m2)*(
-hist2
+target
 %5Bi%5D-m2))

fix issue with histogram computation