Main Page | Class List | File List | Class Members | File Members

chain_provisional.c File Reference

Interpolated measurements for insertion and removal of ring boundaries. More...

#include <sadie.h>
#include <math.h>
#include "junkmath.h"
#include "Sadie_Index.h"
#include "logerr.h"
#include "chain_provisional.h"

Classes

struct  Provisionalrings
 Measurements for rings affected by an added or removed boundary (2 at most). More...
struct  Boundbracket
 Used for interpolating new points between old points and boundaries. More...
struct  Roiframe
 Holds a summary of the region of interest coordinate frame. More...

Defines

#define MAXIMUM_DISTANCE   HUGE_VAL
 A constant larger than any measurable distance.

Typedefs

typedef Provisionalringsprovisionalringsp_t
 Pointer to a container of messy easurement and boundary data.
typedef Boundbracketboundbracketp_t
 Pointer to the pairing of a point and a boundary.
typedef Roiframeroiframep_t
 Pointer to the summary of the ROI coordinate frame.

Functions

void provisionalrings_destruct (void *data)
 Destroy a provisional measurement collection and all its sub-structures.
void scale_boundary (BOUNDER *bound, double scale)
 Scale the coordinate representation of a boundary by a scalar multiplier.
LIST_NODE * make_chain (BOUNDER *bound)
 Generate a chain-coded boundary from a coordinate boundary representation.
void chain_extrapolate (IMAGE_BYTE *mimage, MOSAIC_INDEX *mindex, double scale, double x, double y, double orig_x, double orig_y, double orig_phi, LIST_NODE *guide, BOUNDBOX_LIST box, double *width, PROFILE_LIST *prof, LIST_NODE **extrapolated, LIST_NODE **small_extrapolated)
 Copy an existing chain-coded boundary, and measure the ring thus defined.
void chain_collapse (IMAGE_BYTE *mimage, MOSAIC_INDEX *mindex, LIST_NODE *inner, LIST_NODE *outer, double *width, PROFILE_LIST *prof)
 Measure the new ring formed by deleting the common boundary of two rings.
int provisional_point_in_roi (MOSAIC_INDEX *mindex, double x, double y)
 Test if coordinates fall within the region of interest in the image mosaic.
double provisional_point_distance (double x, double y, LIST_NODE *boundary)
 Find the minimum distance between a point and a chain-coded boundary.
void chain_interpolate (IMAGE_BYTE *mimage, MOSAIC_INDEX *mindex, double scale, double x, double y, LIST_NODE *inner, LIST_NODE *outer, BOUNDBOX_LIST box, double *w_before, PROFILE_LIST *prof_before, double *w_after, PROFILE_LIST *prof_after, LIST_NODE **interpolated, LIST_NODE **small_interpolated)
 Interpolate a new chain-coded ring boundary between two existing ones.
int provisional_insert (char *doc, int provbnum, IMAGE_BYTE *mimage, MOSAIC_INDEX *mindex, double scale, double x, double y, LIST_NODE *inner, LIST_NODE *outer)
 Insert a new boundary in the chain map between two existing boundaries.
int provisional_delete (char *doc, int provbnum, IMAGE_BYTE *mimage, MOSAIC_INDEX *mindex, LIST_NODE *inner, LIST_NODE *deleted, LIST_NODE *outer, LIST_NODE *small)
 Delete an existing chain-coded boundary.
int provisional_missing (char *doc, int provbnum, IMAGE_BYTE *mimage, MOSAIC_INDEX *mindex, BOUNDBOX_LIST bbox, LIST_NODE *guide, LIST_NODE *small)
 Insert a missing ring after an existing chain-coded boundary.
int provisional_extend (char *doc, int provbnum, IMAGE_BYTE *mimage, MOSAIC_INDEX *mindex, double scale, double x, double y, LIST_NODE *initial, LIST_NODE *final)
 Extend the list of chain-coded boundaries by a new boundary at the end.
int provisional_check (double x, double y, LIST_NODE *inner, LIST_NODE *outer)
 Check if a point lies between two chain-coded boundaries.
int have_provisional_changes (char *doc, char *pname)
 Test if there are valid modified data in the provisional measurements.
LIST_NODE * get_provisional_full_chain (char *doc, char *pname)
 Recover the full-resolution chain-coded boundary from the hash table.
