Colorize/matting photos
April 26th, 2008It’s my final project for computational photography course.Though time consuming, it’s pretty cool, and very practical. The idea is to minimize manual input when colorize an image. We assume colors are the same, if the intensity is close.
My algorithm is to propagate color along the color_marked image base on the affinity of neighbor pixels.
Matlab codes could be found here : http://homepages.nyu.edu/~xl338/colorization.zip
Here’s the example:
this is a friend of mine. He looks a little bit down with his semi-dead plant in B/W image, let’s make his life colorful!
gray image we want to colorize.
color marked image as an input.
result image, see what a wonderful job it did on the fine details!! Now he’s happy, and we are happy!
Using the same algorithm, we can do picture matting.The idea is thinking of every pixels in a picture as a combination of foreground and background with a opacity of the foreground alpha. This could be showed as the formula below:
I = a*F + (1-a)*B
a: alpha value form 0-1
F: foreground
B: background
I: pixel value in picture
So in our input file, instead of give color scribbles we define the opacity of the foreground. This method is especially good for fluffy edges i.e. hair, dog, cat, etc.As it needs to take three color channels into consideration, the time for this method is bad, on 2.4G intel computer it’s about 1 min for 500*500 picture.
Here’s a picture I took years ago. the matting picture looks pretty good on the puppy’s edge.
the input file
result image, notice the shadow area and hair.
optimize the algorithm
Though the algorithm did a pretty good job, it needs a lot of computational power and consumes a lot of memory. On my 2.4G intel computer, it took the Matlab program 30 seconds and around 200M RAM to run a 100*100 picture, and worse, as the picture grows, the time is bad.
In Matlab we can play some matlab trick to speed up the code. One thing we notice is that the weight matrix is mainly zeros. So instead of using full matrix, we can use sparse matrix. This really save a lot of memory,for a typical two dimensional image, the space for a sparse weight matrix to the full weight matrix is about 9 to the size of image. (i.e. for a 100*100 image, it would be 9 to 10000). But this addresses another problem, as we are adding values into the sparse matrix in the loop, it become very slow. I guess it’s because every time you add something into sparse matrix, it calls memory allocation function. So my solution is to use three matrices when building the weight matrix, one for the value of the weight, other two for the row indies and column indies. and later on build the sparse weight matrix. This works great, it reduce the time for 100*100 image down to less than a seconds, and save good amount of memory.
However, in real life it’s still not good enough. A typical modern cameras can take picture for more than 10 mega pixels. It will take my previous code too long, if possible, to run such one. By close inspection of the code, we may discover that the majority time the code spend is on the calculation weight matrix. (in a 500*500 picture, it spend 8 seconds on the weight matrix out of 12 seconds total time) So weight matrix may be a good thing to start with. Because the code skip the color marked place, in the weight matrix calculation, we can make a pyramid of the image (half size, quarter size, etc,), and run the algorithm on the smallest one first and scale the result up to the next level, and based on that and the color marked image, we calculate the next level image, so on so forth. The idea is to skip as much weight calculation as we can.
Due to short of time, I don’t have time to implement the second optimization.
Contact me if you are interested in more details. At least the puppy is cute!





















































