【问题标题】:Negative value when calculating the variance of an image -java-计算图像方差时的负值 -java-
【发布时间】:2017-05-10 14:21:55
【问题描述】:

这里我尝试计算图像的方差,从这张图像中每种颜色的方差开始(我已经计算了红色的方差,但结果是-1)

我使用以下公式“var (x) = E (x²) -E (x) ²”。

    private void openActionPerformed(java.awt.event.ActionEvent evt) {                                     
    LoadImage loadImage = new LoadImage(null);
    int w, h;
    BufferedImage image;
    float somR = 0;
    int somG = 0;
    int somB = 0;
    int valR[][];
    int[][] valG;
    int valB[][];
    double meanR = 0;
    double meanG = 0;
    double meanB = 0;
    int nbpixl = 0;
    try {
        if (loadImage.loadImage(jScrollPane1)) {
            int pixel = 0;

            image = loadImage.getImage();
            w = image.getWidth();
            h = image.getHeight();
            System.out.println("width, height: " + w + ", " + h);
            nbpixl = w * h;

            valR = new int[h][w];
            valB = new int[h][w];
            valG = new int[h][w];
            for (int i = 0; i < h; i++) {
                for (int j = 0; j < w; j++) {

                    pixel = image.getRGB(j, i);
                    //rgb argb

                    //int alpha = (pixel >> 24) & 0xff;
                    int red = (pixel >> 16) & 0xff;
                    int green = (pixel >> 8) & 0xff;
                    int blue = (pixel) & 0xff;

                    valR[i][j] = red;
                    somR += red;

                    valG[i][j] = green;
                    somG += green;

                    valB[i][j] = blue;
                    somB += blue;

                    System.out.println("");

                }

            }

            System.out.println("red " + somR);
            System.out.println("green " + somG);
            System.out.println("blue " + somB);
            meanR = somR / nbpixl;
            meanG = somG / nbpixl;
            meanB = somB / nbpixl;
            System.out.println("meanR" + meanR);
            System.out.println("meanV" + meanG);
            System.out.println("meanB" + meanB);



            float summSquareR = somR * somR;
            float meanSquareR = summSquareR / nbpixl;

            System.out.println("summSquareR" + summSquareR);
            System.out.println("meanSquareR" + meanSquareR);
            //float varRrr=(float) (meanSquareR-meanR*meanR);

            //var (x) = E (x²) -E (x) ²

            byte varR = (byte) (255f * (meanSquareR - meanR * meanR));
            // byte varG=(byte)(225f*((somG*somG)/nbpixl)-((somG/nbpixl)*(somG/nbpixl)));
            System.out.println(somB + "\t" + somR + "\t" + somG);
            System.out.println("varR\t" + varR);

        }
    } catch (IOException ex) {
        Logger.getLogger(var_img.class.getName()).log(Level.SEVERE, null, ex);
    }
}

对于结果 宽、高:259、194

红色 5137653.0

绿色 4165933

蓝色 4142841

平均R102.24999237060547

平均V82.0

平均B82.0

summSquareR2.63954786E13

meanSquareR5.2532496E8

4142841 5137653.0 4165933

varR -1

【问题讨论】:

  • 乍一看好像溢出了。你为什么要投到byte?
  • 我有两个原因 1 是在图像处理中,我们处理实际值介于 0 和 1 之间的强度。这就是为什么我必须将整数值 0-255 转换为实际值 0 ... 1 *2 * 将是此代码的延续,如果帧方差超过阈值,我想选择一个阈值(exp 0.25)以将图像每次切割成四(四叉树)
  • 我试过 float Float varR = (float) ((meanSquareR - meanR * meanR));结果** varR 5.25314496E8 **
  • 再看一遍代码后,我看不出你在哪里计算平均值,或者实际的variance (as I know it) - 也许其他人可以更好地理解你的代码和问题,抱歉......
  • 代替getRGB(),使用getSamples(),作为example。

标签: java swing image-processing variance


【解决方案1】:

你要明白公式:

E[X^2]=(x1*x1+x2*x2+...+xn*xn)/n

使用此公式的正确方法如下 - d 和 d2 应该是相同的:

int[] x={1, 2, 5, 7};
int s=0;
for(int i=0; i<x.length; i++) s+=x[i];
double m=s/4.;
double d=0;
for(int i=0; i<x.length; i++) d+=(x[i]-m)*(x[i]-m);
d/=4.;
int s2=0;
for(int i=0; i<x.length; i++) s2+=x[i]*x[i];
double m2=s2/4.;
double d2=m2-m*m;

System.out.println(m+" "+d+" "+d2+" "+m2);

【讨论】:

  • 谢谢 gpasch 所以在这里我尝试应用这两种方法来检查它是否有效 对于图像 1,两个方差值相同但是对于图像 2,我在 2 方法中得到了负值
