ifw-odp  2.0.0-alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Macros
clipm_priv_image_edge_operations.c File Reference
#include "clipm_priv_image_edge_operations.h"
#include "clipm_math.h"
#include "clipm_priv_image.h"
#include "clipm_priv_image_signal.h"
#include "clipm_priv_checks.h"
#include "clipm_compatibility_replacements.h"
#include "clipm_priv_error.h"

Macros

#define _clipm_priv_image_polar2cartesian_BODY(CTYPE)
 
#define clipm_priv_image_compute_angles_BODY(CTYPE)
 
#define clipm_priv_image_compute_pythagoras_BODY(CTYPE)
 
#define clipm_priv_image_compute_mean_angle_BODY(CTYPE, BUFFERSTART, IMSIZE, WINDOWSIZE, W_DATA, A_DATA, W_BPM, A_BPM, PERIODICITY, ANGLE, NORM)
 
#define clipm_priv_image_compute_angular_uniformity_BODY(CTYPE)
 
#define clipm_priv_image_LOOP_GOOD_2DATA_CONST(TYPE, IMSIZE_XY, WDWSIZE_XY, DATA1_WDW, BADP1_WDW, DATA2_WDW, BADP2_WDW, YACTION, XACTION, XACTION_BAD)
 Loop over a pixel buffer, only regarding good pixels. More...
 
cpl_error_code clipm_priv_image_compute_gradients (const cpl_image *input, const cpl_size window_xxyy[4], cpl_image **out_magnitudes, cpl_image **out_angles)
 Compute image gradients. More...
 
cpl_image * clipm_priv_image_conv_sobel_x (const cpl_image *input, const cpl_size window_xxyy[4])
 Convolve image with horizontal Sobel operator. More...
 
cpl_image * clipm_priv_image_conv_sobel_y (const cpl_image *input, const cpl_size window_xxyy[4])
 Convolve image with vertical Sobel operator. More...
 
cpl_image * clipm_priv_image_compute_angles (const cpl_image *grad_x, const cpl_image *grad_y)
 Calculate the angles of a gradient field. More...
 
cpl_image * clipm_priv_image_compute_pythagoras (const cpl_image *input1, const cpl_image *input2)
 Calculate the Pythagoras of two images. More...
 
double clipm_priv_image_compute_mean_angle (const cpl_image *magnitudes, const cpl_image *angles, const cpl_size window_xxyy[4], double periodic_factor, double *out_norm)
 Compute the mean of an angle-field inside a window. More...
 
cpl_error_code clipm_priv_image_compute_mean_gradients (const cpl_image *magnitudes, const cpl_image *angles, const cpl_size window_xxyy[4], double periodic_factor, double radius_sigma, cpl_image **mean_magnitudes, cpl_image **mean_angles)
 Lowpass gradients after applying a periodic factor. More...
 
cpl_image * clipm_priv_image_compute_angular_uniformity (const cpl_image *magnitudes, const cpl_image *angles, const cpl_size window_xxyy[4], double radius_sigma, double periodic_factor)
 Compute an indicator for a uniform pointing direction of gradients. More...
 

Macro Definition Documentation

