Cleaning whiteboard with (almost) four steps

Posted 9 years ago
10365 Views
|
4 Replies
|
27 Total Likes
|
 Hi everybody, here is my first post on Wolfram CommunityThe idea presented here is inspired by whiteboardClean.sh script for ImageMagic. Let's suppose there is a whiteboard photo, like thisSetDirectory[NotebookDirectory[]]initial = Import["Whiteboard.jpg"]The algorithm should clean it thereby making a text more visible. I aim here to make a simple algorithm with a few (clearly undestood) parameters without fine tuning (like choosing a precise threshold for binarization). However, in order to make image processing efficient one usually needs some information a priori. There are three initialization parameters:thickness = 4;denoising = 2;enhancement = 4;We assume that there are only lines/curves on the whiteboard and we know approximately the thickness of these lines. It is not necessary to know the thickness exactly it is rather a characteristic scale or an upper-bound estimate for it. There are a lot of methods to extract such scale from the image automatically, hence I take it as known. The meaning of other two parameters will be clear from the following. The first step is denoising:image = ColorNegate@WienerFilter[initial, denoising];The second step is to prepare a simple approximate mask for the text:mask = Erosion[   Composition[ColorNegate, DeleteSmallComponents, ColorNegate]@    Dilation[EdgeDetect[ColorConvert[image, "GrayScale"], thickness + 1],      thickness], thickness - 2];Here is a demonstration how it works:HighlightImage[initial, mask]The third step is to prepare a background:background =   Inpaint[ImageMultiply[image, ColorNegate@mask], mask,    Method -> "NavierStokes"];The fourth step is to subtract the background and enhance colors:result = Sharpen@  ColorNegate@   ImageMultiply[    ImageSubtract[ImageMultiply[image, mask],      ImageMultiply[background, mask]], enhancement]
4 Replies
Sort By:
Posted 9 years ago
 Ausgezeichnet, Grisha! I was faced with a similar problem not too long ago, and your method is much more complete and far surpasses my meager efforts. The method would work well for wrting on almost any medium, so I would imagine it would be very useful for cleaning up lecture notes, handwritten correspondence, etc. I'm wondering if a filter could be applied to remove the horizontal rules on typical notebook paper?Bob
Posted 9 years ago
 Hi Bob,unfortunately, this method is useless for horizontal rules removal. But there is much more simple and efficent methods. Any periodic noise can be efficently removed by filtering in  frequency domain. You can read a very nice introduction be Prof. Philippe Cattin here. Grisha
Posted 9 years ago
 I tried inpaiting for a very simple example with grid lines and as expected it doesn't work well:SetDirectory[NotebookDirectory[]];initial = Import["Notebook 2.jpg"]Now it is much more difficult to design a robust algorithm. Here is a very stupid brutal force method. First, I need more parameters:angle = 5;        (* threshold for horizontal lines *)denoising = 1;    (* not important *)thickness = 1;    (* approximate thickness of the lines *)threshold = 0.95; (* not important *)postprocessing = MeanShiftFilter[#, 4, .03, MaxIterations -> 10] &; (* important *)Let's prepare black and white image:image = ImageAdjust@   ColorNegate@    WienerFilter[ColorConvert[ImageAdjust@initial, "Grayscale"], 1];The second step is to extract horizontal lines:lines = ImageLines[image];booleMask =   Abs[#] < (angle Pi)/360 & /@    ArcTan[Divide @@@ Composition[Reverse, Subtract] @@@ lines];hlines = Pick[lines, booleMask];The third step is to prepare a mask for inpainting:imageWithLines =   Rasterize[   Show[initial,     Graphics[{Black,       Thickness[(thickness + 2)/First@ImageDimensions[initial]],       Line /@ hlines}]], ImageSize -> ImageDimensions[initial]];mask = Dilation[Binarize[ColorNegate[imageWithLines], threshold], 1];The last step is inpainting and postprocessing:result = postprocessing@  Inpaint[ImageMultiply[initial, ColorNegate@mask] , mask ]
Posted 9 years ago
 This works very well - nice hob! I know Radon can be used to measure lines position and orientation in the image. I wonder if Radon can also be used to filter out the lines. Or, say, GradientOrientationFilter. I like the image btw - artistic and a bit poignant ;-)