Filtering of CPL images.


Defines

#define assure(x)   assert(x)
#define mybool   unsigned char
#define mytrue   1
#define myfalse   0
#define OUT_TYPE   IN_TYPE
#define S_SWAP(SCA, i, j)
#define BITS   64
#define sort3(p0, p1, p2, i0, i1, i2)
 sort 3 elements

Functions

static void qsort_int (unsigned *SCA, unsigned n, const IN_TYPE *image)
 quick sort
static void SCA_init (dheap *dh, unsigned x)
 initialize sorted column array
static void SCA_replace (dheap *dh, unsigned x, unsigned yold, unsigned ynew)
 Update sorted column array.
static void HEAP_SWAP (unsigned i, unsigned j, unsigned int *B, unsigned int *heaps)
 Swap elements in double heap.
static void median (dheap *dh)
 Partion double heaps array in median and upper/lower values.
static unsigned bubble_down_gt (const IN_TYPE *image, unsigned *B, unsigned *heaps, unsigned m, unsigned m1, unsigned root)
 bubble down (towards leaves) in upper heap
static unsigned bubble_up_gt (const IN_TYPE *image, unsigned *B, unsigned *heaps, unsigned m1, unsigned child)
 bubble up (towards root) in upper heap
static void heapify_gt (dheap *dh)
 establish upper heap
static unsigned bubble_down_lt (const IN_TYPE *image, unsigned *B, unsigned *heaps, unsigned end, unsigned root)
 bubble down in lower heap
static unsigned bubble_up_lt (const IN_TYPE *image, unsigned *B, unsigned *heaps, unsigned child)
 bubble up in lower heap
static void heapify_lt (dheap *dh)
 establish lower heap
static void dheap_establish (dheap *dh)
 Initialize double heap.
static dheap * dheap_new (const IN_TYPE *image, unsigned Nx, unsigned Ny, unsigned rx, unsigned ry)
 double heap constructor
static void dheap_delete (dheap *dh)
 double heap destructor
static IN_TYPE dheap_median (const dheap *dh)
 get current median
static void dheap_replace (const IN_TYPE *image, unsigned *B, unsigned *heaps, unsigned m, unsigned m1, unsigned anew, unsigned aold)
 Insert and remove element in double heap.
static IN_TYPE get_kth (IN_TYPE *a, unsigned n, int k)
static IN_TYPE max3 (IN_TYPE p0, IN_TYPE p1, IN_TYPE p2)
 max of 3 elements
static IN_TYPE min3 (IN_TYPE p0, IN_TYPE p1, IN_TYPE p2)
 min of 3 elements
static IN_TYPE median5 (IN_TYPE p0, IN_TYPE p1, IN_TYPE p2, IN_TYPE p3, IN_TYPE p4)
 median of 5
static IN_TYPE median9_2 (IN_TYPE p0, IN_TYPE p1, IN_TYPE p2, IN_TYPE p3, IN_TYPE p4, IN_TYPE p5, IN_TYPE p6, IN_TYPE p7, IN_TYPE p8)
 median of 9
static IN_TYPE median9_1 (IN_TYPE p0, IN_TYPE p1, IN_TYPE p2, IN_TYPE p3, IN_TYPE p4, IN_TYPE p5, IN_TYPE p6, IN_TYPE p7, IN_TYPE p8)
 median of 9
static void filter_median_1 (const IN_TYPE *in, OUT_TYPE *out, unsigned Nx, unsigned Ny, unsigned border_mode)
 fast 3x3 image median filter
static void filter_median (const IN_TYPE *in, OUT_TYPE *out, unsigned Nx, unsigned Ny, unsigned rx, unsigned ry, unsigned border_mode)
 Fast, any bit-depth, image median filter.
static void irplib_image_filter_double_double (double *, const double *, int, int, int, int, unsigned)
static void irplib_image_filter_double_float (double *, const float *, int, int, int, int, unsigned)
static void irplib_image_filter_double_int (double *, const int *, int, int, int, int, unsigned)
static void irplib_image_filter_float_double (float *, const double *, int, int, int, int, unsigned)
static void irplib_image_filter_float_float (float *, const float *, int, int, int, int, unsigned)
static void irplib_image_filter_float_int (float *, const int *, int, int, int, int, unsigned)
static void irplib_image_filter_int_double (int *, const double *, int, int, int, int, unsigned)
static void irplib_image_filter_int_float (int *, const float *, int, int, int, int, unsigned)
static void irplib_image_filter_int_int (int *, const int *, int, int, int, int, unsigned)
cpl_error_code irplib_image_filter (cpl_image *self, const cpl_image *other, int hsizex, int hsizey, irplib_filter_mode mode)
 Filter an image.

