Hello again! I hope this is the right list to discuss such questions here; if not I beg pardon in advance and would kindly ask to redirect me to a more appropriate place for technical discussions.
I finished a draft of the interface (just the interface... the implementation is in a quite early development) for a lens database library. I have attached it to this message. I would gladly listen to any comments on it, since on this list there are people good both at theory and practice. At a second thought I decided that a universal library should provide support for multiple lens models... otherwise it won't be universal :-) So I decided to include all lens models that (IMHO of course) can have practical application. I've included the 3rd and 5th order polynomial models as well as the 1st order Field-of-view model (used in Picture Window Pro), the PTLens model for rectilinear and fish-eye lenses. I hope this complexity could be hidden somehow in user interface to not make users mad :-) By the way, here's what the author of Imatest says about the PTLens model: ------8<------8<------8<------ This equation drives me nuts! rsrc and rdest are reversed from the equations on this page; it only goes up to fourth power (when you include rdest outside the parentheses; third power if you don't); and it has even order terms (a and c) when the theory implies that distortion can be modeled with odd terms only. Give me a higher order term (h * rdest4 ) and dump a * rdest3 and c * rdest. But nonetheless it works pretty well. ------>8------>8------>8------ :-) For lateral chromatic aberrations I decided to include for now only the linear model (e.g. rd = ru * k) since I experimented a little with the GIMP Fix-CA plug-in (http://kcd.sourceforge.net/fix-ca.php) and found it to work pretty well for all images I had at hand (including some images taken with a fisheye with severe TCA) despite the simplistic (linear) model used. Also several papers I found on Internet state that a linear model for TCAs is enough. So for now I'm not sure there are reasons for a more sophisticated TCA model, but if somebody knows some, don't hesitate to tell me :) -- Andrew
/*
* LensFun - a library for maintaining a database of photographical lenses,
* and providing the means to correct some of the typical lens distortions.
*
* /LGPL here/
*/
#ifndef __LENSFUN_H__
#define __LENSFUN_H__
/* Private lens database fields */
typedef struct _lfDatabasePrivate lfDatabasePrivate;
/**
* A lens database object.
*/
typedef struct
{
/* Private fields */
lfDatabasePrivate *Private;
} lfDatabase;
/* Private camera-related fields */
typedef struct _lfCameraPrivate lfCameraPrivate;
/**
* Camera data.
* Unknown fields are set to NULL.
*/
typedef struct
{
/** Camera maker (ex: "Rollei") */
const char *Maker;
/** Model name ("Rolleiflex SL35") */
const char *Name;
/** Camera mount type (ex: "QBM") */
const char *Mount;
/** Camera crop factor (ex: 1.0). Must be defined. */
float CropFactor;
/* Additional private data */
lfCameraPrivate *Private;
} lfCamera;
/**
* The lensdb library implements several lens distortion models.
* This enum lists them. Distortion usually heavily depends on the
* focal distance, but do not depend on the aperture.
*
* For a popular explanation of lens distortion see
* http://www.vanwalree.com/optics/distortion.html
*/
typedef enum
{
/** Distortion parameters are unknown */
LDB_DIST_MODEL_NONE,
/**
* 3rd order polynomial model:
* ru = rd * (1 + k1 * r^2)
* Ref: http://www.imatest.com/docs/distortion.html
*/
LDB_DIST_MODEL_POLY3,
/**
* 5th order polynomial model:
* ru = rd * (1 + k1 * r^2 + k2 * r^4)
*/
LDB_DIST_MODEL_POLY5,
/**
*
* ru = tg (rd * w) / (2 * tg (w/2))
* Ref: ftp://ftp-sop.inria.fr/chir/publis/devernay-faugeras:01.pdf
*/
LDB_DIST_MODEL_FOV1,
/**
* PTLens rectilinear:
* ru = rd * (a * rd^3 + b * rd^2 + c * rd + 1)
*/
LDB_DIST_MODEL_PTLENS_RECT,
/**
* PTLens fisheye model.
* ru = rd * (a * rd^3 + b * rd^2 + c * rd + 1)
* Ref: http://wiki.panotools.org/Lens_correction_model
*/
LDB_DIST_MODEL_PTLENS_FISHEYE
} lfDistortionModel;
/**
* The lensdb library supports several models for lens lateral
* chromatic aberrations (also called transversal chromatic
* aberrations, TCA). TCAs depend on focal distance, but do not
* depend of the aperture.
*
* For a popular explanation of chromatic aberrations see
* http://www.vanwalree.com/optics/chromatic.html
*/
typedef enum
{
/** No TCA correction data is known */
LDB_TCA_MODEL_NONE,
/**
* Linear lateral chromatic abberations model:
* rd = ru * k
* Ref: http://cipa.icomos.org/fileadmin/papers/Torino2005/403.pdf?PHPSESSID=8f5fa7da0b8aef1558792c10425086e2
*/
LDB_TCA_MODEL_LINEAR
} lfTCAModel;
/**
* The lensdb library supports several models for lens vignetting
* correction. We focus on optical and natural vignetting since they
* can be generalized for all lenses of a certain type; mechanical
* vignetting is out of the scope of this library.
*
* Vignetting is dependent on both focal distance and aperture.
*
* For a popular explanation of vignetting see
* http://www.vanwalree.com/optics/vignetting.html
*/
typedef enum
{
/** No vignetting correction data is known */
LDB_VIGNETTING_MODEL_NONE,
/**
* Pablo D'Angelo vignetting model
* (which is a more general variant of the cos^4 law):
* c = 1 + k1 * r^2 + k2 * r^4 + k3 * r^6
* Ref: http://hugin.sourceforge.net/tech/
*/
LDB_VIGNETTING_PA
} lfVignettingModel;
/**
* Lens calibration data. This data describes optical lens
* properties at certain fixed conditions: at some focal length
* and/or aperture. The library will interpolate the actual
* requested values if the exact focal/aperture match is not
* available.
*/
typedef struct
{
/** Focal distance at which this calibration data was taken (0 - unspecified) */
float Focal;
/** Aperture at which this calibration data was taken (0 - unspecified) */
float Aperture;
/** The type of distortion model used */
lfDistortionModel DistModel;
/** Distortion coefficients, dependent on model */
float DistCoeff [3];
/** The lateral chromatic aberration model used */
lfTCAModel TCAModel;
/** The coefficients for TCA, dependent on model */
float TCACoeff [1];
/** The lens vignetting model used */
lfVignettingModel VignettingModel;
/** Lens vignetting model coefficients (depending on model) */
float VignettingCoeff [3];
} lfLensCalibration;
/* Private lens-related fields */
typedef struct _lfLensPrivate lfLensPrivate;
/**
* Lens data.
* Unknown fields are set to NULL or 0.
*/
typedef struct _lfLens
{
/** Lens maker (ex: "Rollei") */
const char *Maker;
/** Lens model (ex: "Zoom-Rolleinar") */
const char *Model;
/**
* A pointer to other lens, which this is a clone of. This is useful
* for lenses that were released under several names. If this field is
* non-NULL, all following fields are unused.
*/
struct _lfLens *Clone;
/** Minimum focal distance, mm (ex: 35). Must be defined. */
float MinFocal;
/** Maximum focal distance, mm (ex: 105). If 0, same as MinFocal. */
float MaxFocal;
/** Aperture at minimum focal distance (ex: 3.5). Must be defined. */
float MinAperture;
/** Aperture at maximum focal distance (ex: 4.3). If 0, same as MinAperture. */
float MaxAperture;
/** Available mounts (NULL-terminated list) (ex: { "QBM", NULL }) */
const char **Mounts;
/** The horizontal shift of all lens distortions in range -1..+1 */
float CenterDX;
/** The vertical shift of all lens distortions; (0,0) for geometric center */
float CenterDY;
/** Lens calibration data, NULL-terminated (unsorted) */
lfLensCalibration **Calibration;
/* Additional private data */
lfLensPrivate *Private;
} lfLens;
/** A opaque data structure used while correcting images */
typedef struct _lfImageCorrector lfImageCorrector;
/** liblensdb error codes: negative codes are -errno, positive are here */
typedef enum
{
/** No error occured */
LDB_NO_ERROR = 0,
/** Wrong XML data format */
LDB_WRONG_FORMAT
} lfError;
/** A list of bitmask flags used for ordering various image corrections */
enum
{
/** Apply all possible corrections */
LF_CORRECT_ALL = 0xffffffff,
/** Correct lens distortion */
LF_CORRECT_DIST = 0x00000001,
/** Correct lens transversal chromatic aberrations */
LF_CORRECT_TCA = 0x00000002,
/** Correct lens vignetting */
LF_CORRECT_VIGN = 0x00000004
};
/**
* The basics of memory allocation: never free objects allocated by the
* library yourselves, instead use this function. It is a direct
* equivalent of standard C free(), however you should not use free()
* in the event that the library uses a separate heap.
* @param data
* A pointer to memory to be freed.
*/
void lf_free (void *data);
/**
* Create a new empty database object.
*/
lfDatabase *lf_db_new (void);
/**
* Create a new database object and load the whole lens database.
* Usually the application will want to do this at startup.
* This calls lf_load_file() for all XML files found in usual places
* (first /usr/share/lensdb/ then ~/.lensdb/).
*/
lfDatabase *lf_db_load (void);
/**
* Destroy the database object.
* @param db
* The database to destroy.
*/
void lf_db_destroy (lfDatabase *db);
/**
* Load just a specific XML file. If the loaded file contains the
* specification of a camera/lens that's already in memory, it
* overrides that data.
* @param db
* The database to add the camera/lens data to.
* @param filename
* The name of a XML file to load. Note that lensdb does not support
* the full XML specification as it uses the glib's simple XML parser,
* so advanced XML features are not available.
* @return
* LDB_NO_ERROR or a error code.
*/
lfError lf_db_load_file (lfDatabase *db, const char *filename);
/**
* Load a set of camera/lenses from a memory array.
* This is the lowest-level loading function.
* @param db
* The database to add the camera/lens data to.
* @param data
* The XML data.
* @return
* LDB_NO_ERROR or a error code.
*/
lfError lf_load (lfDatabase *db, const char *data);
/**
* Save a set of camera and lens descriptions to a file.
* @param filename
* The file name to write the lenses to.
* @param cameras
* A list of cameras to be written to the file. Can be NULL.
* @param lenses
* A list of lenses to be written to the file. Can be NULL.
* @return
* LDB_NO_ERROR or a error code.
*/
lfError lf_save_file (const char *filename, const lfCamera **cameras,
const lfLens **lenses);
/**
* Save a set of camera and lens descriptions into a memory array.
* @param cameras
* A list of cameras to be written to the file. Can be NULL.
* @param lenses
* A list of lenses to be written to the file. Can be NULL.
* @param output
* This variable is set to point to a newly-allocated memory area.
* Like usually, it must be freed with lf_free().
* @return
* LDB_NO_ERROR or a error code.
*/
lfError lf_save (const lfCamera **cameras, const lfLens **lenses,
char **output);
/**
* Parse a human-level lens description (ex: "smc PENTAX-F 35-105mm F4-5.6
* or SIGMA AF 28-300 F3.5-5.6 DL IF") and return a set of lfLens'es which
* are matching this description. Multiple lenses may be listed using the
* "or" glueword, also multiple lenses may be returned if only a part of
* the lens specification is provided (e.g. "Pentax SMC").
*
* The matching algorithm works as follows: both user's description and the
* actual lens description are split into words. Words containing numbers
* are tried to be interpreted as either focal distance ranges or aperture
* ranges. After that word matching is done; a lens matches the description
* ONLY IF it contains all the words found in the description (including
* buzzwords e.g. IF AL LD DI USM SDM etc). Order of the words does not
* matter. An additional check is done on the focal/aperture ranges, they
* must exactly match if they are specified.
* @param db
* The database where to search for lenses.
* @param camera
* The camera (can be NULL if camera is unknown, or just certain
* fields in structure can be NULL).
* @param lens
* A human description of the lens(-es).
* @return
* A list of lenses parsed from user description or NULL.
* Release memory with lf_free(). The list is ordered in the
* most-likely to least-likely order, e.g. the first returned
* value is the most likely match.
*/
const lfLens **lf_find_lenses_hd (lfDatabase *db, const lfCamera *camera,
const char *lens);
/**
* Find a set of lenses that fit certain criteria.
*
* If both camera and lens are NULLs, the whole database is returned.
* @param db
* The database where to search for lenses.
* @param camera
* The camera (can be NULL if camera is unknown, or just certain
* fields in structure can be NULL).
* @param lens
* The candidate lense. Uncertain fields may be NULL. If this
* parameter is NULL, all lenses fitting the specified camera
* are returned.
* @return
* A list of lenses matching the search criteria or NULL if none.
* Release memory with lf_free(). The list is ordered in the
* most-likely to least-likely order, e.g. the first returned
* value is the most likely match.
*/
const lfLens **lf_find_lenses (lfDatabase *db, const lfCamera *camera,
lfLens *lens);
/**
* Initialize the process of correcting abberations in a image.
* You must provide the original image width/height even if you
* plan to correct just a part of the image.
*
* The corrector object will be set up to rectify all aberrations
* found in the lens description. Make sure the focal length and aperture
* value are correct, otherwise the corrector may pick up wrong model
* parameters!
* @param lens
* The lens which abberations you want to correct in a image.
* @param width
* The width of the image you want to correct.
* @param height
* The height of the image you want to correct.
* @param focal
* The focal length at which the image was taken.
* @param aperture
* The aperture at which the image was taken.
* @param flags
* A set of flags (se LF_CORRECT_XXX) telling which distortions you want
* corrected. A value of LF_CORRECT_ALL orders correction of everything
* possible.
* @return
* A new image corrector object.
*/
lfImageCorrector *lf_corrector_new (const lfLens *lens, int width, int height,
float focal, float aperture, int flags);
/**
* Destroy the corrector object.
* @param corrector
* The corrector object to destroy.
*/
void lf_corrector_destroy (lfImageCorrector *corrector);
/**
* Apply the reverse distortion transforms on a pixel coordinate.
* Returns the corrected coordinates separately for R/G/B channels.
* @param xu
* The pixel X coordinate in undistorted image.
* @param yu
* The pixel Y coordinate in undistorted image.
* @param xd
* A pointer to an array of 3 floats receiving the X coordinate of the
* distorted pixel for the R, G and B channels.
* @param yd
* A pointer to an array of 3 floats receiving the Y coordinate of the
* distorted pixel for the R, G and B channels.
*/
void lf_corrector_apply (float xu, float yu, float *xd, float *yd);
#endif /* __LENSFUN_H__ */
signature.asc
Description: PGP signature
_______________________________________________ CREATE mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/create
