0

I am trying to do a subsampling on a List of 8x8 2d arrays. More exactly, from a 8x8, I want to transform into an 4x4 by taking one by one 2x2 blocks and saving the arithmetic mean value of the 2x2 in it's correct place in the 4x4. After I do this, the output would be a List of 4x4 2d arrays. The following two methods are taking care of this

public static long[][] subSample420(long[][] originalBlocks){
    long[][] downsampledBlocks = new long[4][4];
    long[] mediePixel = new long[16];
    int nr = 0;
    for (int i = 0; i < 8; i += 2){
        for (int j = 0; j < 8; j += 2){
            mediePixel[nr] = Math.round((double)(originalBlocks[i][j] + originalBlocks[i][j+1] + originalBlocks[i+1][j] + originalBlocks[i+1][j+1]) / 4);
            nr++;
        }
    }
    nr = 0;
    for (int i = 0; i < 4; i++){
        for (int j = 0; j < 4; j++){
            downsampledBlocks[i][j] = mediePixel[nr];
            nr++;
        }
    }
    return downsampledBlocks;
}


public static List<long[][]> subSampleBlocks(List<long[][]> originalBlockList){
    List<long[][]> downsampledBlockList = new ArrayList<long[][]>();
    for (long[][] anOriginalBlockList : originalBlockList) {
        downsampledBlockList.add(subSample420(anOriginalBlockList));
    }
    return downsampledBlockList;
}

Now after I'm done subsampling, I have to resize the 4x4 2d arrays back to their initial size, that means transforming the List of 4x4 2d arrays back into a List of 8x8 2d arrays, by replacing a single value from the 4x4 with a 2x2 block of the same value. The two methods that do this are the following:

public static long[][] resizeSubsampledBlocks(long[][] subBlocks){
    long[][] resizedBlocks = new long[8][8];
    int nr = 0;
    long[] pixel = new long[16];
    for (int i = 0; i < 4; i++){
        for (int j = 0; j < 4; j++){
            pixel[nr] = subBlocks[i][j];
            nr++;
        }
    }
    nr = 0;
    for (int i = 0; i < 8; i += 2){
        for (int j = 0; j < 8; j += 2){
            resizedBlocks[i][j] = pixel[nr];
            resizedBlocks[i][j+1] = pixel[nr];
            resizedBlocks[i+1][j] = pixel[nr];
            resizedBlocks[i+1][j+1] = pixel[nr];
            nr++;
        }
    }
    return resizedBlocks;
}


public static List<long[][]> reziseSubsampledBlockList(List<long[][]> subBlocks){
    List<long[][]> rezisedBlocks = new ArrayList<long[][]>();
    for (long[][] subBlock : subBlocks) {
        rezisedBlocks.add(resizeSubsampledBlocks(subBlock));
    }
    return rezisedBlocks;
}

But when I tried testing all these with the following method:

private static void testOrderSub(int nr){
    List<long[][]> testList = new ArrayList<long[][]>();
    for (int i = 0; i < nr; i++){
        long[][] matrix = {
                {i,     i,     i+1,   i+1,   i+2,   i+2,   i+3,   i+3},
                {i,     i,     i+1,   i+1,   i+2,   i+2,   i+3,   i+3},
                {i+4,   i+4,   i+5,   i+5,   i+6,   i+6,   i+7,   i+7},
                {i+4,   i+4,   i+5,   i+5,   i+6,   i+6,   i+7,   i+7},
                {i+8,   i+8,   i+9,   i+9,   i+10,  i+10,  i+11,  i+11},
                {i+8,   i+8,   i+9,   i+9,   i+10,  i+10,  i+11,  i+11},
                {i+12,  i+12,  i+13,  i+13,  i+14,  i+14,  i+15,  i+15},
                {i+12,  i+12,  i+13,  i+13,  i+14,  i+14,  i+15,  i+15}};
        testList.add(matrix);
    }

    List<long[][]> subTest = FirstLevelEncoder.subSampleBlocks(testList);
    List<long[][]> sizeTest = FirstLevelDecoder.reziseSubsampledBlockList(subTest);
    for (int i = 0; i < nr; i++) {
        if (!(Arrays.equals(testList.get(i), sizeTest.get(i)))){
            System.out.println("false");
        }
    }
}

The sizeTest.equals(testList) returns false, even though by looking in the debugger they seem to have the same values. I tried using these methods to process an image and the output is also messed up. Am I doing something wrong? Why aren't the Lists equal?

Pred
  • 69
  • 6
  • Because as I've said, it looks alright in the debugger and I couldn't see anything wrong. – Pred Apr 27 '17 at 12:52
  • Got it: when you do list.equals(otherList) ... that boils down to array1.equals(array2) ... and that doesnt work - as this does NOT do an element-by-element comparison. You need to use Arrays.equals() – GhostCat Apr 27 '17 at 12:54
  • You are right, I changed it to:`for (int i = 0; i < nr; i++) {if Arrays.equals(testList.get(i), sizeTest.get(i))){ System.out.println("false"); } }` and it works – Pred Apr 27 '17 at 13:18
  • The 2 lists are equal. But the image that results after this is still messed up because of the subsampling, do you have any idea why? – Pred Apr 27 '17 at 13:19
  • Actually scratch that, it isn't equal but I don't understand why. I should have tested `if !(Arrays.equals(testList.get(i), sizeTest.get(i))))` to print false and it does. So the arrays aren't equal for some reason. – Pred Apr 27 '17 at 14:14

1 Answers1

1

For an Java-Array equals() is testing like array1==array2. It checks if it is the same object. It don't check if it has the same content.

You have to use

Arrays.equals(array1, array2);

Here is another explanation about Java-Arrays: equals vs Arrays.equals in Java

Community
  • 1
  • 1
Benjamin Schüller
  • 2,104
  • 1
  • 17
  • 29
  • Thank you, I have also tried your way, check edited test method in the original post. It says that the arrays aren't equal too. I think I'm doing something wrong in the subsampling / resizing methods but I can't see what. – Pred Apr 27 '17 at 14:15
  • Thanks again, I found the problem, it was somewhere else in the code. – Pred Apr 28 '17 at 15:26