Detailed Description

Synopsis:
     #include <irplib_filter.h>
Example:

Define Documentation

#define S_SWAP ( SCA,
i,
 ) 

Value:

do { \
    const unsigned SCAi = SCA[i]; \
    const unsigned SCAj = SCA[j]; \
    SCA[i] = SCAj; \
    SCA[j] = SCAi; \
} while(0)

Definition at line 75 of file filter_median.c.

Referenced by qsort_int(), and SCA_replace().

#define sort3 ( p0,
p1,
p2,
i0,
i1,
i2   ) 

Value:

do {                                                          \
    if (i0 <= i1) {                                           \
        if (i1 <= i2) {                                       \
             p0 = i0; p1 = i1; p2 = i2;                       \
        } else if (i0 <= i2) {                                \
            /* i0, i2, i1 */                                  \
            p0 = i0; p1 = i2; p2 = i1;                        \
        } else {                                              \
            /*  i2, i0, i1 */                                 \
            p0 = i2; p1 = i0; p2 = i1;                        \
        }                                                     \
    } else {                                                  \
        if (i0 <= i2) {                                       \
            /* i1, i0, i2 */                                  \
            p0 = i1; p1 = i0; p2 = i2;                        \
        } else if (i1 < i2) {                                 \
            /* i1, i2, i0 */                                  \
            p0 = i1; p1 = i2; p2 = i0;                        \
        } else {                                              \
            /* i2, i1, i0 */                                  \
            p0 = i2; p1=i1; p2 = i0;                          \
        }                                                     \
    }                                                         \
} while(0)
sort 3 elements

Parameters:
p0 (out) rank 1
p1 (out) rank 2
p2 (out) rank 3
i0 (in) element
i1 (in) element
i2 (in) element
Cost: 2 (probability 1/3) or 3 (probability 2/3) = 8/3 = 2.66 comparisons

Definition at line 956 of file filter_median.c.

Referenced by filter_median_1().


Function Documentation

static void qsort_int ( unsigned *  SCA,
unsigned  n,
const IN_TYPE *  image 
) [static]

quick sort

Parameters:
SCA sorted column array to be sorted
n length of SCA
image input image
SCA is sorted in increasing order by image[SCA[i]]

Definition at line 94 of file filter_median.c.

References BITS, and S_SWAP.

Referenced by SCA_init().

static void SCA_init ( dheap *  dh,
unsigned  x 
) [static]

initialize sorted column array

Parameters:
dh double heap
x current column

Definition at line 179 of file filter_median.c.

References qsort_int().

Referenced by dheap_new(), and filter_median().

static void SCA_replace ( dheap *  dh,
unsigned  x,
unsigned  yold,
unsigned  ynew 
) [static]

Update sorted column array.

Parameters:
dh double heap
x current column
yold image row of previous element
ynew image row of new element

Definition at line 203 of file filter_median.c.

References S_SWAP.

Referenced by filter_median().

static void HEAP_SWAP ( unsigned  i,
unsigned  j,
unsigned int *  B,
unsigned int *  heaps 
) [static]

Swap elements in double heap.

Parameters:
i index in heaps array
j index in heaps array
B image to heap map
heaps heaps array

Definition at line 265 of file filter_median.c.

Referenced by bubble_down_gt(), bubble_down_lt(), bubble_up_gt(), bubble_up_lt(), dheap_replace(), and median().

static void median ( dheap *  dh  )  [static]

Partion double heaps array in median and upper/lower values.

Parameters:
dh double heap with elements in no particular order

Definition at line 286 of file filter_median.c.

References HEAP_SWAP().

Referenced by dheap_establish(), irplib_spectrum_find_brightest(), opt_measure_profile_order(), uves_average_reject(), and uves_get_blaze_ratio().

