1

Im trying to decompile the convolution matrix for the filters on the Motorola Gallery App

Im using the following code to read the pixel data:

public static void main(String[] foo) {
new JavaWalkBufferedImageTest1();
}

public void printPixelARGB(int pixel) {
int alpha = (pixel >> 24) & 0xff;
int red = (pixel >> 16) & 0xff;
int green = (pixel >> 8) & 0xff;
int blue = (pixel) & 0xff;
System.out.println("argb: " + alpha + ", " + red + ", " + green + ", " + blue);
}

private void marchThroughImage(BufferedImage image) {
int w = image.getWidth();
int h = image.getHeight();
System.out.println("width, height: " + w + ", " + h);

for (int i = 0; i < h; i++) {
  for (int j = 0; j < w; j++) {
    System.out.println("x,y: " + j + ", " + i);
    int pixel = image.getRGB(j, i);
    printPixelARGB(pixel);
    System.out.println("");
  }
}
}

  public JavaWalkBufferedImageTest1() {
  try {
  // get the BufferedImage, using the ImageIO class
  BufferedImage image = 
    ImageIO.read(this.getClass().getResource("WhiteSpot.jpg"));
  marchThroughImage(image);
} catch (IOException e) {
  System.err.println(e.getMessage());
}
}

It gives the desired output. But this is not leading me anywhere into finding the matrix.

How do I modify the code so that I can input 2 image files, Original & Filtered. And get the convolution matrix. Or is there an online tool that I can use, where I upload multiple Original & Filtered samples, and get the convolution matrix?

Zen
  • 2,698
  • 4
  • 28
  • 41

1 Answers1

1

I would approach this problem (will work if only convolution was applied and only once!) like this:

  1. first you need to find matrix size.

    So you can loop through all possible matrix sizes or use a big one expecting zero values inside. That can be slow but you can try to estimate matrix size from the bluryness of sharp intensity edges (to how many pixels is the color bleeded).

  2. for tested (big) matrix size try to find zero values

    So for each tested matrix value form 2 arrays. One with few samples of pixels from convoluted image and second with pixels (shifted by tested matrix position) from original image. Now compute correlation coefficient between the two and if no significant correlation present you can assume the value in matrix is zero.

  3. solve the remaining nonzero values in matrix

    You can do this algebraically (form as many equation as many nonzero values you have (do not forget to choose pixels with different color). Or you can do search to minimize error/distance of convoluted output by your matrix and the real convoluted output. You can use something like mine approx class in C++ for this but if Your matrix is big then this will take a lot of time.

[Notes]

If more then just single convolution is applied to image then this will most likely not work.

Convolution matrices are mostly square and symmetric around mid value so you can compute the quarter of values and mirror the rest ... speeding up the computation.

Also see Dealing with filters and colour's which is similar question.

Bullet #2 can be used to detect the matrix size. As usually the max nonzero values are in the central cross of matrix.

0 0 2 0 0
0 1 2 1 0
2 2 3 2 2
0 1 2 1 0
0 0 2 0 0

Values 2 are the central cross and value 3 is the mid value of convolution matrix. So start computing the #2 correlations from mid point in x and y direction. And when hit zero value you are most likely at the edge of convolution matrix. So you can use that as matrix size (unless the matrix is some weird filter ...).

Also each color channel can have its own convolution matrix so may be you should do this separately per channel (and convolution can be done in any color space not just in RGB).

There might be other approaches for this (my guts tells me this should be solvable by PCA)

If you got black area in the original image then you can use that to find the values of matrix more easily (it will significantly ease up the algebraic approach)

Community
  • 1
  • 1
Spektre
  • 49,595
  • 11
  • 110
  • 380
  • Ive done few of the steps. Like used different sample images of a single color, and also used a sample image with colors on a square grid to figure out the matrix size(ie, by seeing how far off the pixels are affected) But basically I was trying to reverse-engineer some of the photo filters on an app. And now Im not sure if a ColorMatrixFilter was used, or a ConvolutionMatrix filter. From what I know for such photo-effects ColorMatrixFilters are used mostly. Is my assumption right? – Zen Oct 24 '15 at 15:50
  • Also, when do I use a ColvolutionMatrix vs ColorMatrix filter? Because some of the effects are common in both, like Sepia/BlacknWhite/Brightness/Contrast etc? – Zen Oct 24 '15 at 16:45
  • @summers Color matrix filters does not blur the image at all. They just change the colors, gamma, etc ... something like this [Impact of cubic and catmull splines on image](http://stackoverflow.com/a/23627081/2521214). So edges will stay edges with the same sharpness (unless they have some kind of color gradient that will visually change after recolor) If the details are bleeding to neighboring pixels then most likely convolution was used. – Spektre Oct 24 '15 at 18:26
  • Also possible that majority of the color effect might have be done through a colorMatrix, and Contrast/Brightness might have been done through Convolution. Assuming, the people making the filters would have kept things simple, because most effects can be done through a ColorMatrix from what I know. – Zen Oct 24 '15 at 23:46
  • Ive been able to recreate most of the effects in Photoshop using Hue/Saturation/Contrast/Brightness/Lightness/Color-Balance(using only these variables allows me to enter & get the matrix value faster). I used that I calculate the matrix. – Zen Oct 25 '15 at 00:00