SANEI 1.3.1.72-4c77c
Data Structures | Macros | Functions
sanei_ir.h File Reference

This file provides an interface to the sanei_ir functions for utilizing the infrared plane. More...

Go to the source code of this file.

Data Structures

union  SANEI_IR_bufptr
 Pointer to access values of different bit depths. More...
 

Macros

#define SAMPLE_SIZE   40000
 maximal for random sampling
 
#define HISTOGRAM_SHIFT   8
 standard histogram size
 
#define SAFE_LOG(x)   ( ((x) > 0.0) ? log ((x)) : (0.0) )
 define log (0) = 0
 
#define MAD_WIN2_SIZE(x)   ( (((x) * 4) / 3) | 1 )
 MAD filter: 2nd window size.
 

Functions

void sanei_ir_init (void)
 Initialize sanei_ir. More...
 
SANE_Status sanei_ir_create_norm_histogram (const SANE_Parameters *params, const SANE_Uint *img_data, double **histogram)
 Create the normalized histogram of a grayscale image. More...
 
SANE_Status sanei_ir_threshold_yen (const SANE_Parameters *params, double *norm_histo, int *thresh)
 Implements Yen's thresholding method. More...
 
SANE_Status sanei_ir_threshold_otsu (const SANE_Parameters *params, double *norm_histo, int *thresh)
 Implements Otsu's thresholding method. More...
 
SANE_Status sanei_ir_threshold_maxentropy (const SANE_Parameters *params, double *norm_histo, int *thresh)
 Implements a Maximum Entropy thresholding method. More...
 
SANE_Status sanei_ir_RGB_luminance (SANE_Parameters *params, const SANE_Uint **in_img, SANE_Uint **out_img)
 Generate gray scale luminance image from separate R, G, B images. More...
 
SANE_Status sanei_ir_to_8bit (SANE_Parameters *params, const SANE_Uint *in_img, SANE_Parameters *out_params, SANE_Uint **out_img)
 Convert image from >8 bit depth to an 8 bit image. More...
 
SANE_Status sanei_ir_ln_table (int len, double **lut_ln)
 Allocate and initialize logarithmic lookup table. More...
 
SANE_Status sanei_ir_spectral_clean (const SANE_Parameters *params, double *lut_ln, const SANE_Uint *red_data, SANE_Uint *ir_data)
 Reduces red spectral overlap from an infrared image plane. More...
 
SANE_Status sanei_ir_filter_mean (const SANE_Parameters *params, const SANE_Uint *in_img, SANE_Uint *out_img, int win_rows, int win_cols)
 Optimized mean filter. More...
 
SANE_Status sanei_ir_filter_madmean (const SANE_Parameters *params, const SANE_Uint *in_img, SANE_Uint **out_img, int win_size, int a_val, int b_val)
 Find noise by adaptive thresholding. More...
 
void sanei_ir_add_threshold (const SANE_Parameters *params, const SANE_Uint *in_img, SANE_Uint *mask_img, int threshold)
 Add dark pixels to mask from static threshold. More...
 
void sanei_ir_manhattan_dist (const SANE_Parameters *params, const SANE_Uint *mask_img, unsigned int *dist_map, unsigned int *idx_map, unsigned int erode)
 Calculates minimal Manhattan distances for an image mask. More...
 
void sanei_ir_dilate (const SANE_Parameters *params, SANE_Uint *mask_img, unsigned int *dist_map, unsigned int *idx_map, int by)
 Dilate or erode a mask image. More...
 
void sanei_ir_find_crop (const SANE_Parameters *params, unsigned int *dist_map, int inner, int *edges)
 Suggest cropping for dark margins of positive film. More...
 
SANE_Status sanei_ir_dilate_mean (const SANE_Parameters *params, SANE_Uint **in_img, SANE_Uint *mask_img, int dist_max, int expand, int win_size, SANE_Bool smooth, int inner, int *crop)
 Dilate clean image parts into dirty ones and smooth int inner,. More...
 

Detailed Description

This file provides an interface to the sanei_ir functions for utilizing the infrared plane.

Copyright (C) 2012 Michael Rickmann mrick.nosp@m.ma@g.nosp@m.wdg.d.nosp@m.e

This file is part of the SANE package.