static unsigned bubble_down_gt ( const IN_TYPE *  image,
unsigned *  B,
unsigned *  heaps,
unsigned  m,
unsigned  m1,
unsigned  root 
) [static]

bubble down (towards leaves) in upper heap

Parameters:
image input image
B inverse map
heaps double heap array
m heap size
m1 m + 1
root double heap position
Returns:
final position

Definition at line 332 of file filter_median.c.

References HEAP_SWAP().

Referenced by dheap_replace(), and heapify_gt().

static unsigned bubble_up_gt ( const IN_TYPE *  image,
unsigned *  B,
unsigned *  heaps,
unsigned  m1,
unsigned  child 
) [static]

bubble up (towards root) in upper heap

Parameters:
image input image
B inverse map
heaps double heap array
m1 heap size + 1
child double heap position
Returns:
final position

Definition at line 372 of file filter_median.c.

References HEAP_SWAP().

Referenced by dheap_replace().

static void heapify_gt ( dheap *  dh  )  [static]

establish upper heap

Parameters:
dh double heap

Definition at line 398 of file filter_median.c.

References bubble_down_gt().

Referenced by dheap_establish().

static unsigned bubble_down_lt ( const IN_TYPE *  image,
unsigned *  B,
unsigned *  heaps,
unsigned  end,
unsigned  root 
) [static]

bubble down in lower heap

Parameters:
image input image
B inverse map
heaps double heap array
end double heap last position
root double heap position
Returns:
final position

Definition at line 423 of file filter_median.c.

References HEAP_SWAP().

Referenced by dheap_replace(), and heapify_lt().

static unsigned bubble_up_lt ( const IN_TYPE *  image,
unsigned *  B,
unsigned *  heaps,
unsigned  child 
) [static]

bubble up in lower heap

Parameters:
image input image
B inverse map
heaps double heap array
child double heap position
Returns:
final position

Definition at line 459 of file filter_median.c.

References HEAP_SWAP().

Referenced by dheap_replace().

static void heapify_lt ( dheap *  dh  )  [static]

establish lower heap

Parameters:
dh double heap

Definition at line 483 of file filter_median.c.

References bubble_down_lt().

Referenced by dheap_establish().

static void dheap_establish ( dheap *  dh  )  [static]

Initialize double heap.

Parameters:
dh double heap with elements in no particular order

Definition at line 502 of file filter_median.c.

References heapify_gt(), heapify_lt(), and median().

Referenced by dheap_new().

static dheap* dheap_new ( const IN_TYPE *  image,
unsigned  Nx,
unsigned  Ny,
unsigned  rx,
unsigned  ry 
) [static]

double heap constructor

Parameters:
image input image
Nx image width
Ny image height
rx filtering half-size in x
ry filtering half-size in y
Returns:
newly allocated double heap which may be destroyed using dheap_delete()
The double heap, inverse map and SCA invariants are established using the first image window

Definition at line 525 of file filter_median.c.

References assure, dheap_establish(), and SCA_init().

Referenced by filter_median().

static void dheap_delete ( dheap *  dh  )  [static]

double heap destructor

Parameters:
dh double heap

Definition at line 578 of file filter_median.c.

static IN_TYPE dheap_median ( const dheap *  dh  )  [static]

get current median

Parameters:
dh double heap
Returns:
the median element value

Definition at line 594 of file filter_median.c.

Referenced by filter_median().

static void dheap_replace ( const IN_TYPE *  image,
unsigned *  B,
unsigned *  heaps,
unsigned  m,
unsigned  m1,
unsigned  anew,
unsigned  aold 
) [static]

Insert and remove element in double heap.

Parameters:
image input image
B inverse map
heaps double heap array
m heap size
m1 m + 1
anew image index of pixel to be inserted
aold image index of pixel to be removed
Note: Uses static memory, not thread-safe

Algorithm: The inverse map is used to quickly locate the old pixel, which is replaced, and the new element bubbled to a (non-unique) correct position until the double heap structure is re-established. The inverse map is maintained while swapping heap elements.

Definition at line 617 of file filter_median.c.

References bubble_down_gt(), bubble_down_lt(), bubble_up_gt(), bubble_up_lt(), HEAP_SWAP(), mybool, myfalse, and mytrue.