#define _clipm_priv_image_polar2cartesian_BODY (   CTYPE)
#define clipm_priv_image_compute_angles_BODY (   CTYPE)
Value:
do { \
const CTYPE *x, *y; \
CTYPE *r; \
cpl_size n; \
result = cpl_image_new(size_x, size_y, type)); \
x = cpl_image_get_data_const(grad_x); \
y = cpl_image_get_data_const(grad_y); \
r = cpl_image_get_data(result); \
for (n = 0; n < totalsize; n++) \
*(r++) = (CTYPE)clipm_math_arctan_0to2pi(*(x++), *(y++)); \
} while (0)
double clipm_math_arctan_0to2pi(double x, double y)
Compute the arcus tangens for the whole angle range.
Definition: clipm_math.c:48
#define CLIPM_TRY_CHECK_ERROR_STATE(void)
Check the CPL error state, and exit the try-block if not CPL_ERROR_NONE.
Definition: clipm_priv_error.h:362
#define CLIPM_TRY_EXIT_IFN(condition)
If condition == 0, then the try-block is exited.
Definition: clipm_priv_error.h:461
#define clipm_priv_image_compute_angular_uniformity_BODY (   CTYPE)
Value:
do { \
cpl_binary *r_bpm; \
const cpl_binary *m_bpm; \
CTYPE *rdata; \
const CTYPE *mdata; \
\
rdata = cpl_image_get_data(result); \
mdata = cpl_image_get_data_const(mean_magnitudes); \
\
r_bpm = cpl_mask_get_data(cpl_image_get_bpm(result)); \
\
m_bpm = clipm_priv_image_bpm_get_if_exist(mean_magnitudes); \
size, \
size, \
rdata, /*data1*/\
r_bpm, \
mdata, /*data2*/\
m_bpm, \
\
, \
if (data2[x] > 1e-9) \
((CTYPE*)data1)[x] /= data2[x]; \
, \
((cpl_binary*)badp1)[x] = CPL_BINARY_1; \
); \
} while (0)
#define CLIPM_TRY_ASSERT_ERROR_STATE(void)
Assert that the CPL error state is CPL_ERROR_NONE, otherwise set a custom bugreport message and exit ...
Definition: clipm_priv_error.h:403
#define clipm_priv_image_LOOP_GOOD_2DATA_CONST(TYPE, IMSIZE_XY, WDWSIZE_XY, DATA1_WDW, BADP1_WDW, DATA2_WDW, BADP2_WDW, YACTION, XACTION, XACTION_BAD)
Loop over a pixel buffer, only regarding good pixels.
Definition: clipm_priv_image_edge_operations.c:74
const cpl_binary * clipm_priv_image_bpm_get_if_exist(const cpl_image *image)
Return bad pixel mask data, if there are bad pixels, otherwise NULL.
Definition: clipm_priv_image.c:633
#define clipm_priv_image_compute_mean_angle_BODY (   CTYPE,
  BUFFERSTART,
  IMSIZE,
  WINDOWSIZE,
  W_DATA,
  A_DATA,
  W_BPM,
  A_BPM,
  PERIODICITY,
  ANGLE,
  NORM 
)
#define clipm_priv_image_compute_pythagoras_BODY (   CTYPE)
Value:
do { \
const CTYPE *a, *b; \
CTYPE *r; \
cpl_size n; \
result = cpl_image_new(size_x, size_y, type)); \
a = cpl_image_get_data_const(input1); \
b = cpl_image_get_data_const(input2); \
r = cpl_image_get_data(result); \
\
for (n = 0; n < totalsize; n++) \
*(r++) = sqrt(a[n]*a[n] + b[n]*b[n]); \
} while (0)
#define CLIPM_TRY_CHECK_ERROR_STATE(void)
Check the CPL error state, and exit the try-block if not CPL_ERROR_NONE.
Definition: clipm_priv_error.h:362
#define CLIPM_TRY_EXIT_IFN(condition)
If condition == 0, then the try-block is exited.
Definition: clipm_priv_error.h:461
#define clipm_priv_image_LOOP_GOOD_2DATA_CONST (   TYPE,
  IMSIZE_XY,
  WDWSIZE_XY,
  DATA1_WDW,
  BADP1_WDW,
  DATA2_WDW,
  BADP2_WDW,
  YACTION,
  XACTION,
  XACTION_BAD 
)

Loop over a pixel buffer, only regarding good pixels.

Parameters
TYPEC data type (e.g. int, float, double)
IMSIZE_XYInt buffer of size 2, containing the image size [x, y]
WDWSIZE_XYInt buffer of size 2, containing the window size
DATA1_WDWPointer to image 1 data (window)
BADP1_WDWPointer to bad pixel mask 1 data (window)
DATA2_WDWPointer to image 2 data (window)
BADP2_WDWPointer to bad pixel mask 2 data (window)
YACTIONAction to perform first in each row
XACTIONAction to always perform per good pixel
XACTION_BADAction to always perform per bad pixel

Function Documentation

cpl_image* clipm_priv_image_compute_angles ( const cpl_image *  grad_x,
const cpl_image *  grad_y 
)

