Excellent description of both the problem, and the solution. I wrote sanei_magic to contain exactly these sort of routines. Though, you could also add a sanei_ir or some such, if you want a more 'private' playground :)
allan On Mon, Jul 11, 2011 at 12:54 PM, Michael Rickmann <mrickma at gwdg.de> wrote: > I learned from other posts in this list that SANE does not provide much > support for infrared. In sane.h some related definitions are even commented > out. Only in coolscan.c I have found some RGBIfix routines by Andreas Rick > which must be related to what he describes on his page at > http://andreas.rick.free.fr/sane/dustremove.html. With my attempts to > support PIE film scanners in the pie backend I have reached a stage where I > can receive R, G, B and I color planes at resolutions from 300 to 3600 dpi > at 16 bit color depth. I wish to use the infrared channel for dirt removal > without touching current SANE specifications. Essentially three things have > to be done: > 1) reduce red spectral overlap from the infrared (ired) plane > 2) find the dirt > 3) replace the dirt > Everything beyond depends on the kind of film and taste. If you are > interested in quick results skip down to the last paragraphs of this post. > I rolled up my sleeves though in a different way than suggested on this list > and made a small program ircleanest.c in which I tried to implement above > three steps. For trying image calculations before programming "ImageJ" > (http://rsbweb.nih.gov/ij/) ?has been great help. > > Ad 1) Quite often the ired image looks like a greyscale image with dirt > emphasized. Something similar was reported for the Epson V700 scanner in ( > http://lists.alioth.debian.org/pipermail/sane-devel/2011-February/028149.html > ). The ired plane of negative films usually only contains slight shades of > the image but slide films may show a considerable amount of it. I tried > something with gamma and linear operations what Andreas Rick describes for > the Coolscan. I could not get it to work and I do not wish to craft > parameters by hand for every slide. > When plotting the ired value of 1000 randomly chosen pixels against the red > value the relation ired = b + a * ln (red) always gave a good fit. So > calculating an ired' = ired - a ?* ln (red) should clean the ired plane. It > works. I randomly sample 2000 pixels, calculate the parameter "a" by linear > regression from the ln (red) and ired values, produce an ired' plane and > scale it between 0 and 65535. I also tried to include green and blue planes > but there is a lot of calculation and no real benefit. A similar cleaning > effect one gets with the relations ired = b * red ^ a and ired' = ired / red > ^ a. This comes closer Andreas Rick's suggestion of applying a gamma, and > the coefficients can also be determined by linear regression. > > Ad 2) First I tried static thresholds to find the dirt. I still use two of > them, Otsu's and Yen's in M. Emre Celebi's implementation in the FOURIER 0.8 > project ( http://sourceforge.net/projects/fourier-ipal ). Yen's threshold in > this implementation assumes a bimodal distribution and was the best of the > static thresholds I tried in detecting only dirt. I still use it to add > large dirty areas. But soon I gave up detecting smaller dirt with static > thresholding without user intervention. On my search for an adaptive > threshold I stumbled over the MAD (median of the absolute deviations from > the median) filter (Crnojevic V. (2005) "Impulse Noise Filter with Adaptive > Mad-Based Threshold. Proc. of the IEEE Int. Conf. on Image Processing, 3: > 337-340). It is an understandable paper describing an algorithm of rather > low complexity. Median filtering, however, is rather slow. First, ?I > replaced the first median filter step of the original paper with a maximum > filter because the dirty pixels are always darker than the real signal. Then > I managed to get images from the scanner at maximum resolution and realized > some impulse noise. So I resorted to a mean filter. The second median I also > replaced by a mean filter to reduce computation time. In spite of these > changes Crnojevic's recommendations for the choice of the parameters "a" and > "b" were still valid when scaled to 16 bit. In my ircleanest.c program it is > the filter_madmean routine. Combining the madmean dirt mask with the one > from Yen's static threshold gave a good representation of what I felt had to > be removed. > > Ad 3) For Replacing the dirt I dilate the clean image parts into the dirty > ones. As I wish to do that in one sweep several pixels deep I first > calculate the Manhattan distance of dirty pixels to their closest clean > neighbors and keep an index of these clean ones. The result is ok in general > but looks funny when the original dirt was overlapping a region of high > colour changes. So I adapt the dilated pixels by a mean filter to their new > surroundings and replace them again. Clean pixels remain unchanged by this > procedure. > > You find examples of my dust removal at > http://wwwuser.gwdg.de/~mrickma/sane-proscan-7200/status-110711/. The > ircleanest.c is in the files.tar.gz. All you have to tell ircleanest is the > resolution at which the scan was taken. An approximately 5 year old Pentium > 4, 3.40GHz needs about 14 secs to clean a 4979 * 3330 image (slide scanned > at 2700 dpi) though gprof reports only 5.09 secs. A two year old Phenom x4 > 64-bit needs 7 - 8 secs with gprof reporting about 4.75 secs. > > Would code for dirt removal be acceptable in a SANE backend or in > sanei_magic? > Regards > Michael > > > -- > sane-devel mailing list: sane-devel at lists.alioth.debian.org > http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/sane-devel > Unsubscribe: Send mail with subject "unsubscribe your_password" > ? ? ? ? ? ?to sane-devel-request at lists.alioth.debian.org > -- "The truth is an offense, but not a sin"