Referenced by filter_median().

static IN_TYPE max3 ( IN_TYPE  p0,
IN_TYPE  p1,
IN_TYPE  p2 
) [static]

max of 3 elements

Parameters:
p0 element
p1 element
p2 element
Returns:
maximum element
Cost: 2 comparisons

Definition at line 797 of file filter_median.c.

Referenced by median5().

static IN_TYPE min3 ( IN_TYPE  p0,
IN_TYPE  p1,
IN_TYPE  p2 
) [static]

min of 3 elements

Parameters:
p0 element
p1 element
p2 element
Returns:
minimum element
Cost: 2 comparisons

Definition at line 818 of file filter_median.c.

Referenced by median5().

static IN_TYPE median5 ( IN_TYPE  p0,
IN_TYPE  p1,
IN_TYPE  p2,
IN_TYPE  p3,
IN_TYPE  p4 
) [static]

median of 5

Parameters:
p0 element
p1 element
p2 element
p3 element
p4 element
Returns:
median
Precondition: p0 <= p1 <= p2

Cost: 2 + 0 (probability 4/7) or 2 + 2 (probability 3/7) = 20/7 = 2.86 comparisons

Definition at line 846 of file filter_median.c.

References max3(), and min3().

Referenced by median9_2().

static IN_TYPE median9_2 ( IN_TYPE  p0,
IN_TYPE  p1,
IN_TYPE  p2,
IN_TYPE  p3,
IN_TYPE  p4,
IN_TYPE  p5,
IN_TYPE  p6,
IN_TYPE  p7,
IN_TYPE  p8 
) [static]

median of 9

Parameters:
p0 element
p1 element
p2 element
p3 element
p4 element
p5 element
p6 element
p7 element
p8 element
Returns:
median
Precondition: p0 <= p1 <= p2 p3 <= p4 <= p5 p6 <= p7 <= p8 p1 <= p4

Cost: 1 + 2.86 (probability 1/3) or 2 + 2.86 (probability 2/3) = 95/21 = 4.52 comparisons

Definition at line 891 of file filter_median.c.

References median5().

Referenced by median9_1().

static IN_TYPE median9_1 ( IN_TYPE  p0,
IN_TYPE  p1,
IN_TYPE  p2,
IN_TYPE  p3,
IN_TYPE  p4,
IN_TYPE  p5,
IN_TYPE  p6,
IN_TYPE  p7,
IN_TYPE  p8 
) [static]

median of 9

Parameters:
p0 element
p1 element
p2 element
p3 element
p4 element
p5 element
p6 element
p7 element
p8 element
Returns:
median
Precondition: p0 <= p1 <= p2 p3 <= p4 <= p5 p6 <= p7 <= p8

Cost: 1 + 4.52 = 116/21 = 5.52 comparisons

Definition at line 929 of file filter_median.c.

References median9_2().

Referenced by filter_median_1().

static void filter_median_1 ( const IN_TYPE *  in,
OUT_TYPE *  out,
unsigned  Nx,
unsigned  Ny,
unsigned  border_mode 
) [static]

fast 3x3 image median filter

Parameters:
in image to filter
out pre-allocated output image, must not overlap with the input image
Nx image width
Ny image height
border_mode periodic boundaries

Definition at line 994 of file filter_median.c.

References assure, get_kth(), median9_1(), OUT_TYPE, and sort3.

Referenced by filter_median().

static void filter_median ( const IN_TYPE *  in,
OUT_TYPE *  out,
unsigned  Nx,
unsigned  Ny,
unsigned  rx,
unsigned  ry,
unsigned  border_mode 
) [static]

Fast, any bit-depth, image median filter.

Parameters:
in image to filter
out pre-allocated output image, may not overlap with the input image
Nx image width
Ny image height
rx filtering half-size in x, non-negative
ry filtering half-size in y, non-negative
border_mode Handling of the pixels near the border 0: the border is not processed 1: border copy 2: constant extrapolation 3: median of fewer values
Unsupported filter modes: In-place: Possible using a pixel buffer of dimension (Nx + 2Rx) * (1 + 2Ry) Unsupported border modes: Crop: The dimension of the output image is Mx = Nx - 2Rx, My = Ny - 2Ry

