图像处理:使用矢量中值处理降低噪声

时间:2015-10-05 05:19:22

标签: java image-processing

因此,我的任务是创建一个矢量中值滤镜来帮助清理嘈杂的图像。这背后的逻辑并不复杂。首先,为了平衡付费字段,所有图像都作为3d数组值被带入java。红色,绿色和蓝色值存储在某种行/列情况中。所以当引用像素值时,它可以解决这个问题:

[Color Component (Red, green, or blue)][Row][Col]

这将显示图像特定位置的确切像素值。在做这些事情的时候,我想象一个类似矩阵的东西。

所以...到过滤器..

来自学术文章:"此滤镜通过在具有RGB值的目标像素上移动窗口[掩模]来执行非线性滤波,并将该像素的值重置为具有最小距离总和的像素到窗口中的其他像素。"

如果你还没有完成任何图像处理工作,这看起来有点令人困惑,但它实际上非常直接。你的面具基本上是一个盒子,可以在图像中移动并创建一个"邻居"像素的大小是预定约束的大小(我通常使用3x3"邻域",所以我有9个值 - 就像我下面的代码一样。)

要点是选择邻域中的目标像素 - 通常是中心(在此示例中,始终是中心)并根据周围像素计算其值。非常简单,它在消除图像噪点方面也非常令人印象深刻。

因此,创建新像素值的逻辑是最重要的部分。获得"邻居"值相当容易,我也会包含它,但我遇到的问题是我认为我没有正确计算逻辑。如上所述,逻辑比较每个"邻域"像素值相互之间,并创建每个像素相对于其余像素的距离的运行总和。运行总和为LOWEST的像素将成为目标像素的新值。