LIST_NODE * get_provisional_small_chain (char *doc, char *pname)
 Recover the downsampled chain-coded boundary from the hash table.
int get_provisional_insert_point (char *doc, char *pname)
 Recover the insertion point in the list of chain-coded boundaries.
int find_provisional_widths (char *doc, char *pname, double **widthhandle)
 Find the array of provisional total ring widths in the hash table.
int find_provisional_profiles (char *doc, char *pname, PROFILE_LIST **profhandle)
 Find the array of provisional brightness profiles in the hash table.
int find_provisional_diff_profiles (char *doc, char *pname, PROFILE_LIST **diffprofhandle)
 Find the array of provisional differenced brightness profiles.
int find_provisional_earlywidths (char *doc, char *pname, double **earlywidthhandle)
 Find the array of provisional earlywood widths in the hash table.
int find_provisional_latewidths (char *doc, char *pname, double **latewidthhandle)
 Find the array of provisional latewood widths in the hash table.
int find_provisional_boundbox (char *doc, char *pname, BOUNDBOX_LIST *boundboxhandle)
 Find the bounding box for the provisional ring.

Variables

sad_doclistp_t global_doclist
 Hash table storing arbitrary data (including Provisionalrings structures).


Detailed Description

Interpolated measurements for insertion and removal of ring boundaries.

This provides several operations to support the operations that add or remove ring boundaries. They generate new boundaries by either interpolating between a pair of previously detected boundaries close to a specified position (e.g., a mouse click on an image), or by taking the long axis of the region of interest within which the other boundaries lie and placing a copy of one of these previously detected boundaries at a position along this axis close to the secified position. We use the Sadie_Index hash table implementation to store the measurements generated or modified by the boundary insertions and deletions, and provide a complete range of functions to retrieve these data while hiding the messy details of the implementation.

Author:
University of Arizona Digital Image Analysis Lab
Date:
2004
Version:
Id
chain_provisional.c,v 1.4 2004/11/19 19:11:11 mmunro Exp

Function Documentation

void chain_collapse IMAGE_BYTE mimage,
MOSAIC_INDEX *  mindex,
LIST_NODE *  inner,
LIST_NODE *  outer,
double *  width,
PROFILE_LIST prof
 

Measure the new ring formed by deleting the common boundary of two rings.

Although we will generally use this to derive a new set of measurements for the single ring formed from two rings by the deletion of their common boundary, in principle it is just a general single-ring measurement function, analogous to a single iteration of the main loop in the CHAIN_RINGWIDTHS function.

Parameters:
mimage points to the mosaic image.
mindex points to the index to the mosaic image.
inner points to the first pre-existing chaincoded boundary.
outer points to the second pre-existing chaincoded boundary.
width will point to the total ring width for the new ring.
prof will point to the brightness profile for the new ring.

void chain_extrapolate IMAGE_BYTE mimage,
MOSAIC_INDEX *  mindex,
double  scale,
double  x,
double  y,
double  orig_x,
double  orig_y,
double  orig_phi,
LIST_NODE *  guide,
BOUNDBOX_LIST  box,
double *  width,
PROFILE_LIST prof,
LIST_NODE **  extrapolated,
LIST_NODE **  small_extrapolated
 

Copy an existing chain-coded boundary, and measure the ring thus defined.

Taking the region of interest within the image mosaic, the coordinates of the new boundary position, and an existing chain-coded boundary, we generate a new boundary as copy of the existing one, translated along the region of interest so that it falls near the specified coordinates. We transcribe the old chain-coded boundary to a representation that records the absolute coordinates of each point in continuous space (rather than the discrete relative steps of the chain code): a BOUNDER structure. The new boundary is initially also a BOUNDER structure, and all the ring measurements are derived from this pair of BOUNDER representations. We convert the new boundary to a chain-code representation (at two different resolutions), and simply discard the BOUNDER structures, which isn't very elegant.

Parameters:
mimage points to the mosaic image.
mindex points to the index to the mosaic image.
scale the downsampling factor for the low-resolution chaincode.
x the horizontal coordinate of the new boundary location.
y the vertical coordinate of the new boundary location.
orig_x the x coordinate of the region of interest origin.
orig_y the y coordinate of the region of interest origin.
orig_phi the angle of the long axis of the ROI.
guide points to the chaincoded existing boundary.
box will point to the bounding box for the new boundary.
width will point to the total ring width for the new ring.
prof will point to the brightness profile for the new ring.
extrapolated will point to the new chain-coded boundary.
small_extrapolated will point to the new boundary, downsampled.