Essentially three things have to be done:

Function Documentation

◆ sanei_ir_init()

void sanei_ir_init ( void  )

Initialize sanei_ir.

Call this before any other sanei_ir function.

◆ sanei_ir_create_norm_histogram()

SANE_Status sanei_ir_create_norm_histogram ( const SANE_Parameters *  params,
const SANE_Uint *  img_data,
double **  histogram 
)

Create the normalized histogram of a grayscale image.

Parameters
[in]paramsdescribes image
[in]img_dataimage pointer { grayscale }
[out]histograman array of double with histogram
Returns
  • SANE_STATUS_GOOD - success
  • SANE_STATUS_NO_MEM - if out of memory
Note
histogram has to be freed by calling routine

◆ sanei_ir_threshold_yen()

SANE_Status sanei_ir_threshold_yen ( const SANE_Parameters *  params,
double *  norm_histo,
int *  thresh 
)

Implements Yen's thresholding method.

Parameters
[in]paramsdescribes image
[in]norm_histopoints to a normalized histogram
[out]threshfound threshold
Returns
  • SANE_STATUS_GOOD - success
  • SANE_STATUS_NO_MEM - if out of memory
  1. Yen J.C., Chang F.J., and Chang S. (1995) "A New Criterion for Automatic Multilevel Thresholding" IEEE Trans. on Image Processing, 4(3): 370-378
  2. Sezgin M. and Sankur B. (2004) "Survey over Image Thresholding Techniques and Quantitative Performance Evaluation" Journal of Electronic Imaging, 13(1): 146-165
  3. M. Emre Celebi, 06.15.2007, fourier_0.8, http://sourceforge.net/projects/fourier-ipal/
  4. ImageJ Multithresholder plugin, http://rsbweb.nih.gov/ij/plugins/download/AutoThresholder.java

◆ sanei_ir_threshold_otsu()

SANE_Status sanei_ir_threshold_otsu ( const SANE_Parameters *  params,
double *  norm_histo,
int *  thresh 
)

Implements Otsu's thresholding method.

Parameters
[in]paramsdescribes image
[in]norm_histopoints to a normalized histogram
[out]threshfound threshold
Returns
  • SANE_STATUS_GOOD - success
  • SANE_STATUS_NO_MEM - if out of memory
  1. Otsu N. (1979) "A Threshold Selection Method from Gray Level Histograms" IEEE Trans. on Systems, Man and Cybernetics, 9(1): 62-66
  2. M. Emre Celebi, 06.15.2007, fourier_0.8 http://sourceforge.net/projects/fourier-ipal/

◆ sanei_ir_threshold_maxentropy()

SANE_Status sanei_ir_threshold_maxentropy ( const SANE_Parameters *  params,
double *  norm_histo,
int *  thresh 
)

Implements a Maximum Entropy thresholding method.

Parameters
[in]paramsdescribes image
[in]norm_histopoints to a normalized histogram
[out]threshfound threshold
Returns
  • SANE_STATUS_GOOD - success
  • SANE_STATUS_NO_MEM - if out of memory
  1. Kapur J.N., Sahoo P.K., and Wong A.K.C. (1985) "A New Method for Gray-Level Picture Thresholding Using the Entropy of the Histogram" Graphical Models and Image Processing, 29(3): 273-285
  2. M. Emre Celebi, 06.15.2007, fourier_0.8 http://sourceforge.net/projects/fourier-ipal/
  3. ImageJ Multithresholder plugin, http://rsbweb.nih.gov/ij/plugins/download/AutoThresholder.java

◆ sanei_ir_RGB_luminance()

SANE_Status sanei_ir_RGB_luminance ( SANE_Parameters *  params,
const SANE_Uint **  in_img,
SANE_Uint **  out_img 
)

Generate gray scale luminance image from separate R, G, B images.

Parameters
paramspoints to image description
[in]in_imgpointer to at least 3 planes of image data
[out]out_imgnewly allocated image
Returns
  • SANE_STATUS_GOOD - success
  • SANE_STATUS_NO_MEM - if out of memory
  • SANE_STATUS_UNSUPPORTED - wrong input bit depth
Note
out_img has to be freed by the calling routine.
on input params describe a single color plane, on output params are updated if image depth is scaled

