Tuesday, December 2, 2008

Image Editing with Java and Excel

Here's a nice 2560x1600 image I found the other day. I thought I had the perfect desktop wallpaper, except there was this unsightly dark rectangle on the left side of the image. I'm the kind of guy who gets irked by dead pixels on my monitors and TVs; I can't enjoy a movie unless the picture is perfect. So, there was no way I could use this wallpaper as is. However, it seemed like such a travesty to waste an otherwise perfectly good image.

First, I tried trusty old Photoshop. I selected the dark rectangle and applied the brightness/contrast filter. But alas, it seemed like no combination of brightness and contrast values did the trick of completely removing the rectangle.

After a little thought, I realized that the dark rectangle is really just a function, mapping the original pixel value to another pixel value. If I knew what that function was, I could apply the inverse function and restore the original pixel values! Finding that function is the tricky part. If I could only get a good sample of original pixel values and corresponding dark pixel values, I could approximate it however. Then it hit me; I could look at the right edge of the dark rectangle. Pixel values generally don't change too much over just a few pixels, so I could take the pixel just to the right of the edge to be the original value and take the pixel just to the left of the edge to be the corresponding dark pixel value! Of course, JPEG artifacts and high texture areas in the image would make the data a bit noisy, but the idea should still work.

I wrote a quick Java program to get the data. The program went down the edge, making a map from original pixel value to a list of all corresponding dark pixel values. When finished, it would output all the original pixel value it had seen, and the average corresponding dark pixel value. I had it only output the original value if it had seen it at least 3 times (to reduce noise in the data). I then imported the data into Excel, made a scatter chart, and computed a liner regression.

I created another Java program to apply the inverse function to the rectangle. This is the final result. You can still make out the outline of the rectangle, but it's much better than before.

1 comment:

Kevin Chiu said...

This reminds me of the grail lab =) Good times.