Finding neighboring pixels in a 2D array without exceeding bounds

finding neighbours in a two-dimensional array python
find length of the largest region in boolean matrix
given a 2d array of 1s and 0s count the number of islands of 1s eg groups of connecting 1s
dfs on 2d array
find largest area in 2d array

I'm looking to find neighboring pixels in a 2D array. Using a formula for euclidean distance, and an arbitrary number, I want to find if the 'color difference' between a pixel, pix1, and the neighboring pixel, pix2, is > 65. If so, change neighbor pixel, pix2, to black, otherwise change to white. Now, I realize a pixel can have up to 8 neighbors in a 2D array.

For this homework, I was given other .java files which prompt you to select any image, and using this program I'm writing, will output a black and white image based on the mentioned 'color difference.'

I implemented, albeit very inefficient, series of if-statements to check for bounds in the 2D array, but there's a mistake somewhere that I can't seem to find.

edit: no longer get out of bounds, but null pointer errors.

When I forgo a return statement.

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    This method must return a result of type Color[][]

I don't know what it should be returning, all I want is to change pixel colors. Clearly objects are an area I lack understanding.

Also when adding a return statement: 'return result', I get a null pointer exception, where it references other java files

Exception in thread "main" java.lang.NullPointerException
    at ImageConverter.arrayToBufferedImage(ImageConverter.java:45)
    at ImageWriter.writeImage(ImageWriter.java:16)
    at ImageProcessing.processImage(ImageProcessing.java:164)
    at ImageProcessing.main(ImageProcessing.java:186)

Updated code:

    import java.awt.Color;

public class OperationContour implements OperationImage {

public Color[][] doOperation(Color[][] imagingArray) {
    int numberOfRows = imagingArray.length;
    int numberOfColumns = imagingArray[0].length;

    Color[][] result = new Color[numberOfRows][numberOfColumns];

    for (int i = 0; i < numberOfRows; i++)
        for (int j = 0; j < numberOfColumns; j++) {

            Color pix1 = imagingArray[i][j];
            Color pix2 = imagingArray[i][j];

            double colorDifference = Math.sqrt(Math.pow(pix1.getRed() - pix2.getRed(),2) + Math.pow(pix1.getGreen() - pix2.getGreen(),2) + Math.pow(pix1.getBlue() - pix2.getBlue(),2));

            // BELOW
            if (i < numberOfRows-1 && j>0) {
                pix2 = imagingArray[i+1][j];
                colorDifference = Math.sqrt(Math.pow(pix1.getRed() - pix2.getRed(),2) + Math.pow(pix1.getGreen() - pix2.getGreen(),2) + Math.pow(pix1.getBlue() - pix2.getBlue(),2));
                if (colorDifference > 65) {
                    pix1 = Color.BLACK;}
                else {
                    pix1 = Color.WHITE; 


        // #2 BOTTOM RIGHT
            if (j < numberOfColumns-1 && i < numberOfRows-1){
                pix2 = imagingArray[i+1][j+1];
                colorDifference = Math.sqrt(Math.pow(pix1.getRed() - pix2.getRed(),2) + Math.pow(pix1.getGreen() - pix2.getGreen(),2) + Math.pow(pix1.getBlue() - pix2.getBlue(),2));
                if (colorDifference > 65) {
                    pix1 = Color.BLACK;}
                else {
                    pix1 = Color.WHITE;     
                    }
                }

        // #3 BOTTOM LEFT
            if(j > 0 && i < numberOfRows-1){
                pix2 = imagingArray[i+1][j-1];
                colorDifference = Math.sqrt(Math.pow(pix1.getRed() - pix2.getRed(),2) + Math.pow(pix1.getGreen() - pix2.getGreen(),2) + Math.pow(pix1.getBlue() - pix2.getBlue(),2));
                if (colorDifference > 65) {
                    pix1 = Color.BLACK;}
                else {
                    pix1 = Color.WHITE;     
                    }
                }
            }           

            // ABOVE
            if(i>0 && j>0){
                pix2 = imagingArray[i-1][j];
                colorDifference = Math.sqrt(Math.pow(pix1.getRed() - pix2.getRed(),2) + Math.pow(pix1.getGreen() - pix2.getGreen(),2) + Math.pow(pix1.getBlue() - pix2.getBlue(),2));
                if (colorDifference > 65) {
                    pix1 = Color.BLACK;}
                else {
                    pix1 = Color.WHITE;     
                }

            // TOP RIGHT
            if(j < numberOfColumns-1 && i>0){
                pix2 = imagingArray[i-1][j+1];
                colorDifference = Math.sqrt(Math.pow(pix1.getRed() - pix2.getRed(),2) + Math.pow(pix1.getGreen() - pix2.getGreen(),2) + Math.pow(pix1.getBlue() - pix2.getBlue(),2));
                if (colorDifference > 65) {
                    pix1 = Color.BLACK;}
                else {
                    pix1 = Color.WHITE;     
                }
            }
            //6  TOP LEFT
            if(j > 0 && i>0 ){
                pix2 = imagingArray[i-1][j-1];
                colorDifference = Math.sqrt(Math.pow(pix1.getRed() - pix2.getRed(),2) + Math.pow(pix1.getGreen() - pix2.getGreen(),2) + Math.pow(pix1.getBlue() - pix2.getBlue(),2));
                if (colorDifference > 65) {
                    pix1 = Color.BLACK;}
                else {
                    pix1 = Color.WHITE;     
                }
            }

            // 7 RIGHT
            if(j<numberOfColumns-1 && i>0) {
                pix2 = imagingArray[i][j+1];
                colorDifference = Math.sqrt(Math.pow(pix1.getRed() - pix2.getRed(),2) + Math.pow(pix1.getGreen() - pix2.getGreen(),2) + Math.pow(pix1.getBlue() - pix2.getBlue(),2));
                if (colorDifference > 65) {
                    pix1 = Color.BLACK;}
                else { 
                    pix1 = Color.WHITE;     
                }
            }
        }
            // 8 LEFT
            if(j>0 && i>0) {
                pix2 = imagingArray[i][j-1];
                colorDifference = Math.sqrt(Math.pow(pix1.getRed() - pix2.getRed(),2) + Math.pow(pix1.getGreen() - pix2.getGreen(),2) + Math.pow(pix1.getBlue() - pix2.getBlue(),2));
                if (colorDifference > 65) {
                    pix1 = Color.BLACK;}
                else { 
                    pix1 = Color.WHITE;}
            }
            }
        }
    return result;
}

}