【解决方案2】:

在此处输入代码

    private void openActionPerformed(java.awt.event.ActionEvent evt) {
    LoadImage loadImage = new LoadImage(null);
    int w = 0, h = 0;
    BufferedImage image;
    float somR = 0;
    int somG = 0;
    int somB = 0;
    int valR[][];
    int[][] valG;
    int valB[][];
    float meanR = 0;
    float meanG = 0;
    float meanB = 0;
    int nbpixl = 0;

    float square_Red = 0, square_Blue = 0, square_Green = 0;
    //The sum of pixels for each color
    int sum_Square_Red = 0, sum_Square_Blue = 0, sum_Square_Green = 0;
    // The square sum of the pixels for each color
    float varR = 0, varG = 0, varB = 0;//The variance of each color
    try {
        if (loadImage.loadImage(jScrollPane1)) {
            int pixel = 0;

            image = loadImage.getImage();
            w = image.getWidth();
            h = image.getHeight();
            System.out.println("width, height: " + w + ", " + h);
            nbpixl = w * h;

            valR = new int[h][w];
            valB = new int[h][w];
            valG = new int[h][w];
            for (int i = 0; i < h; i++) {
                for (int j = 0; j < w; j++) {
                    pixel = image.getRGB(j, i);
                    int red = (pixel >> 16) & 0xff;
                    int green = (pixel >> 8) & 0xff;
                    int blue = (pixel) & 0xff;

                    valR[i][j] = red;
                    somR += red;

                    square_Red = red * red;
                    sum_Square_Red += square_Red;

                    valG[i][j] = green;
                    somG += green;

                    square_Green = green * green;
                    sum_Square_Green += square_Green;

                    valB[i][j] = blue;
                    somB += blue;

                    square_Blue = blue * blue;
                    sum_Square_Blue += square_Blue;

                }

            }

            //la moyenne de pixels dechaque couleurs
            meanR = somR / nbpixl;
            meanG = somG / nbpixl;
            meanB = somB / nbpixl;
            //meanB = somB / nbpixl * 255.0f;

            //1  method of calculating the variance
            System.out.println("1 method of calculating the variance\n");
            float var[] = new float[3];
            for (int i = 0; i < h; i++) {
                for (int j = 0; j < w; j++) {

                    varR += (meanR - valR[i][j]) * (meanR - valR[i][j]);
                    varG += (meanG - valG[i][j]) * (meanG - valG[i][j]);
                    varB += (meanR - valB[i][j]) * (meanB - valB[i][j]);

                }

            }

            var[0] = (varR / nbpixl);

            var[1] = (varG / nbpixl);

            var[2] = (varB / nbpixl);

            float var_img = ((var[0] + var[1] + var[2]) / nbpixl);

             System.out.println("var=\t"+var[0] + "\t"+ var[1] + "\t"+                                                                  var[2]);
            System.out.println("var of image=\t" + var_img);

            //2 method of calculating the variance
            System.out.println("2 method of calculating the variance\n");

            float varR1 = sum_Square_Red / nbpixl - (meanR * meanR);
            float varG1 = sum_Square_Green / nbpixl - (meanG * meanG);
            float varB1 = sum_Square_Blue / nbpixl - (meanB * meanB);
            float mean_img1 = ((varR1 + varG1 + varB1) / nbpixl);

       System.out.println("var=\t" + varR1 + "\t" + varG1 + "\t" + varB1);
            System.out.println("var of image=\t" + mean_img1);

        }

    } catch (IOException ex) {
        Logger.getLogger(var_img1.class.getName()).log(Level.SEVERE, null, ex);
    }
}

对于图像 1 的结果

宽、高:259、194

1种计算方差的方法

varR= 7598.217 varG= 5033.452 varB= 4910.8223

图片变量 = 0.34913212

2计算方差的方法

2计算方差的方法

varR= 7597.9395 varG= 5183.0 varB= 4994.0

图像变量 = 0.3537583



对于图片 2

宽、高:620、349 1 计算方差的方法

varR= 991.2626 varG= 1525.1627 varB= 1280.9857

图像变量= 0.017549733

2计算方差的方法

varR= -52462.875 varG= -50101.0 varB= -50592.0

图像变量= -0.70780975


这是我使用的 2 张图片 image1 image

【讨论】:

  • 问题通过将代码的int类型改为float解决:int sum_Square_Red = 0, sum_Square_Blue = 0, sum_Square_Green = 0;代码可能是导致溢出的问题.....
猜你喜欢
  • 1970-01-01
  • 2013-02-27
  • 2015-05-09
  • 1970-01-01
  • 2020-01-28
  • 1970-01-01
  • 2018-06-27
  • 2020-03-31
  • 1970-01-01
相关资源
最近更新 更多