Calculate the angles of a gradient field.

Parameters
grad_xImage representing the horizontal gradients
grad_yImage representing the vertical gradients
Returns
Image containing the angle field in the range $[0\ldots 2\pi]$, NULL in the case of error
Constraints:
  • The input images must be of the same cpl_type and size.
  • The cpl_type of the input images must be one of CPL_TYPE_FLOAT or CPL_TYPE_DOUBLE.
  • The created output image is of the same type as the input images.
Bad Pixel Handling:
  • Bad pixels in any input image will produce bad pixels in the output.
Error Handling
The following error codes can be set:
  • CPL_ERROR_NULL_INPUT: grad_x or grad_y is NULL
  • CPL_ERROR_TYPE_MISMATCH: grad_x and grad_y are not of the same type
  • CPL_ERROR_INVALID_TYPE: grad_x and grad_y are neither of type CPL_TYPE_FLOAT nor of type CPL_TYPE_DOUBLE
  • CPL_ERROR_INCOMPATIBLE_INPUT: grad_x and grad_y don't have the same size
cpl_image* clipm_priv_image_compute_angular_uniformity ( const cpl_image *  magnitudes,
const cpl_image *  angles,
const cpl_size  window_xxyy[4],
double  radius_sigma,
double  periodic_factor 
)

Compute an indicator for a uniform pointing direction of gradients.

Parameters
magnitudesImage containing gradient magnitude values
anglesImage containing gradient angle values
window_xxyyCoordinate buffer of the form {xa, xb, ya, yb}, can be NULL, minimum/maximum order is irrelevant
radius_sigmaSigma of the gaussian region used for the lowpass
periodic_factorDivisor for the periodicity of $2\pi$
Returns
Image containing measurements in the range 0...1, NULL in the case of error
Principle:
  • Within a certain influence radius, abs(mean(vi)) / mean(abs(vi)) is computed, where vi are the individual vectors.
  • The radius is not a sharp limit, but the influence decreases with a Gaussian shape.
Constraints:
magnitudes and angles must be either of type CPL_TYPE_FLOAT or type CPL_TYPE_DOUBLE.
Bad Pixel Handling:
Pixels which are bad in either magnitudes or angles are skipped during computation.
Error Handling:
The following error codes can be set:
  • CPL_ERROR_NULL_INPUT: magnitudes or angles is NULL
  • CPL_ERROR_TYPE_MISMATCH: magnitudes and angles are not of the same type
  • CPL_ERROR_ACCESS_OUT_OF_RANGE: window coordinates are outside the images
  • CPL_ERROR_INVALID_TYPE: magnitudes and angles are neither of type CPL_TYPE_FLOAT nor of type CPL_TYPE_DOUBLE
  • CPL_ERROR_INCOMPATIBLE_INPUT: magnitudes and angles don't have the same size
  • CPL_ERROR_ILLEGAL_INPUT:
    • if periodic_factor <= 0, or
    • radius_sigma <= 0
cpl_error_code clipm_priv_image_compute_gradients ( const cpl_image *  input,
const cpl_size  window_xxyy[4],
cpl_image **  out_magnitudes,
cpl_image **  out_angles 
)

Compute image gradients.

Parameters
inputInput image
window_xxyyCoordinate buffer of the form {xa, xb, ya, yb}, can be NULL, minimum/maximum order is irrelevant
out_magnitudesPointer to ouput image for absolute gradient
out_anglesPointer to ouput image for gradient angles in the range $[0\ldots 2\pi]$
Returns
The cpl error code if any occurred
Introduction:
This function computes the absolute gradient field of the input image, and the corresponding orientation field. There are the following constraints:
  • The pointers to the output image pointers must not be NULL.
  • The input can be integer, float or double.
  • If the input is of type integer, then values of type double will be produced as output, otherwise the created output images are of the same type as the input image.
  • On failure, NULL pointers are returned.
Error Handling
The following error codes can be set and returned:
  • CPL_ERROR_NULL_INPUT: any of the input or output pointers is NULL
  • CPL_ERROR_INVALID_TYPE: input is neither of type CPL_TYPE_INT, CPL_TYPE_FLOAT, nor of type CPL_TYPE_DOUBLE