void chain_interpolate IMAGE_BYTE mimage,
MOSAIC_INDEX *  mindex,
double  scale,
double  x,
double  y,
LIST_NODE *  inner,
LIST_NODE *  outer,
BOUNDBOX_LIST  box,
double *  w_before,
PROFILE_LIST prof_before,
double *  w_after,
PROFILE_LIST prof_after,
LIST_NODE **  interpolated,
LIST_NODE **  small_interpolated
 

Interpolate a new chain-coded ring boundary between two existing ones.

Given two existing chain-coded boundaries and the coordinates of a point, we construct a new boundary by interpolation between the boundaries, taking the point coordinates as an approximate guide to its position. As normally used, the new boundary will split a previously measured ring in two, so there will be not just one set of modified ring measurements, but two. We transcribe the existing chain-coded boundaries to a representation that use the absolute coordinates of each point (BOUNDER structures); when first constructed, the new boundary uses the same representation, however the new boundary gets converted to a chain-coded representation (at two different resolutions), which along with the new measurements are the only data output from this function. The original BOUNDER representation of the interpolated boundary lacks the accurate information about local perpendicular directions needed for the width measurement, so we wastefully discard it after creating the chain-coded boundary, re-generate a new BOUNDER from the chain code, and use this for the measurements, before discarding it as well.

Parameters:
mimage points to the mosaic image.
mindex points to the index to the mosaic image.
scale the downsampling factor for the low-resolution chaincode.
x the horizontal coordinate of the new boundary location.
y the vertical coordinate of the new boundary location.
inner points to the first pre-existing chaincoded boundary.
outer points to the second pre-existing chaincoded boundary.
box will point to the bounding box for the new boundary.
width will point to the total ring width for the new rings.
prof will point to the brightness profile for the new rings.
interpolated will point to the new chain-coded boundary.
small_interpolated will point to the new boundary, downsampled.

int find_provisional_boundbox char *  doc,
char *  pname,
BOUNDBOX_LIST *  boundboxhandle
 

Find the bounding box for the provisional ring.

Although this could be the head of a list of bounding boxes in a completely general case, here we're assuming it's the single box for one ring boundary.

Parameters:
doc the string identifying the document in the hash table.
pname a string identifying the set of provisional measrements.
boundboxhandle will get set to a pointer to bounding box.
Returns:
the number of valid boxes (should be exactly 1, or 0 if an error).

int find_provisional_diff_profiles char *  doc,
char *  pname,
PROFILE_LIST **  diffprofhandle
 

Find the array of provisional differenced brightness profiles.

Parameters:
doc the string identifying the document in the hash table.
pname a string identifying the set of provisional measrements.
diffprofhandle will get set to a pointer to the first profile list.
Returns:
the number of valid profiles (should be 1 or 2).

int find_provisional_earlywidths char *  doc,
char *  pname,
double **  earlywidthhandle
 

Find the array of provisional earlywood widths in the hash table.

Parameters:
doc the string identifying the document in the hash table.
pname a string identifying the set of provisional measrements.
earlywidthhandle will get set to a pointer to the first width.
Returns:
the number of valid widths (should be 1 or 2).

int find_provisional_latewidths char *  doc,
char *  pname,
double **  latewidthhandle
 

Find the array of provisional latewood widths in the hash table.

Parameters:
doc the string identifying the document in the hash table.
pname a string identifying the set of provisional measrements.
latewidthhandle will get set to a pointer to the first width.
Returns:
the number of valid widths (should be 1 or 2).

int find_provisional_profiles char *  doc,
char *  pname,
PROFILE_LIST **  profhandle
 

Find the array of provisional brightness profiles in the hash table.

Parameters:
doc the string identifying the document in the hash table.
pname a string identifying the set of provisional measrements.
profhandle will get set to a pointer to the first brightness list.
Returns:
the number of valid profiles (should be 1 or 2).

int find_provisional_widths char *  doc,
char *  pname,
double **  widthhandle
 

Find the array of provisional total ring widths in the hash table.

