Two amigos MATLAB contest
Today I discovered a MATLAB mini-contest called The Two Amigos. The idea is two use MATLAB to remove Bob from a photo of the three Pick-of-the-Week bloggers. The contest officially closed last week but they had no entries by submission day so you’re still in with a chance, if you’re quick.
I hadn’t done any image processing in MATLAB until earlier today, and I don’t have access to the image processing toolbox, so my attempt is pretty basic. I’m posting my submission here to give you a headstart. As with all the other code on this blog, it is licensed under the WTFPL, so you can literally do “what the f*ck” you want with it. ( If you submit something based upon my code though, an attribution would be appreciated.)
First up: reading and displaying an image in MATLAB is easy.
theAmigos = imread('threeamigos-800w.jpg'); image(theAmigos)
My first idea was to simply place a black rectangle over a region roughly corresponding to Bob.
% Take a copy of the basic image theAmigosBlackout = theAmigos; % Select 'Bob' region bobRectX = 220:563; bobRectY = 300:470; % Make this region black theAmigosBlackout(bobRectX, bobRectY, : ) = 0; image(theAmigosBlackout)
Hmm. The black region looks a little severe. It would be easier on the eye to simply blur him out. My homemade blur technique uses the
filter2 function to create a moving average filter (a very simple smoother) to blur the region.
theAmigosBlur = theAmigos; blurRadius = 20; % Calculate weights for the blur filter w = [(blurRadius + 1):-1:1 2:(blurRadius + 1)]; w2 = repmat(w, length(w), 1); weights = 1 ./ (w2 + w2'); weights = weights / sum(weights(:)); % Apply filter to each colour channel for i = 1:3 theAmigosBlur(bobRectX, bobRectY, i) = ... filter2(weights, theAmigosBlur(bobRectX, bobRectY, i)); end image(theAmigosBlur)
The problem here is that the edges of the blurred region look darker. Presumably missing values are considered as black, for some reason. To solve this we only use the central “valid” region of the filter. This involves some fiddling to extend the rectangle’s region, which in turn involves some fiddling to extend the base of the image.
theAmigosBetterBlur = theAmigos; % Temporarily extend image bottom bottom = repmat(theAmigosBetterBlur(end, :, : ), blurRadius, 1); theAmigosBetterBlur = [theAmigosBetterBlur; bottom]; % Extend rectangle extendedX = (min(bobRectX) - blurRadius):(max(bobRectX) + blurRadius); extendedY = (min(bobRectY) - blurRadius):(max(bobRectY) + blurRadius); % Apply filter to valid region for i = 1:3 theAmigosBetterBlur(bobRectX, bobRectY, i) = ... filter2(weights, theAmigosBetterBlur(extendedX, extendedY, i), 'valid'); end % Remove the extension to the bottom of the image theAmigosBetterBlur = theAmigosBetterBlur(1:(end - blurRadius), :, : ); image(theAmigosBetterBlur)
Can you do better than this? Maybe you can figure out how to do edge detection, or find a better way to find the ‘Bob’ region? Can you think of a more appropriate substitute than blurring? Maybe a few MATLAB logos in there might swing the judges decision. Or you could recreate the special effect used when they transport people on Star Trek.
Let me know how you get on.