我遵循的步骤(使用代码示例):

  1. 获取邻域值:

            //First two for loops will travel through column and row of image array. 
            //The third will travel through the RGB values (This is 4 values because Transparency is also accounted for here.)
            for (int row = 1; row < imageInDimension.getHeight() - 1; row++) {
            for (int column = 1; column < imageInDimension.getWidth() - 1; column++) {
            for (int ColComp = 1; ColComp < 4; ColComp++) {
            //////////////////////////
            //The Neighborhood////////
            //////////////////////////
            int pixelNeighbors[] = new int[9];
            //Assign values to neighborhood
            pixelNeighbors[0] = OldImageTGRB[ColComp][column - 1][row - 1];
            pixelNeighbors[1] = OldImageTGRB[ColComp][column - 1][row];
            pixelNeighbors[2] = OldImageTGRB[ColComp][column - 1][row + 1];
            pixelNeighbors[3] = OldImageTGRB[ColComp][column][row - 1];
            pixelNeighbors[4] = OldImageTGRB[ColComp][column][row];
            pixelNeighbors[5] = OldImageTGRB[ColComp][column][row + 1];
            pixelNeighbors[6] = OldImageTGRB[ColComp][column + 1][row - 1];
            pixelNeighbors[7] = OldImageTGRB[ColComp][column + 1][row];
            pixelNeighbors[8] = OldImageTGRB[ColComp][column + 1][row + 1];
    
  2. 对&#34;邻居&#34;中的每个像素执行距离计算。相对于&#34;邻域中的其他像素&#34;并将每个值存储在一个运行总和中(在这里使用绝对值,因为它是一个距离公式)

                //Calculate distances
                for (int i = 0; i < 8; i++) {
                    runningSumPixel0 += Math.abs(pixelNeighbors[0] - pixelNeighbors[i]);
                    runningSumPixel1 += Math.abs(pixelNeighbors[1] - pixelNeighbors[i]);
                    runningSumPixel2 += Math.abs(pixelNeighbors[2] - pixelNeighbors[i]);
                    runningSumPixel3 += Math.abs(pixelNeighbors[3] - pixelNeighbors[i]);
                    runningSumPixel4 += Math.abs(pixelNeighbors[4] - pixelNeighbors[i]);
                    runningSumPixel5 += Math.abs(pixelNeighbors[5] - pixelNeighbors[i]);
                    runningSumPixel6 += Math.abs(pixelNeighbors[6] - pixelNeighbors[i]);
                    runningSumPixel7 += Math.abs(pixelNeighbors[7] - pixelNeighbors[i]);
                    runningSumPixel8 += Math.abs(pixelNeighbors[8] - pixelNeighbors[i]);
                }
    
  3. 这就是我认为我要么太复杂或搞乱逻辑的地方。我需要为最低运行总和提供资金,并将目标像素设置为该值。我现在所拥有的将比较每个运行总和与所有值并验证它是否是最低值。如果它是最低的,则它变为目标像素值。这是一个很长的问题,我道歉。

                    //Determine lowest distance value and set target pixel to lowest distance value original value
                    if (runningSumPixel0 < runningSumPixel1 &
                            runningSumPixel0 < runningSumPixel2 &
                            runningSumPixel0 < runningSumPixel3 &
                            runningSumPixel0 < runningSumPixel4 &
                            runningSumPixel0 < runningSumPixel5 &
                            runningSumPixel0 < runningSumPixel6 &
                            runningSumPixel0 < runningSumPixel7 &
                            runningSumPixel0 < runningSumPixel8) {
                        System.out.println("Target set to o position");
                        newImageTRGB[ColComp][column][row] = pixelNeighbors[0];
    
                    } else if (runningSumPixel1 < runningSumPixel0 &
                            runningSumPixel1 < runningSumPixel2 &
                            runningSumPixel1 < runningSumPixel3 &
                            runningSumPixel1 < runningSumPixel4 &
                            runningSumPixel1 < runningSumPixel5 &
                            runningSumPixel1 < runningSumPixel6 &
                            runningSumPixel1 < runningSumPixel7 &
                            runningSumPixel1 < runningSumPixel8) {
                        System.out.println("Target set to 1 position");
                        newImageTRGB[ColComp][column][row] = pixelNeighbors[1];
    
                    } else if (runningSumPixel2 < runningSumPixel0 &
                            runningSumPixel2 < runningSumPixel1 &
                            runningSumPixel2 < runningSumPixel3 &
                            runningSumPixel2 < runningSumPixel4 &
                            runningSumPixel2 < runningSumPixel5 &
                            runningSumPixel2 < runningSumPixel6 &
                            runningSumPixel2 < runningSumPixel7 &
                            runningSumPixel2 < runningSumPixel8) {
                        System.out.println("Target set to 2 position");
                        newImageTRGB[ColComp][column][row] = pixelNeighbors[2];
    
                    } else if (runningSumPixel3 < runningSumPixel0 &
                            runningSumPixel3 < runningSumPixel1 &
                            runningSumPixel3 < runningSumPixel3 &
                            runningSumPixel3 < runningSumPixel4 &
                            runningSumPixel3 < runningSumPixel5 &
                            runningSumPixel3 < runningSumPixel6 &
                            runningSumPixel3 < runningSumPixel7 &
                            runningSumPixel3 < runningSumPixel8) {
                        System.out.println("Target set to 3 position");
                        newImageTRGB[ColComp][column][row] = pixelNeighbors[3];
    
                    } else if (runningSumPixel4 < runningSumPixel0 &
                            runningSumPixel4 < runningSumPixel2 &
                            runningSumPixel4 < runningSumPixel3 &
                            runningSumPixel4 < runningSumPixel1 &
                            runningSumPixel4 < runningSumPixel5 &
                            runningSumPixel4 < runningSumPixel6 &
                            runningSumPixel4 < runningSumPixel7 &
                            runningSumPixel4 < runningSumPixel8) {
                        System.out.println("Target set to 4 position");
                        newImageTRGB[ColComp][column][row] = pixelNeighbors[4];
    
                    } else if (runningSumPixel5 < runningSumPixel0 &
                            runningSumPixel5 < runningSumPixel2 &
                            runningSumPixel5 < runningSumPixel3 &
                            runningSumPixel5 < runningSumPixel4 &
                            runningSumPixel5 < runningSumPixel1 &
                            runningSumPixel5 < runningSumPixel6 &
                            runningSumPixel5 < runningSumPixel7 &
                            runningSumPixel5 < runningSumPixel8) {
                        System.out.println("Target set to 5 position");
                        newImageTRGB[ColComp][column][row] = pixelNeighbors[5];
    
                    } else if (runningSumPixel6 < runningSumPixel0 &
                            runningSumPixel6 < runningSumPixel2 &
                            runningSumPixel6 < runningSumPixel3 &
                            runningSumPixel6 < runningSumPixel4 &
                            runningSumPixel6 < runningSumPixel5 &
                            runningSumPixel6 < runningSumPixel1 &
                            runningSumPixel6 < runningSumPixel7 &
                            runningSumPixel6 < runningSumPixel8) {
                        System.out.println("Target set to 6 position");
                        newImageTRGB[ColComp][column][row] = pixelNeighbors[6];
    
                    } else if (runningSumPixel7 < runningSumPixel0 &
                            runningSumPixel7 < runningSumPixel2 &
                            runningSumPixel7 < runningSumPixel3 &
                            runningSumPixel7 < runningSumPixel4 &
                            runningSumPixel7 < runningSumPixel5 &
                            runningSumPixel7 < runningSumPixel6 &
                            runningSumPixel7 < runningSumPixel1 &
                            runningSumPixel7 < runningSumPixel8) {
                        System.out.println("Target set to 7 position");
                        newImageTRGB[ColComp][column][row] = pixelNeighbors[7];
    
                    } else if (runningSumPixel8 < runningSumPixel0 &
                            runningSumPixel8 < runningSumPixel2 &
                            runningSumPixel8 < runningSumPixel3 &
                            runningSumPixel8 < runningSumPixel4 &
                            runningSumPixel8 < runningSumPixel5 &
                            runningSumPixel8 < runningSumPixel6 &
                            runningSumPixel8 < runningSumPixel7 &
                            runningSumPixel8 < runningSumPixel1) {
                        System.out.println("Target set to 8 position");
                        newImageTRGB[ColComp][column][row] = pixelNeighbors[8];
    
                    }
                }
    
            }
        }
    
  4. 返回新图片。

  5. 我相当肯定我的邻居是正确的,因为我使用相同的算法在不同的过滤器上找到邻域并且它可以完美地工作。

    问题:基本上代码根本没有减少噪音。事实上,它对图像没有任何影响。这没有任何意义,因为我理论上改变了每个像素值。

    有什么建议吗?希望这不是一个问题的具体问题。提前谢谢!

    建议更新后的完整方法:

    protected Image VMFilter (Image imageIn) {
            //Get Image Dimensions
            Dimension imageInDimension = getImageDimension(imageIn);
    
            //calculate total number of pixels
            double totalPixels = imageInDimension.getHeight() * imageInDimension.getWidth();
    
            //Move image into an array.."old image"
            int OldImageTGRB[][][] = pixelsArrayToTRGBArray(imageToPixelsArray(imageIn), imageInDimension);
            //Create new image where new values will be stored
            int newImageTRGB[][][] = pixelsArrayToTRGBArray(imageToPixelsArray(imageIn), imageInDimension);
    
    
            //////////////////////////////////
            //////////THE LOGIC///////////////
            //////////////////////////////////
            //Sort through oldImage TRGB and create the neighborhood from values
            for (int row = 1; row < imageInDimension.getHeight() - 1; row++) {
                for (int column = 1; column < imageInDimension.getWidth() - 1; column++) {
                    //Will Cycle through the color components assigning values to the neighborhood
                    for (int ColComp = 1; ColComp < 4; ColComp++) {
    
                        //////////////////////////
                        //The Neighborhood////////
                        //////////////////////////
                        int pixelNeighbors[] = new int[9];
    
                        //Assign values to neighborhood
                        pixelNeighbors[0] = OldImageTGRB[ColComp][column - 1][row - 1];
                        pixelNeighbors[1] = OldImageTGRB[ColComp][column - 1][row];
                        pixelNeighbors[2] = OldImageTGRB[ColComp][column - 1][row + 1];
                        pixelNeighbors[3] = OldImageTGRB[ColComp][column][row - 1];
                        pixelNeighbors[4] = OldImageTGRB[ColComp][column][row];
                        pixelNeighbors[5] = OldImageTGRB[ColComp][column][row + 1];
                        pixelNeighbors[6] = OldImageTGRB[ColComp][column + 1][row - 1];
                        pixelNeighbors[7] = OldImageTGRB[ColComp][column + 1][row];
                        pixelNeighbors[8] = OldImageTGRB[ColComp][column + 1][row + 1];
    
                        //Create running sum variables to keep track of distance calculation sums
                        int runningSumPixels[] = new int[9];
    
    
                        //Calculate distances
                        for (int i = 0; i < 9; i++) {
                            runningSumPixels[i] += Math.abs(pixelNeighbors[i] - pixelNeighbors[i]);
                        }
    
                        int iLow = Integer.MAX_VALUE;
                        int lowest = Integer.MAX_VALUE;
    
                        for (int i = 0; i < 9; ++i) {
                            if (runningSumPixels[i] < lowest) {
                                iLow = i;
                                lowest = runningSumPixels[i];
                            }
                            System.out.println("Old Value:" + newImageTRGB[ColComp][column][row]);
                            newImageTRGB[ColComp][column][row] = pixelNeighbors[iLow];
                            System.out.println("New Value:" + newImageTRGB[ColComp][column][row]);
                            }
                        }
                    }
                }
            //Return new image..
            return pixelsArrayToImage(
                    TRGBArrayToPixelsArray(newImageTRGB, imageInDimension), imageInDimension);
        }
    