Parameters:
doc the string identifying the document in the hash table.
pname a string identifying the set of provisional measrements.
widthhandle will get set to a pointer to the first width.
Returns:
the number of valid widths (should be 1 or 2).

LIST_NODE* get_provisional_full_chain char *  doc,
char *  pname
 

Recover the full-resolution chain-coded boundary from the hash table.

Parameters:
doc the string identifying the document in the hash table.
provbnum the number used to derive the hash key.
Returns:
a pointer to the head of the boundary, or NULL on failure.

int get_provisional_insert_point char *  doc,
char *  pname
 

Recover the insertion point in the list of chain-coded boundaries.

The id number for the list item immediately before the insertion point should have been saved in the hash table, and may be the invalid id code if the insertion point is at the head of the list.

Parameters:
doc the string identifying the document in the hash table.
pname a string identifying the set of provisional measrements.
Returns:
the ring_id number of a list item, or the invalid id on failure.

LIST_NODE* get_provisional_small_chain char *  doc,
char *  pname
 

Recover the downsampled chain-coded boundary from the hash table.

Parameters:
doc the string identifying the document in the hash table.
pname a string identifying the set of provisional measrements.
Returns:
a pointer to the head of the boundary, or NULL on failure.

int have_provisional_changes char *  doc,
char *  pname
 

Test if there are valid modified data in the provisional measurements.

Even if there are no valid profiles, there will always be a (possibly empty) profile structure if there are valid widths, so use its presence as the test.

Parameters:
doc the string identifying the document in the hash table.
provbnum the number used to derive the hash key.
Returns:
a boolena result, true if there are any valid measurements.

LIST_NODE* make_chain BOUNDER *  bound  ) 
 

Generate a chain-coded boundary from a coordinate boundary representation.

A BOUNDER structure represents boundaries by lists of points with explicit coordinates in continuous space, whereas chain-coded boundaries use lists of discrete relative steps instead. Conversion may reduce the total number of points, as the coordinates of several points may fall within the same discrete interval.

Parameters:
bound points to the old BOUNDER boundary representation to convert.
Returns:
a newly-created chain-code boundary representation.

int provisional_check double  x,
double  y,
LIST_NODE *  inner,
LIST_NODE *  outer
 

Check if a point lies between two chain-coded boundaries.

We treat the boundaries as edges of a polygon, which is closed by defining an extra edge between the first points of the boundary pair, and another edge between the last points of the pair. For full background see Haines, Eric, "Point in Polygon Strategies", Graphics Gems IV, ed. Paul Heckbert : Academic Press : 1994. p. 24--46. and equivalently: http://www.acm.org/tog/editors/erich/ptinpoly/

Parameters:
x coordinate of the point to test;
y coordinate of the point to test;
inner points to the chaincoded representation of one boundary.
outer points to the chaincoded representation of the other boundary.

int provisional_delete char *  doc,
int  provbnum,
IMAGE_BYTE mimage,
MOSAIC_INDEX *  mindex,
LIST_NODE *  inner,
LIST_NODE *  deleted,
LIST_NODE *  outer,
LIST_NODE *  small
 

Delete an existing chain-coded boundary.

Given a chain-coded boundary that is already in the chain map lists, and two enclosing boundaries (which are also already in the chain map, or are NULL), remove the boundary and re-compute the measurements to be associated with the enclosing boundaries (if they exist).

Parameters:
doc a string identifying the hash table document.
provbnum used to form the hash key to store the measurements.
mimage points to the mosaic image.
mindex points to the index to the mosaic image.
inner points to the inner enclosing chain-coded boundary.
delete points to the deleted existing chain-coded boundary.
outer points to the outer enclosing chain-coded boundary.
small points to the deleted low-resolution chain-coded boundary.
Returns:
an error code on failure, zero otherwise.

int provisional_extend char *  doc,
int  provbnum,
IMAGE_BYTE mimage,
MOSAIC_INDEX *  mindex,
double  scale,
double  x,
double  y,
LIST_NODE *  initial,
LIST_NODE *  final
 

Extend the list of chain-coded boundaries by a new boundary at the end.

Given the first and last chain-coded boundaries (which are already in the full-resolution chain map) and the coordinates of a point outside them, we construct a new boundary close to this point, derive revised measurements from the re-defined rings, and store them with the new boundaries in the hash table.