◆ sanei_ir_to_8bit()

SANE_Status sanei_ir_to_8bit ( SANE_Parameters *  params,
const SANE_Uint *  in_img,
SANE_Parameters *  out_params,
SANE_Uint **  out_img 
)

Convert image from >8 bit depth to an 8 bit image.

Parameters
[in]paramspimage description
[in]in_imgpoints to input image data
[out]out_paramsif != NULL receives description of new image
[out]out_imgnewly allocated 8-bit image
Returns
  • SANE_STATUS_GOOD - success
  • SANE_STATUS_NO_MEM - if out of memory
  • SANE_STATUS_UNSUPPORTED - wrong input bit depth
Note
out_img has to be freed by the calling routine,

◆ sanei_ir_ln_table()

SANE_Status sanei_ir_ln_table ( int  len,
double **  lut_ln 
)

Allocate and initialize logarithmic lookup table.

Parameters
[in]lenlength of table, usually 1 << depth
[out]lut_lnaddress of pointer to allocated table
Returns
  • SANE_STATUS_GOOD - success
  • SANE_STATUS_NO_MEM - if out of memory
Note
natural logarithms are provided

◆ sanei_ir_spectral_clean()

SANE_Status sanei_ir_spectral_clean ( const SANE_Parameters *  params,
double *  lut_ln,
const SANE_Uint *  red_data,
SANE_Uint *  ir_data 
)

Reduces red spectral overlap from an infrared image plane.

Parameters
[in]paramspointer to image description
[in]lut_lnpointer lookup table if NULL it is dynamically handled
[in]red_datapointer to red image plane
ir_datapointer to ir image plane
Returns
  • SANE_STATUS_GOOD - success
  • SANE_STATUS_NO_MEM - if out of memory

This routine is based on the observation that the relation between the infrared value ired and the red value red of an image point can be described by ired = b + a * ln (red). First points are randomly sampled to calculate the linear regression coefficient a. Then ired' = ired - a * ln (red) is calculated for each pixel. Finally, the ir' image is scaled between 0 and maximal value. For the logarithms a lookup table is used. Negative films show very little spectral overlap but positive film usually has to be cleaned. As we do a statistical measure of the film here dark margins and lumps of dirt have to be excluded.

Note
original ired data are replaced by the cleaned ones

◆ sanei_ir_filter_mean()

SANE_Status sanei_ir_filter_mean ( const SANE_Parameters *  params,
const SANE_Uint *  in_img,
SANE_Uint *  out_img,
int  win_rows,
int  win_cols 
)

Optimized mean filter.

Parameters
[in]paramspointer to image description
[in]in_imgPointer to grey scale image data
[out]out_imgPointer to grey scale image data
[in]win_rowsHeight of filtering window, odd
[in]win_colsWidth of filtering window, odd
Returns
  • SANE_STATUS_GOOD - success
  • SANE_STATUS_NO_MEM - if out of memory
  • SANE_STATUS_INVAL - wrong window size
Note
At the image margins the size of the filtering window is adapted. So there is no need to pad the image.
Memory for the output image has to be allocated before

◆ sanei_ir_filter_madmean()

SANE_Status sanei_ir_filter_madmean ( const SANE_Parameters *  params,
const SANE_Uint *  in_img,
SANE_Uint **  out_img,
int  win_size,
int  a_val,
int  b_val 
)

Find noise by adaptive thresholding.

Parameters
[in]paramspointer to image description
[in]in_imgpointer to grey scale image
[out]out_imgaddress of pointer to newly allocated binary image
[in]win_sizeSize of filtering window
[in]a_valParameter, below is definitely clean
[in]b_valParameter, above is definitely noisy
Returns
  • SANE_STATUS_GOOD - success
  • SANE_STATUS_NO_MEM - if out of memory

This routine follows the concept of Crnojevic's MAD (median of the absolute deviations from the median) filter. The first median filter step is replaced with a mean filter. The dirty pixels which we wish to remove are always darker than the real signal. But at high resolutions the scanner may generate some noise and the ired cleaning step can reverse things. So a maximum filter will not do. The second median is 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" are still valid when scaled to the color depth.

@reco Crnojevic recommends 10 < a_val < 30 and 50 < b_val < 100 for 8 bit color depth