Example (omitting error handling):
*#include <cpl.h>
*#include <clipm.h>
*
*int main(void) {
* cpl_image *in_img,
* *out_absgrad,
* *out_angles;
* cpl_propertylist
* *img_header;
* const char infilename[] = "example.fits";
*
* in_img = cpl_image_load(infilename,
* CPL_TYPE_DOUBLE,
* 0,
* 0);
* img_header = cpl_propertylist_load(infilename, 0);
*
* in_img,
* &out_absgrad,
* &out_angles);
*
* cpl_image_save( out_absgrad,
* "abs_gradients.fits",
* CPL_BPP_IEEE_DOUBLE,
* image_header,
* CPL_IO_DEFAULT);
* cpl_image_save( ` out_angles,
* "grad_angles.fits",
* CPL_BPP_IEEE_DOUBLE,
* image_header,
* CPL_IO_DEFAULT);
* return 0;
*}
*
Todo:
  • Implement care for bad pixels map
double clipm_priv_image_compute_mean_angle ( const cpl_image *  magnitudes,
const cpl_image *  angles,
const cpl_size  window_xxyy[4],
double  periodic_factor,
double *  out_norm 
)

Compute the mean of an angle-field inside a window.

Parameters
magnitudesImage containing gradient magnitude values (FITS convention)
anglesImage containing local angle values (FITS convention)
window_xxyyCoordinate buffer of the form {xa, xb, ya, yb}, can be NULL, minimum/maximum order is irrelevant
periodic_factorDivisor for the periodicity of $2\pi$
out_norm(Optional output) the gradient's norm
Returns
Mean angle inside range of $\left[0\cdots \frac{2\pi}{periodic\_factor}\right]$, -1 in the case of error
Principle:
Consider a local angle $\alpha_n$, a local weight $w_n$ and a periodic factor $p$. Then the mean angle $\overline\alpha$ is determined by:

\[\overline\alpha = \frac{1}{p}\cdot\angle\left(\sum_n w_n\cdot e^{i \alpha\cdot p}\right).\]



It does not always make sense to compute a mean angle in the range $[0\ldots 2\pi]$, for example a line crossing an image has an orientation but the orientation has no sign. In this case, only angles in the range $[0\ldots\pi]$ are interesting. Therefore, the periodic factor is adjustable. For example, a periodic factor of $p=2$ causes opposite angles to fall together in the complex plane before summing, and thus to be considered the same. The final division by $p$ scales the angle back to the range $[0\ldots \pi]$. The following values for periodic_factor are of specific interest:


periodic_factorExample Purpose
1 Uni-directional (e.g. global) gradients
2 Lines and rectangular apertures
3 Equilateral triangles
4 Square apertures, crossing spikes of secondary mirror holder
6 Honeycombs
Constraints:
  • The input images must be of the same cpl_type and size.
  • The cpl_type of the input images must be one of CPL_TYPE_FLOAT or CPL_TYPE_DOUBLE.
Bad Pixel Handling:
Pixels which are bad in either magnitudes or angles are ignored during computation.
Error Handling:
The following error codes can be set:
  • CPL_ERROR_NULL_INPUT: magnitudes or angles is NULL
  • CPL_ERROR_TYPE_MISMATCH: magnitudes and angles are not of the same type
  • CPL_ERROR_ACCESS_OUT_OF_RANGE: window coordinates are outside the images
  • CPL_ERROR_INVALID_TYPE: magnitudes and angles are neither of type CPL_TYPE_FLOAT nor of type CPL_TYPE_DOUBLE
  • CPL_ERROR_INCOMPATIBLE_INPUT: magnitudes and angles don't have the same size
  • CPL_ERROR_ILLEGAL_INPUT: periodic_factor <= 0
  • CPL_ERROR_DATA_NOT_FOUND: all pixels are bad
Example (omitting error handling):
*#include <cpl.h>
*#include <clipm.h>
*#include <stdio.h>
*
*int main(void) {
* cpl_image *in_img,
* *grad_field,
* *angle_field;
* double periodic_f,
* mean_angle,
* norm;
* const char infilename[] = "example.fits";
*
* in_img = cpl_image_load(infilename,
* CPL_TYPE_DOUBLE,
* 0,
* 0);
*
* // compute gradient and angle field
* in_img,
* &grad_field,
* &angle_field);
*
* // example: want to get the orientation of parallel lines
* periodic_f = 2;
*
* // compute mean angle, use gradients for magnitude
* grad_field,
* angle_field,
* NULL,
* periodic_f,
* &norm);
*
* // we got the gradients' angle, the lines are orthogonal,
* // so add PI/2 and make sure
* // that it is inside the range 0...PI
* mean_angle = (mean_angle + CPL_MATH_PI_2) % CPL_MATH_PI;
*
* printf( "Line orientation: %.2f degrees\n",
* 180*mean_angle/CPL_MATH_PI);
* cpl_image_delete(in_img);
* cpl_image_delete(grad_field);
* cpl_image_delete(angle_field);
* return 0;
*}
*
Todo:
  • adapt cpl_error handling
  • ignore bad pixels: done
  • return also $\sqrt{|\sum/N|}$ as measurement for the quality
cpl_error_code clipm_priv_image_compute_mean_gradients ( const cpl_image *  magnitudes,
const cpl_image *  angles,
const cpl_size  window_xxyy[4],
double  periodic_factor,
double  radius_sigma,
cpl_image **  mean_magnitudes,
cpl_image **  mean_angles 
)

Lowpass gradients after applying a periodic factor.

Parameters
magnitudesImage containing gradient magnitude values (FITS convention)
anglesImage containing gradient angle values (FITS convention)
window_xxyyCoordinate buffer of the form {xa, xb, ya, yb}, can be NULL, minimum/maximum order is irrelevant
periodic_factorDivisor for the periodicity of $2\pi$
radius_sigmaSigma of the gaussian used for the lowpass
mean_magnitudes(Optional output) magnitudes of lowpassed gradients
mean_angles(Optional output) angles of lowpassed gradients
Returns
CPL error code
Principle:
The formula to compute a mean gradient from a region of gradients from function clipm_priv_image_compute_mean_angle() is used, but with the extension that the input gradients are weighted with a Gaussian bell kurve with sigma radius_sigma.
Constraints:
  • The input images must be of the same cpl_type and size.
  • The cpl_type of the input images must be one of CPL_TYPE_FLOAT or CPL_TYPE_DOUBLE.
Bad Pixel Handling:
Pixels which are bad in either magnitudes or angles are skipped during computation.
Error Handling:
The following error codes can be set:
  • CPL_ERROR_NULL_INPUT: magnitudes or angles is NULL
  • CPL_ERROR_TYPE_MISMATCH: magnitudes and angles are not of the same type
  • CPL_ERROR_ACCESS_OUT_OF_RANGE: window coordinates are outside the images
  • CPL_ERROR_INVALID_TYPE: magnitudes and angles are neither of type CPL_TYPE_FLOAT nor of type CPL_TYPE_DOUBLE
  • CPL_ERROR_INCOMPATIBLE_INPUT: magnitudes and angles don't have the same size
  • CPL_ERROR_ILLEGAL_INPUT: periodic_factor <= 0
cpl_image* clipm_priv_image_compute_pythagoras ( const cpl_image *  input1,
const cpl_image *  input2 
)

Calculate the Pythagoras of two images.

Parameters
input1First input image
input2Second input image
Returns
Output image, NULL in the case of error
Constraints:
  • The input images must be of the same cpl_type and size.
  • The cpl_type of the input images must be one of CPL_TYPE_FLOAT or CPL_TYPE_DOUBLE.
  • The created output image is of the same type as the input images.
  • The pythagoras c of two values a and b is given by $c=\sqrt{a^2+b^2}$.
Bad Pixel Handling:
  • Bad pixels in any input image will produce bad pixels in the output.
Error Handling
The following error codes can be set:
  • CPL_ERROR_NULL_INPUT: grad_x or grad_y is NULL
  • CPL_ERROR_TYPE_MISMATCH: grad_x and grad_y are not of the same type
  • CPL_ERROR_INVALID_TYPE: grad_x and grad_y are neither of type CPL_TYPE_FLOAT nor of type CPL_TYPE_DOUBLE
  • CPL_ERROR_INCOMPATIBLE_INPUT: grad_x and grad_y don't have the same size
cpl_image* clipm_priv_image_conv_sobel_x ( const cpl_image *  input,
const cpl_size  window_xxyy[4] 
)

Convolve image with horizontal Sobel operator.

Parameters
inputInput image
window_xxyyCoordinate buffer of the form {xa, xb, ya, yb}, can be NULL, minimum/maximum order is irrelevant
Returns
Horizontal gradient image, NULL in the case of error
Principle:
  • A sobel operator is an edge detecting convolution kernel, relatively insensitive to noise. The horizontal one is (here normed by one eighth):

    \[S_x = \frac{1}{8}\cdot\left( \begin{array}{rrr} -1 & 0 & +1 \\ -2 & 0 & +2 \\ -1 & 0 & +1 \end{array}\right) = \frac{1}{8}\cdot \left( \begin{array}{rrr} -1 & 0 & +1 \end{array}\right) * \left( \begin{array}{r} 1 \\ 2 \\ 1 \end{array}\right) \]

  • The input can be integer, float or double.
  • If the input is of type integer, then values of type double will be produced as output.
Bad Pixel Handling:
  • Bad pixels in the input image will contaminate their neighbours.
  • Specifying no window, or a window touching the image border, will result in bad pixels at the output border.
Error Handling:
The following error codes can be set:
  • CPL_ERROR_NULL_INPUT: if input is NULL
  • CPL_ERROR_ACCESS_OUT_OF_RANGE: a window coordinate exceeds the image range
  • CPL_ERROR_INVALID_TYPE: input is neither of type CPL_TYPE_INT, CPL_TYPE_FLOAT nor CPL_TYPE_DOUBLE
Note
In the worst case, a sobel operator without a pre-factor can produce a value 8 times higher than the maximum, and can by this way cause a range violation (resulting in an infinite number). For this reason the pre-factor is used here. But be aware, that this pre-factor causes an increased quantization error when applied to integer numbers.
See Also
cpl_image* clipm_priv_image_conv_sobel_y ( const cpl_image *  input,
const cpl_size  window_xxyy[4] 
)

Convolve image with vertical Sobel operator.

Parameters
inputInput image
window_xxyyCoordinate buffer of the form {xa, xb, ya, yb}, can be NULL, minimum/maximum order is irrelevant
Returns
Vertical gradient image, NULL in the case of error
Principle:
  • A sobel operator is an edge detecting convolution kernel, relatively insensitive to noise. The vertical one is (here normed by one eighth):

    \[S_x = \frac{1}{8}\cdot\left( \begin{array}{rrr} +1 & +2 & +1 \\ 0 & 0 & 0 \\ -1 & -2 & -1 \end{array}\right) = \frac{1}{8}\cdot \left( \begin{array}{rrr} 1 & 2 & 1 \end{array}\right) * \left( \begin{array}{r} +1 \\ 0 \\ -1 \end{array}\right) \]

  • The input can be integer, float or double.
  • If the input is of type integer, then values of type double will be produced as output.
Bad Pixel Handling:
  • Bad pixels in the input image will contaminate their neighbours.
  • Specifying no window, or a window touching the image border, will result in bad pixels at the output border.
Error Handling
The following error codes can be set:
  • CPL_ERROR_NULL_INPUT: if input is NULL
  • CPL_ERROR_ACCESS_OUT_OF_RANGE: a window coordinate exceeds the image range
  • CPL_ERROR_INVALID_TYPE: input is neither of type CPL_TYPE_INT, CPL_TYPE_FLOAT nor CPL_TYPE_DOUBLE
Note
In the worst case, a sobel operator without a pre-factor can produce a value 8 times higher than the maximum, and can by this way cause a range violation (resulting in an infinite number). For this reason the pre-factor is used here. But be aware, that this pre-factor causes an increased quantization error when applied to integer numbers.
See Also