For each pixel in the image the median of a (2*Rx + 1)(2*Ry + 1) window is computed.

The straightforward approach is to loop over the image and build and sort the kernel array for every pixel. This leads to an O(RxRy log RxRy) algorithm, or O(RxRy) if the median is computed by repeated partitions.

The basic idea in this implementation is to maintain a double heap structure of the running window pixels:

_____ \ / <-- minimum heap of elements greater than the median \ / . <-- median

/ \ <-- maximum heap of elements less than the median / \ -----

With every 1 pixel shift of the running window (2Ry + 1) pixels have to be removed from the double heap, and another (2Ry + 1) pixels must be inserted. The worst case time for inserting/removing one element is two heap heights, O(log RxRy), so the overall time is O(Ry log RxRy).

Various tricks improve the performance

Rather than sorting every time the (2Ry + 1) new and old values (which would cost O(Ry log Ry), a sorted array of the current pixels is maintained for every column in the image. To update the sorted column arrays (SCA) only one pixel needs to be inserted/removed per iteration. When using simple linear search and insertion, the maintenance cost for the SCAs is O(Ry). A possible optimization not pursued here is to implement the SCAs as balanced binary search trees, which would reduce their maintenance cost to O(log Ry) (but the heap maintenance cost would still be O(Ry).

Performance: While the theoretical time complexity is O(Ry log RxRy), the empirical behaviour (for realistic size images with random, uncorrelated pixels from the same probability distribution) is O(Ry) with small constant coefficients.

Rx = Ry = 1 is handled as a separate case.

Definition at line 1311 of file filter_median.c.

References assure, dheap_median(), dheap_new(), dheap_replace(), filter_median_1(), OUT_TYPE, SCA_init(), and SCA_replace().

cpl_error_code irplib_image_filter ( cpl_image *  self,
const cpl_image *  other,
int  hsizex,
int  hsizey,
irplib_filter_mode  mode 
)

Filter an image.

Parameters:
self Filtered image
other Image to filter
hsizex Filtering half-size in x, total size is 1 + 2 * hsizex
hsizey Filtering half-size in y, total size is 1 + 2 * hsizey
mode Filter mode binary or-ed with border handling mode
Returns:
CPL_ERROR_NONE or the relevant CPL error code
Note:
A bad pixel map in any of the two images is ignored.
Filter modes: IRPLIB_FILTER_AVERAGE An avering filter, i.e. the output pixel is the average of the surrounding (1 + 2 * hsizex) (1 + 2 * hsizey) pixels. This filter uses a running average, which means that the rounding errors are greater than when using brute-force averaging. The cost per ouput pixel is O(1). The two images may have different pixel types. When the input and output pixel types are identical, the arithmetic is done with that type, e.g. int for two integer images. When the input and output pixel types differ, the arithmetic is done in double precision when one of the two images have pixel type CPL_TYPE_DOUBLE, otherwise float is used. Supports border mode IRPLIB_FILTER_BORDER_FILTER. IRPLIB_FILTER_MEDIAN A median filter. The pixel types of the input and output images must be identical (since a resulting median value must be one of the input pixels). For hsizex == hsizey == 1 all border modes are supported, othersize IRPLIB_FILTER_BORDER_NOP is supported.

Border modes: IRPLIB_FILTER_BORDER_NOP: Do not modify the border of the filtered image (This is the default mode). IRPLIB_FILTER_BORDER_CROP: Crop filtered image IRPLIB_FILTER_BORDER_FILTER: Filter the border using the reduced number of pixels. If in median filterring the number of pixels is even choose any one of the two central values. (For hsizex * hsizey == 1 the chosen value is always the lower one). IRPLIB_FILTER_BORDER_COPY: Copy the border of the raw image IRPLIB_FILTER_BORDER_EXTRAPOL_OUT: Extrapolate computed medians to border

Example:
      irplib_image_filter(filtered, raw, 1, 1, IRPLIB_FILTER_MEDIAN |
                                               IRPLIB_FILTER_BORDER_FILTER);

Definition at line 166 of file irplib_filter.c.


Generated on Thu Nov 15 14:32:37 2007 for UVES Pipeline Reference Manual by  doxygen 1.5.1