0
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import java.util.Arrays;

public class Main {

private static double getRGB(int i, int j, Mat matrix) { //this method is used to obtain pixel values of an image
    double rgbVal; 
    double[] pixel = matrix.get(i, j);
    rgbVal = pixel[0] + pixel[1] + pixel[2]; //error on this line 
    rgbVal = rgbVal / 3;
    return rgbVal;
}

public static void main(String[] args) {
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    Imgcodecs imageCodecs = new Imgcodecs();
    Mat matrix = imageCodecs.imread("/Users/brand/Downloads/SPACE.JPG");
    System.out.println("Image loaded");
    System.out.println("Image size : " + matrix.width() + " x " + matrix.height());
    double[][] rgb = new double[matrix.width()][matrix.height()]; //this is where i want to store the values

    for (int i = 0 ; i < matrix.width(); i++) {
        for (int j = 0; j < matrix.height(); j++) {
            rgb[i][j] = getRGB(i, j, matrix); //iterating through my Mat object and storing here
        }
    }
    System.out.println(Arrays.deepToString(rgb)); //checking if it works
}
}

I am throwing a null pointer exception on line 11 for : Exception in thread "main" java.lang.NullPointerException: Cannot load from double array because "pixel" is null.

I have tried adding the code: System.out.println(Arrays.deepToString(pixel));

After doing this I can see that my program is actually working as intended for the first several hungred pixel values, but for some reason it keeps stopping on the same value, and then reading null before throwing the exception. Any advice would be appreciated.

  • @fantaghirocco unfortunately it doesn't :(. The biggest head scratcher about this is that it's only throwing the nullpointerexception after iterating several hundred times. I don't understand what is making it suddenly null. – Stonezarcon Dec 21 '20 at 23:53

2 Answers2

1

In OpenCV, images are treated like 2D (or 3D) arrays and are indexed by matrix indices (row, column) rather than cartesian coordinates (x, y). The issue is that your code is using the index i to represent the x coordinate instead of the row index and is using the image's width as the limit. To fix this, use i as a row index and use as a limit the number of rows in the image which is basically matrix.height(). Similar logic applies also to the j index. Please check the correction to your nested loop below:

    for (int i = 0 ; i < matrix.height(); i++) { // Height is the # of rows not width.
        for (int j = 0; j < matrix.width(); j++) { // Width is the # of columns not height.
            rgb[i][j] = getRGB(i, j, matrix); //iterating through my Mat object and storing here
        }
    }
mefathy
  • 771
  • 5
  • 10
  • Even better, I would be more explicit and will prefer to use `r` and `c` as names for my loop counters instead of the ambiguous `i` and `j` indices. – mefathy Dec 22 '20 at 00:15
  • thank you so much!!! This has been a nightmare! Sometimes you get so in your own head you don't realize something that should have been obvious from the beginning. This is an awesome learning experience – Stonezarcon Dec 22 '20 at 00:45
  • @Stonezarcon, you may mark the answers which were suggestive and that solved your problem. – Twenkid Dec 22 '20 at 09:08
0
double rgbVal; 
double[] pixel = matrix.get(i, j);
rgbVal = pixel[0] + pixel[1] + pixel[2]; 

I believe your issue is that the pixel array doesnt actually have 3 elements in it. pixel[0] and pixel[1] are accounted for, but pixel[2] doesn't exist ?

there should be three values for RGB, I would add another int for the blue value in rgb, then pass that through the array

Jake
  • 17
  • 5
  • matrix.get(i, j) returns the value at those coordinates, which is the 3 rgb values, and stores them inside my pixel[] variable. If I add code to print pixel everytime it gets updated it works properly, for awhile before eventually throwing the exception. I hope this makes sense. – Stonezarcon Dec 21 '20 at 23:50
  • Okay that is interesting, If it is working indefinitely until a CERTAIN POINT then that means that maybe something inside the image is messing with it. Maybe its transparent(like the image has contents, and it got magic wand to make it transparent ) and doesn't have an actual rgb value ? I am just spit balling here, but i could see that being an issue – Jake Dec 21 '20 at 23:59