2 个答案:

答案 0 :(得分:0)

步骤3 if语句中的

错误:,Java逻辑AND运算符为&&,而不是&

在步骤2循环中

可能的错误:,在我看来应该允许i取值8,将条件更改为i < 9而不是{{ 1}}。

改进:您当前的第3步实施非常幼稚(可能有问题,因为i < 8而不是<运算符。考虑这样做:

  • 将9个<=变量替换为一个数组(如runningSumPixel);
  • 使用以下代码替换第3步。

<子> CODE功能

pixelNeighbors

比你的小一点,对吗? :)

答案 1 :(得分:0)

我已将您的代码转换为位图用例。

protected Bitmap VMFilter (Bitmap bitmap) {
        //Get Image Dimensions
        //Dimension imageInDimension = getImageDimension(imageIn);

        //calculate total number of pixels
        double totalPixels = bitmap.getWidth()* bitmap.getHeight(); //imageInDimension.getHeight() * imageInDimension.getWidth();
        int w = bitmap.getWidth(),h = bitmap.getHeight();

        //Move image into an array.."old image"
        int OldImageTGRB[][][] = bitmapToTRGBArray(bitmap);
        //Create new image where new values will be stored
        int[][][] newImageTRGB = new int[w][h][3];////pixelsArrayToTRGBArray(bitmap);


        //////////////////////////////////
        //////////THE LOGIC///////////////
        //////////////////////////////////
        //Sort through oldImage TRGB and create the neighborhood from values
        int nearbyWindow = 10;
        for (int row = nearbyWindow; row < bitmap.getWidth() -nearbyWindow ; row++) {
            for (int column = nearbyWindow; column < bitmap.getHeight()-nearbyWindow ; column++) {
                //Will Cycle through the color components assigning values to the neighborhood
                for (int ColComp = 0; ColComp < 3; ColComp++) {

                    //////////////////////////
                    //The Neighborhood////////
                    //////////////////////////
                    int totalNeighbors = nearbyWindow * nearbyWindow;

                    int pixelNeighbors[] = new int[totalNeighbors];

                    
                    for(int i=0;i<totalNeighbors;i++){
                        pixelNeighbors[i] = OldImageTGRB[row-1][column-1][ColComp];
                    }

                    //Create running sum variables to keep track of distance calculation sums
                    int runningSumPixels[] = new int[totalNeighbors];


                    //Calculate distances
                    for (int i = 0; i < totalNeighbors; i++) {
                        runningSumPixels[i] += Math.abs(pixelNeighbors[i] - pixelNeighbors[ColComp]);
                    }

                    int iLow = Integer.MAX_VALUE;
                    int lowest = Integer.MAX_VALUE;

                    for (int i = 0; i < totalNeighbors; ++i) {
                        if (runningSumPixels[i] < lowest) {
                            iLow = i;
                            lowest = runningSumPixels[i];
                        }
                        //System.out.println("Old Value:" + newImageTRGB[ColComp][column][row]);
                        newImageTRGB[row][column][ColComp] = pixelNeighbors[iLow];
                        //System.out.println("New Value:" + newImageTRGB[ColComp][column][row]);
                    }
                }
            }
        }
        //Return new image..
        return pixelsArrayToBitmap(newImageTRGB, w,h, bitmap);
    }

相关问题