You can iterate over neighboring 8 pixels using 2 nested for loops like following

for (int i = 0; i < numberOfRows; i++)
    for (int j = 0; j < numberOfColumns; j++) {
        for(i1 = -1; i1 <= 1; i1++) {
            for(j1 = -1; j1 <= 1; j1++) {
                if(!(i1 == 0 && j1 == 0) && i + i1 >=0 && i + i1 < numberOfRows && j + j1 >= 0 and j + j1 < numberOfColumns) {
                    pix2 = imagingArray[i+i1][j+j1];
                }
            }
        }
    }
}

Or an even simpler option is to store an array of 8 elements that store the coordinate offsets for the neighbors like [[0, -1], [-1, -1], [-1, 0], [-1, 1]...] (I will let you figure out remaining 4 offsets)

Finding neighbours in a two-dimensional array, One trick to avoid bounds checking issues, is to make the array and the array references above are guaranteed to be valid, and have no  0 Finding neighboring pixels in a 2D array without exceeding bounds Feb 2 '19 -1 Calculating 'color distance' between 2 points in a 3-dimensional space Jan 31 '19 -2 How to assign a numerical value to a user string input in Python Sep 26 '18

the error can occur in several places in the code, where you check for upper bounds. for example:

            if (i < numberOfRows && j>0) {
                pix2 = imagingArray[i+1][j];//to the right of current pixel

here i can be equal to numberOfRows-1 and then when you try to access i+1 you will get the above mentioned exception

you need to remember that array indices go from 0 to length-1

Find length of the largest region in Boolean Matrix, If one or more filled cells are also connected, they form a region. find the A cell in 2D matrix can be connected to at most 8 neighbours. and not yet visited. The set of weights is called the filter kernel; the width and height of the kernel determines the number of neighbor pixels ( width × height) included in the sum. In the general case, a 2D convolution operation requires ( width × height) multiplications for each output pixel.

I would suggest that instead of surrounding each of the "modules" in if statements (e.g. if (j > 0)) you surround them in a try-catch. This means it is impossible to receive an IndexOutOfBoundsException. Doing this will look like so:

try {
    if (i < numberOfRows) {
        // ..do whatever you did here
    }
} catch (IndexOutOfBoundsException e) {
    // do nothing because you hit the edge
}

Do this for each if statement and it should work.

Hope this helps!

Edit: Doing it this way has another perk of easily seeing where the exception occurred if you want to. Just place e.printStackTrace() in the catch block that's effected.

New Advances in Computer Graphics: Proceedings of CG International ’89, Pointers are stored to each adjacent vertex, since in polygon mesh modelling the mesh These occupy an extendible array since different vertices have different is used as a time stamp (Section 3.4), and the boolean fields bound, anchored, Since shared vertices and edges will appear more than once, as polygons are​  Let's say I have an array list of four java 2d arrays with the same dimensions. I will join the 2d arrays at index 0 and 1 of the array list and then join the arrays at indexes 2 and 3 of the array list. Then I will add these two joined arrays to the variable that is also another list of 2d arrays called "currentMatrices".

NASA Tech Briefs, T-IIII MH7 where no luck-in has gune before ERE44 RF microspacecraft, given such considerations as synergy among multiple sensors, limits on the which is a recursive neural network that comprises a multidimensional array of mainly in analog networks, and is highly efficient in finding globally optimal solutions. Once, I find all these outer pixels (which will be 16 pixels in this case), I'll choose one among these 16 pixels. Now, I have another a random patch (not squared patch as it has 3x3 + 1 pixels). Then, I want to apply the same steps i.e., find the outer pixels surrounding this non-squared region and choose one pixel among them and make another

STACS 2007: 24th Annual Symposium on Theoretical Aspects of , So far we used Nearest Neighbour Interpolation because of its simplicity. In NNI, the grey value of each pixel in f(A) depends solely on one pixel in A. This method is applied the pixel values of f(A) may depend on more than one pixel of A. In Multiply e with the inverse scaling matrix corresponding to s yielding the affine  For each colony, we also report its circularity 4 π A P 2, where P is the number of foreground pixels neighboring a background pixel. If the boundary contains foreground pixels, there is no clean separation between neighboring colonies, suggesting they are at least touching. In this case, the colony is flagged as potentially overlapping in the

Breast Imaging: The Requisites E-Book, B-values have not been standardized yet, but most investigators use 500 to 1000 gaps, to image faster than 2D multislice imaging, to provide improved reformatted and to avoid SAR limits at 3 T. Slice thickness and resolution are selected to from postcontrast images so that only brightly enhancing findings are seen,  I should be able to input a pixel position and get all the same coloured(in my case it should be black) pixels which are connected to it. How to do this in opencv with c++. Simply the output pixels should be connected to each other with color black. FindContours() method does not work as it cannot be feeded with a pixel.

Comments
  • the exception should be acompanied with stack trace that has line numbers
  • the method in the stack trace is doOperation but in the pasted code it has different name
  • Sorry that's just a typo, where I changed the name of the method, and forgot to change it on here.
  • perhaps you can help us just little bit by pointing out which line is the exception thrown from? what is line number 31??
  • no bother, see my answer
  • In your example, what do i1 and j1 represent?
  • the offset of the neighboring pixel relative to your current pixel.
  • Coding by exception is considered an anti pattern and bad practice
  • but in many cases it can save a lot of space when you know exactly what you are looking for. I created a voxel-like game before and to check the neighboring chunks I also surrounded the code blocks in try-catch statements. The difference is that I knew exactly what I needed to catch and why.
  • Of course it depends on what you are coding, in my case I would have had to surround the block with multiple if statements (or one reeeaaaallllyyyy) long one so it kind of worked out better. It's a personal preference for me, my eyes like the look of it. Besides, if you leave the catch blank, then it takes up the same amount of space.
  • readability is not about saving "space". exceptions were not designed to be part of the code flow. there are solutions if you want to reduce blocks (curly brackets) or indentation - like putting the if statements in separate method. personal preference aside, this is not an advice that gets endorsed by the professional community
  • I guess you're right, but it's always good to know alternative ways to code things, I thought my answer was a good way to see the concept, not nessesarily to be efficient. But I'll take it into consideration