This answer suggests that it's over 10 times faster to loop pixel array instead of using BufferedImage.getRGB. Such difference is too important to by ignored in my computer vision program. For that reason, O rewritten my IntegralImage method to calculate integral image using the pixel array:
/* Generate an integral image. Every pixel on such image contains sum of colors or all the
     pixels before and itself.
  */
  public static double[][][] integralImage(BufferedImage image) {
    //Cache width and height in variables
    int w = image.getWidth();
    int h = image.getHeight();
    //Create the 2D array as large as the image is
    //Notice that I use [Y, X] coordinates to comply with the formula
    double integral_image[][][] = new double[h][w][3];
    //Variables for the image pixel array looping
    final int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
    //final byte[] pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
    //If the image has alpha, there will be 4 elements per pixel
    final boolean hasAlpha = image.getAlphaRaster() != null;
    final int pixel_size = hasAlpha?4:3;
    //If there's alpha it's the first of 4 values, so we skip it
    final int pixel_offset = hasAlpha?1:0;
    //Coordinates, will be iterated too
    //It's faster than calculating them using % and multiplication
    int x=0;
    int y=0;
    int pixel = 0;
    //Tmp storage for color
    int[] color = new int[3];
    //Loop through pixel array
    for(int i=0, l=pixels.length; i<l; i+=pixel_size) {
      //Prepare all the colors in advance
      color[2] = ((int) pixels[pixel + pixel_offset] & 0xff); // blue;
      color[1] = ((int) pixels[pixel + pixel_offset + 1] & 0xff); // green;
      color[0] = ((int) pixels[pixel + pixel_offset + 2] & 0xff); // red;
      //For every color, calculate the integrals
      for(int j=0; j<3; j++) {
        //Calculate the integral image field
        double A = (x > 0 && y > 0) ? integral_image[y-1][x-1][j] : 0;
        double B = (x > 0) ? integral_image[y][x-1][j] : 0;
        double C = (y > 0) ? integral_image[y-1][x][j] : 0;
        integral_image[y][x][j] = - A + B + C + color[j];
      }
      //Iterate coordinates
      x++;
      if(x>=w) {
        x=0;
        y++;        
      }
    }
    //Return the array
    return integral_image;
  }
The problem is that if I use this debug output in the for loop:
  if(x==0) {
    System.out.println("rgb["+pixels[pixel+pixel_offset+2]+", "+pixels[pixel+pixel_offset+1]+", "+pixels[pixel+pixel_offset]+"]");
    System.out.println("rgb["+color[0]+", "+color[1]+", "+color[2]+"]");
  }
This is what I get:
rgb[0, 0, 0]
rgb[-16777216, -16777216, -16777216]
rgb[0, 0, 0]
rgb[-16777216, -16777216, -16777216]
rgb[0, 0, 0]
rgb[-16777216, -16777216, -16777216]
rgb[0, 0, 0]
rgb[-16777216, -16777216, -16777216]
rgb[0, 0, 0]
rgb[-16777216, -16777216, -16777216]
rgb[0, 0, 0]
rgb[-16777216, -16777216, -16777216]
rgb[0, 0, 0]
rgb[-16777216, -16777216, -16777216]
rgb[0, 0, 0]
...
So how should I properly retrieve pixel array for BufferedImage images?
 
     
    