Parameters:
doc a string identifying the hash table document.
provbnum used to form the hash key to store the measurements.
mimage points to the mosaic image.
mindex points to the index to the mosaic image.
scale the downsampling factor for the low-resolution chaincode.
x the horizontal coordinate of the new boundary location.
y the vertical coordinate of the new boundary location.
initial points to the first existing chain-coded boundary.
final points to the last existing chain-coded boundary.
Returns:
an error code on failure, zero otherwise.

int provisional_insert char *  doc,
int  provbnum,
IMAGE_BYTE mimage,
MOSAIC_INDEX *  mindex,
double  scale,
double  x,
double  y,
LIST_NODE *  inner,
LIST_NODE *  outer
 

Insert a new boundary in the chain map between two existing boundaries.

Given a pair of chain-coded boundaries (which are already in the full-resolution chain map) and the coordinates of a point between them, we construct a new boundary close to this point, derive revised measurements from the re-defined rings, and store them with the new boundaries in the hash table.

Parameters:
doc a string identifying the hash table document.
provbnum used to form the hash key to store the measurements.
mimage points to the mosaic image.
mindex points to the index to the mosaic image.
scale the downsampling factor for the low-resolution chaincode.
x the horizontal coordinate of the new boundary location.
y the vertical coordinate of the new boundary location.
inner points to the inner existing chain-coded boundary.
outer points to the outer existing chain-coded boundary.
Returns:
an error code on failure, zero otherwise.

int provisional_missing char *  doc,
int  provbnum,
IMAGE_BYTE mimage,
MOSAIC_INDEX *  mindex,
BOUNDBOX_LIST  bbox,
LIST_NODE *  guide,
LIST_NODE *  small
 

Insert a missing ring after an existing chain-coded boundary.

Given a chain-coded boundary that is already in the chain map lists, and two enclosing boundaries (which are also already in the chain map, or are NULL), copy the boundary and create a set of measurements to be associated with it and the original boundary as a special zero-width ring (the marker following a convention in other dendrochronology software for a ring whose position is inferred, but not visible in the part of the tree-ring sample used to produce a particular series of measurements).

Parameters:
doc a string identifying the hash table document.
provbnum used to form the hash key to store the measurements.
mimage points to the mosaic image.
mindex points to the index to the mosaic image.
inner points to the inner enclosing chain-coded boundary.
guide points to the existing chain-coded boundary to copy.
outer (unused) points to the outer enclosing chain-coded boundary.
small points to the low-resolution chain-coded boundary to copy.
Returns:
an error code on failure, zero otherwise.

double provisional_point_distance double  x,
double  y,
LIST_NODE *  boundary
 

Find the minimum distance between a point and a chain-coded boundary.

Although the individual line segments making up the chain-coded boundary can only have two lengths, and are joined at nodes that lie on a regular grid, the coordinates of the point are not necessarily constrained in any way, so we treat it as the more general case of finding the distance between a point and an arbitrary polyline in continuous coordinates.

Parameters:
x coordinate of the point whose distance we are determining.
y coordinate of the point whose distance we are determining.
x points to the chain-coded representation of a boundary.
Returns:
the minimum point-boundary distance.

int provisional_point_in_roi MOSAIC_INDEX *  mindex,
double  x,
double  y
 

Test if coordinates fall within the region of interest in the image mosaic.

Transform the coordinates to a frame with its origin an upper corner of the ROI and its x axis along the longest edge, then compare them to the lengths of the edges of the ROI.

Parameters:
mindex points to the index to the mosaic image.
x the horizontal coordinate of the new boundary location.
y the vertical coordinate of the new boundary location.
Returns:
true if the coordinates are inside (the int is really a boolean).

void provisionalrings_destruct void *  data  ) 
 

Destroy a provisional measurement collection and all its sub-structures.

Parameters:
data points to a Provisionalrings structure to destroy.

void scale_boundary BOUNDER *  bound,
double  scale
 

Scale the coordinate representation of a boundary by a scalar multiplier.

Multiply all the x and y coordinates in the boundary representation, and remove the (now inavalid) index to the points.

Parameters:
bound points to the BOUNDER encoded representation of the boundary.
scale scale factor.


Generated on Sat Dec 4 17:12:27 2004 for trees by  doxygen 1.3.9.1