Note
a_val, b_val are scaled by the routine according to bit depth
"0" in the mask output is regarded "dirty", 255 "clean"
  1. Crnojevic V. (2005) "Impulse Noise Filter with Adaptive Mad-Based Threshold" Proc. of the IEEE Int. Conf. on Image Processing, 3: 337-340

◆ sanei_ir_add_threshold()

void sanei_ir_add_threshold ( const SANE_Parameters *  params,
const SANE_Uint *  in_img,
SANE_Uint *  mask_img,
int  threshold 
)

Add dark pixels to mask from static threshold.

Parameters
[in]paramspointer to image description
[in]in_imgpointer to grey scale image
mask_imgpointer to binary image (0, 255)
[in]thresholdbelow which the pixel is set 0

◆ sanei_ir_manhattan_dist()

void sanei_ir_manhattan_dist ( const SANE_Parameters *  params,
const SANE_Uint *  mask_img,
unsigned int *  dist_map,
unsigned int *  idx_map,
unsigned int  erode 
)

Calculates minimal Manhattan distances for an image mask.

Parameters
[in]paramspointer to image description
[in]mask_imgpointer to binary image (0, 255)
[out]dist_mapinteger pointer to map of closest distances
[out]idx_mapinteger pointer to indices of closest pixels
[in]erode== 0: closest pixel has value 0, != 0: is 255

manhattan_dist takes a mask image consisting of 0 or 255 values. Given that a 0 represents a dirty pixel and erode != 0, manhattan_dist will calculate the shortest distance to a clean (255) pixel and record which pixel that was so that the clean parts of the image can be dilated into the dirty ones. Thresholding can be done on the distance. Conversely, if erode == 0 the distance of a clean pixel to the closest dirty one is calculated which can be used to dilate the mask.

extended and C version of http://ostermiller.org/dilate_and_erode.html

◆ sanei_ir_dilate()

void sanei_ir_dilate ( const SANE_Parameters *  params,
SANE_Uint *  mask_img,
unsigned int *  dist_map,
unsigned int *  idx_map,
int  by 
)

Dilate or erode a mask image.

Parameters
[in]paramspointer to image description
mask_imgpointer to binary image (0, 255)
dist_mapinteger pointer to map of closest distances
idx_mapinteger pointer to indices of closest pixels
[in]bynumber of pixels, > 0 dilate, < 0 erode
Note
by > 0 will enlarge the 0 valued area

◆ sanei_ir_find_crop()

void sanei_ir_find_crop ( const SANE_Parameters *  params,
unsigned int *  dist_map,
int  inner,
int *  edges 
)

Suggest cropping for dark margins of positive film.

Parameters
[in]paramspointer to image description
[in]dist_mapinteger pointer to map of closest distances
[in]innercrop within (!=0) or outside (==0) the image's edges
[out]edgespointer to array holding top, bottom, left and right edges

The distance map as calculated by sanei_ir_manhattan_dist contains distances to the next clean pixel. Dark margins are detected as dirt. So the first/last rows/columns tell us how to crop. This is rather fast if the distance map has been calculated anyhow.

◆ sanei_ir_dilate_mean()

SANE_Status sanei_ir_dilate_mean ( const SANE_Parameters *  params,
SANE_Uint **  in_img,
SANE_Uint *  mask_img,
int  dist_max,
int  expand,
int  win_size,
SANE_Bool  smooth,
int  inner,
int *  crop 
)

Dilate clean image parts into dirty ones and smooth int inner,.

Parameters
[in]paramspointer to image description
in_imgarray of pointers to color planes of image
[in]mask_imgpointer to dirt mask image
[in]dist_maxthreshold up to which dilation is done
[in]expandthe dirt mask before replacing the pixels
[in]win_sizesize of adaptive mean filtering window
[in]smoothtriangular filter whole image for grain removal
[in]innerfind crop within or outside the image's edges
[out]croparray of 4 integers, if non-NULL, top, bottom, left and right values for cropping are returned.
Returns
  • SANE_STATUS_GOOD - success
  • SANE_STATUS_NO_MEM - if out of memory

The main purpose of this routine is to replace dirty pixels. As spin-off it obtains half of what is needed for film grain smoothening and most of how to crop positive film. To speed things up these functions are also implemented.