mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Fix printf issue in apriltags, dmtx and lsd.
* The root cause for this issue is "define double float". printf functions promote float to double, which is #define'd as float causing the implicit conversion error. * Replaced all double with float, and DBL_MIN and FLT_MIN etc... and added explicit cast to double in printf functions.
This commit is contained in:
parent
fa2ffaa655
commit
7eaeefacb1
File diff suppressed because it is too large
Load Diff
@ -21,18 +21,11 @@
|
|||||||
|
|
||||||
#define perror(str)
|
#define perror(str)
|
||||||
#define fprintf(stream, format, ...)
|
#define fprintf(stream, format, ...)
|
||||||
#define fputc(character, stream)
|
|
||||||
#define snprintf(s, c, format, ...) 0
|
|
||||||
#define free(ptr) ({ umm_free(ptr); })
|
#define free(ptr) ({ umm_free(ptr); })
|
||||||
#define malloc(size) ({ void *_r = umm_malloc(size); if(!_r) fb_alloc_fail(); _r; })
|
#define malloc(size) ({ void *_r = umm_malloc(size); if(!_r) fb_alloc_fail(); _r; })
|
||||||
#define realloc(ptr, size) ({ void *_r = umm_realloc((ptr), (size)); if(!_r) fb_alloc_fail(); _r; })
|
#define realloc(ptr, size) ({ void *_r = umm_realloc((ptr), (size)); if(!_r) fb_alloc_fail(); _r; })
|
||||||
#define calloc(num, item_size) ({ void *_r = umm_calloc((num), (item_size)); if(!_r) fb_alloc_fail(); _r; })
|
#define calloc(num, item_size) ({ void *_r = umm_calloc((num), (item_size)); if(!_r) fb_alloc_fail(); _r; })
|
||||||
#define assert(expression)
|
#define assert(expression)
|
||||||
#define double float
|
|
||||||
#undef DBL_MIN
|
|
||||||
#define DBL_MIN FLT_MIN
|
|
||||||
#undef DBL_MAX
|
|
||||||
#define DBL_MAX FLT_MAX
|
|
||||||
#define sqrt(x) fast_sqrtf(x)
|
#define sqrt(x) fast_sqrtf(x)
|
||||||
#define sqrtf(x) fast_sqrtf(x)
|
#define sqrtf(x) fast_sqrtf(x)
|
||||||
#define floor(x) fast_floorf(x)
|
#define floor(x) fast_floorf(x)
|
||||||
@ -258,7 +251,7 @@ typedef enum {
|
|||||||
DmtxFlipY = 0x01 << 1
|
DmtxFlipY = 0x01 << 1
|
||||||
} DmtxFlip;
|
} DmtxFlip;
|
||||||
|
|
||||||
typedef double DmtxMatrix3[3][3];
|
typedef float DmtxMatrix3[3][3];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct DmtxPixelLoc
|
* @struct DmtxPixelLoc
|
||||||
@ -274,8 +267,8 @@ typedef struct DmtxPixelLoc_struct {
|
|||||||
* @brief DmtxVector2
|
* @brief DmtxVector2
|
||||||
*/
|
*/
|
||||||
typedef struct DmtxVector2_struct {
|
typedef struct DmtxVector2_struct {
|
||||||
double X;
|
float X;
|
||||||
double Y;
|
float Y;
|
||||||
} DmtxVector2;
|
} DmtxVector2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -283,8 +276,8 @@ typedef struct DmtxVector2_struct {
|
|||||||
* @brief DmtxRay2
|
* @brief DmtxRay2
|
||||||
*/
|
*/
|
||||||
typedef struct DmtxRay2_struct {
|
typedef struct DmtxRay2_struct {
|
||||||
double tMin;
|
float tMin;
|
||||||
double tMax;
|
float tMax;
|
||||||
DmtxVector2 p;
|
DmtxVector2 p;
|
||||||
DmtxVector2 v;
|
DmtxVector2 v;
|
||||||
} DmtxRay2;
|
} DmtxRay2;
|
||||||
@ -348,7 +341,7 @@ typedef struct DmtxBestLine_struct {
|
|||||||
int stepPos;
|
int stepPos;
|
||||||
int stepNeg;
|
int stepNeg;
|
||||||
int distSq;
|
int distSq;
|
||||||
double devn;
|
float devn;
|
||||||
DmtxPixelLoc locBeg;
|
DmtxPixelLoc locBeg;
|
||||||
DmtxPixelLoc locPos;
|
DmtxPixelLoc locPos;
|
||||||
DmtxPixelLoc locNeg;
|
DmtxPixelLoc locNeg;
|
||||||
@ -459,7 +452,7 @@ typedef struct DmtxDecode_struct {
|
|||||||
int edgeMin;
|
int edgeMin;
|
||||||
int edgeMax;
|
int edgeMax;
|
||||||
int scanGap;
|
int scanGap;
|
||||||
double squareDevn;
|
float squareDevn;
|
||||||
int sizeIdxExpected;
|
int sizeIdxExpected;
|
||||||
int edgeThresh;
|
int edgeThresh;
|
||||||
|
|
||||||
@ -510,35 +503,35 @@ extern int dmtxImageGetByteOffset(DmtxImage *img, int x, int y);
|
|||||||
extern DmtxPassFail dmtxImageGetPixelValue(DmtxImage *img, int x, int y, int channel, /*@out@*/ int *value);
|
extern DmtxPassFail dmtxImageGetPixelValue(DmtxImage *img, int x, int y, int channel, /*@out@*/ int *value);
|
||||||
extern DmtxPassFail dmtxImageSetPixelValue(DmtxImage *img, int x, int y, int channel, int value);
|
extern DmtxPassFail dmtxImageSetPixelValue(DmtxImage *img, int x, int y, int channel, int value);
|
||||||
extern DmtxBoolean dmtxImageContainsInt(DmtxImage *img, int margin, int x, int y);
|
extern DmtxBoolean dmtxImageContainsInt(DmtxImage *img, int margin, int x, int y);
|
||||||
extern DmtxBoolean dmtxImageContainsFloat(DmtxImage *img, double x, double y);
|
extern DmtxBoolean dmtxImageContainsFloat(DmtxImage *img, float x, float y);
|
||||||
|
|
||||||
/* dmtxvector2.c */
|
/* dmtxvector2.c */
|
||||||
extern DmtxVector2 *dmtxVector2AddTo(DmtxVector2 *v1, const DmtxVector2 *v2);
|
extern DmtxVector2 *dmtxVector2AddTo(DmtxVector2 *v1, const DmtxVector2 *v2);
|
||||||
extern DmtxVector2 *dmtxVector2Add(/*@out@*/ DmtxVector2 *vOut, const DmtxVector2 *v1, const DmtxVector2 *v2);
|
extern DmtxVector2 *dmtxVector2Add(/*@out@*/ DmtxVector2 *vOut, const DmtxVector2 *v1, const DmtxVector2 *v2);
|
||||||
extern DmtxVector2 *dmtxVector2SubFrom(DmtxVector2 *v1, const DmtxVector2 *v2);
|
extern DmtxVector2 *dmtxVector2SubFrom(DmtxVector2 *v1, const DmtxVector2 *v2);
|
||||||
extern DmtxVector2 *dmtxVector2Sub(/*@out@*/ DmtxVector2 *vOut, const DmtxVector2 *v1, const DmtxVector2 *v2);
|
extern DmtxVector2 *dmtxVector2Sub(/*@out@*/ DmtxVector2 *vOut, const DmtxVector2 *v1, const DmtxVector2 *v2);
|
||||||
extern DmtxVector2 *dmtxVector2ScaleBy(DmtxVector2 *v, double s);
|
extern DmtxVector2 *dmtxVector2ScaleBy(DmtxVector2 *v, float s);
|
||||||
extern DmtxVector2 *dmtxVector2Scale(/*@out@*/ DmtxVector2 *vOut, const DmtxVector2 *v, double s);
|
extern DmtxVector2 *dmtxVector2Scale(/*@out@*/ DmtxVector2 *vOut, const DmtxVector2 *v, float s);
|
||||||
extern double dmtxVector2Cross(const DmtxVector2 *v1, const DmtxVector2 *v2);
|
extern float dmtxVector2Cross(const DmtxVector2 *v1, const DmtxVector2 *v2);
|
||||||
extern double dmtxVector2Norm(DmtxVector2 *v);
|
extern float dmtxVector2Norm(DmtxVector2 *v);
|
||||||
extern double dmtxVector2Dot(const DmtxVector2 *v1, const DmtxVector2 *v2);
|
extern float dmtxVector2Dot(const DmtxVector2 *v1, const DmtxVector2 *v2);
|
||||||
extern double dmtxVector2Mag(const DmtxVector2 *v);
|
extern float dmtxVector2Mag(const DmtxVector2 *v);
|
||||||
extern double dmtxDistanceFromRay2(const DmtxRay2 *r, const DmtxVector2 *q);
|
extern float dmtxDistanceFromRay2(const DmtxRay2 *r, const DmtxVector2 *q);
|
||||||
extern double dmtxDistanceAlongRay2(const DmtxRay2 *r, const DmtxVector2 *q);
|
extern float dmtxDistanceAlongRay2(const DmtxRay2 *r, const DmtxVector2 *q);
|
||||||
extern DmtxPassFail dmtxRay2Intersect(/*@out@*/ DmtxVector2 *point, const DmtxRay2 *p0, const DmtxRay2 *p1);
|
extern DmtxPassFail dmtxRay2Intersect(/*@out@*/ DmtxVector2 *point, const DmtxRay2 *p0, const DmtxRay2 *p1);
|
||||||
extern DmtxPassFail dmtxPointAlongRay2(/*@out@*/ DmtxVector2 *point, const DmtxRay2 *r, double t);
|
extern DmtxPassFail dmtxPointAlongRay2(/*@out@*/ DmtxVector2 *point, const DmtxRay2 *r, float t);
|
||||||
|
|
||||||
/* dmtxmatrix3.c */
|
/* dmtxmatrix3.c */
|
||||||
extern void dmtxMatrix3Copy(/*@out@*/ DmtxMatrix3 m0, DmtxMatrix3 m1);
|
extern void dmtxMatrix3Copy(/*@out@*/ DmtxMatrix3 m0, DmtxMatrix3 m1);
|
||||||
extern void dmtxMatrix3Identity(/*@out@*/ DmtxMatrix3 m);
|
extern void dmtxMatrix3Identity(/*@out@*/ DmtxMatrix3 m);
|
||||||
extern void dmtxMatrix3Translate(/*@out@*/ DmtxMatrix3 m, double tx, double ty);
|
extern void dmtxMatrix3Translate(/*@out@*/ DmtxMatrix3 m, float tx, float ty);
|
||||||
extern void dmtxMatrix3Rotate(/*@out@*/ DmtxMatrix3 m, double angle);
|
extern void dmtxMatrix3Rotate(/*@out@*/ DmtxMatrix3 m, float angle);
|
||||||
extern void dmtxMatrix3Scale(/*@out@*/ DmtxMatrix3 m, double sx, double sy);
|
extern void dmtxMatrix3Scale(/*@out@*/ DmtxMatrix3 m, float sx, float sy);
|
||||||
extern void dmtxMatrix3Shear(/*@out@*/ DmtxMatrix3 m, double shx, double shy);
|
extern void dmtxMatrix3Shear(/*@out@*/ DmtxMatrix3 m, float shx, float shy);
|
||||||
extern void dmtxMatrix3LineSkewTop(/*@out@*/ DmtxMatrix3 m, double b0, double b1, double sz);
|
extern void dmtxMatrix3LineSkewTop(/*@out@*/ DmtxMatrix3 m, float b0, float b1, float sz);
|
||||||
extern void dmtxMatrix3LineSkewTopInv(/*@out@*/ DmtxMatrix3 m, double b0, double b1, double sz);
|
extern void dmtxMatrix3LineSkewTopInv(/*@out@*/ DmtxMatrix3 m, float b0, float b1, float sz);
|
||||||
extern void dmtxMatrix3LineSkewSide(/*@out@*/ DmtxMatrix3 m, double b0, double b1, double sz);
|
extern void dmtxMatrix3LineSkewSide(/*@out@*/ DmtxMatrix3 m, float b0, float b1, float sz);
|
||||||
extern void dmtxMatrix3LineSkewSideInv(/*@out@*/ DmtxMatrix3 m, double b0, double b1, double sz);
|
extern void dmtxMatrix3LineSkewSideInv(/*@out@*/ DmtxMatrix3 m, float b0, float b1, float sz);
|
||||||
extern void dmtxMatrix3Multiply(/*@out@*/ DmtxMatrix3 mOut, DmtxMatrix3 m0, DmtxMatrix3 m1);
|
extern void dmtxMatrix3Multiply(/*@out@*/ DmtxMatrix3 mOut, DmtxMatrix3 m0, DmtxMatrix3 m1);
|
||||||
extern void dmtxMatrix3MultiplyBy(DmtxMatrix3 m0, DmtxMatrix3 m1);
|
extern void dmtxMatrix3MultiplyBy(DmtxMatrix3 m0, DmtxMatrix3 m1);
|
||||||
extern int dmtxMatrix3VMultiply(/*@out@*/ DmtxVector2 *vOut, DmtxVector2 *vIn, DmtxMatrix3 m);
|
extern int dmtxMatrix3VMultiply(/*@out@*/ DmtxVector2 *vOut, DmtxVector2 *vIn, DmtxMatrix3 m);
|
||||||
@ -681,7 +674,7 @@ typedef struct C40TextState_struct {
|
|||||||
} C40TextState;
|
} C40TextState;
|
||||||
|
|
||||||
/* dmtxregion.c */
|
/* dmtxregion.c */
|
||||||
static double RightAngleTrueness(DmtxVector2 c0, DmtxVector2 c1, DmtxVector2 c2, double angle);
|
static float RightAngleTrueness(DmtxVector2 c0, DmtxVector2 c1, DmtxVector2 c2, float angle);
|
||||||
static DmtxPointFlow MatrixRegionSeekEdge(DmtxDecode *dec, DmtxPixelLoc loc0);
|
static DmtxPointFlow MatrixRegionSeekEdge(DmtxDecode *dec, DmtxPixelLoc loc0);
|
||||||
static DmtxPassFail MatrixRegionOrientation(DmtxDecode *dec, DmtxRegion *reg, DmtxPointFlow flowBegin);
|
static DmtxPassFail MatrixRegionOrientation(DmtxDecode *dec, DmtxRegion *reg, DmtxPointFlow flowBegin);
|
||||||
static long DistanceSquared(DmtxPixelLoc a, DmtxPixelLoc b);
|
static long DistanceSquared(DmtxPixelLoc a, DmtxPixelLoc b);
|
||||||
@ -1099,8 +1092,8 @@ dmtxDecodeGetPixelValue(DmtxDecode *dec, int x, int y, int channel, int *value)
|
|||||||
|
|
||||||
/* Remove spherical lens distortion */
|
/* Remove spherical lens distortion */
|
||||||
/* int width, height;
|
/* int width, height;
|
||||||
double radiusPow2, radiusPow4;
|
float radiusPow2, radiusPow4;
|
||||||
double factor;
|
float factor;
|
||||||
DmtxVector2 pointShifted;
|
DmtxVector2 pointShifted;
|
||||||
DmtxVector2 correctedPoint;
|
DmtxVector2 correctedPoint;
|
||||||
|
|
||||||
@ -1322,7 +1315,7 @@ dmtxDecodeCreateDiagnostic(DmtxDecode *dec, int *totalBytes, int *headerBytes, i
|
|||||||
int widthDigits, heightDigits;
|
int widthDigits, heightDigits;
|
||||||
int count, channelCount;
|
int count, channelCount;
|
||||||
int rgb[3];
|
int rgb[3];
|
||||||
double shade;
|
float shade;
|
||||||
unsigned char *pnm, *output, *cache;
|
unsigned char *pnm, *output, *cache;
|
||||||
|
|
||||||
width = dmtxDecodeGetProp(dec, DmtxPropWidth);
|
width = dmtxDecodeGetProp(dec, DmtxPropWidth);
|
||||||
@ -1379,7 +1372,7 @@ dmtxDecodeCreateDiagnostic(DmtxDecode *dec, int *totalBytes, int *headerBytes, i
|
|||||||
else
|
else
|
||||||
dmtxDecodeGetPixelValue(dec, col, row, 0, &rgb[i]);
|
dmtxDecodeGetPixelValue(dec, col, row, 0, &rgb[i]);
|
||||||
|
|
||||||
rgb[i] += (int)(shade * (double)(255 - rgb[i]) + 0.5);
|
rgb[i] += (int)(shade * (float)(255 - rgb[i]) + 0.5);
|
||||||
if(rgb[i] > 255)
|
if(rgb[i] > 255)
|
||||||
rgb[i] = 255;
|
rgb[i] = 255;
|
||||||
}
|
}
|
||||||
@ -1564,7 +1557,7 @@ PopulateArrayFromMatrix(DmtxDecode *dec, DmtxRegion *reg, DmtxMessage *msg)
|
|||||||
colTmp = (xRegionCount * mapWidth) + mapCol;
|
colTmp = (xRegionCount * mapWidth) + mapCol;
|
||||||
idx = (rowTmp * xRegionTotal * mapWidth) + colTmp;
|
idx = (rowTmp * xRegionTotal * mapWidth) + colTmp;
|
||||||
|
|
||||||
if(tally[mapRow][mapCol]/(double)weightFactor >= 0.5)
|
if(tally[mapRow][mapCol]/(float)weightFactor >= 0.5)
|
||||||
msg->array[idx] = DmtxModuleOnRGB;
|
msg->array[idx] = DmtxModuleOnRGB;
|
||||||
else
|
else
|
||||||
msg->array[idx] = DmtxModuleOff;
|
msg->array[idx] = DmtxModuleOff;
|
||||||
@ -2442,7 +2435,7 @@ MatrixRegionOrientation(DmtxDecode *dec, DmtxRegion *reg, DmtxPointFlow begin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = FindTravelLimits(dec, reg, &line1x);
|
err = FindTravelLimits(dec, reg, &line1x);
|
||||||
if(line1x.distSq < 100 || line1x.devn * 10 >= sqrt((double)line1x.distSq)) {
|
if(line1x.distSq < 100 || line1x.devn * 10 >= sqrt((float)line1x.distSq)) {
|
||||||
TrailClear(dec, reg, 0x40);
|
TrailClear(dec, reg, 0x40);
|
||||||
return DmtxFail;
|
return DmtxFail;
|
||||||
}
|
}
|
||||||
@ -2459,7 +2452,7 @@ MatrixRegionOrientation(DmtxDecode *dec, DmtxRegion *reg, DmtxPointFlow begin)
|
|||||||
if(line2p.mag > line2n.mag) {
|
if(line2p.mag > line2n.mag) {
|
||||||
line2x = line2p;
|
line2x = line2p;
|
||||||
err = FindTravelLimits(dec, reg, &line2x);
|
err = FindTravelLimits(dec, reg, &line2x);
|
||||||
if(line2x.distSq < 100 || line2x.devn * 10 >= sqrt((double)line2x.distSq))
|
if(line2x.distSq < 100 || line2x.devn * 10 >= sqrt((float)line2x.distSq))
|
||||||
return DmtxFail;
|
return DmtxFail;
|
||||||
|
|
||||||
cross = ((line1x.locPos.X - line1x.locNeg.X) * (line2x.locPos.Y - line2x.locNeg.Y)) -
|
cross = ((line1x.locPos.X - line1x.locNeg.X) * (line2x.locPos.Y - line2x.locNeg.Y)) -
|
||||||
@ -2496,7 +2489,7 @@ MatrixRegionOrientation(DmtxDecode *dec, DmtxRegion *reg, DmtxPointFlow begin)
|
|||||||
else {
|
else {
|
||||||
line2x = line2n;
|
line2x = line2n;
|
||||||
err = FindTravelLimits(dec, reg, &line2x);
|
err = FindTravelLimits(dec, reg, &line2x);
|
||||||
if(line2x.distSq < 100 || line2x.devn / sqrt((double)line2x.distSq) >= 0.1)
|
if(line2x.distSq < 100 || line2x.devn / sqrt((float)line2x.distSq) >= 0.1)
|
||||||
return DmtxFail;
|
return DmtxFail;
|
||||||
|
|
||||||
cross = ((line1x.locNeg.X - line1x.locPos.X) * (line2x.locNeg.Y - line2x.locPos.Y)) -
|
cross = ((line1x.locNeg.X - line1x.locPos.X) * (line2x.locNeg.Y - line2x.locPos.Y)) -
|
||||||
@ -2561,14 +2554,14 @@ extern DmtxPassFail
|
|||||||
dmtxRegionUpdateCorners(DmtxDecode *dec, DmtxRegion *reg, DmtxVector2 p00,
|
dmtxRegionUpdateCorners(DmtxDecode *dec, DmtxRegion *reg, DmtxVector2 p00,
|
||||||
DmtxVector2 p10, DmtxVector2 p11, DmtxVector2 p01)
|
DmtxVector2 p10, DmtxVector2 p11, DmtxVector2 p01)
|
||||||
{
|
{
|
||||||
double xMax, yMax;
|
float xMax, yMax;
|
||||||
double tx, ty, phi, shx, scx, scy, skx, sky;
|
float tx, ty, phi, shx, scx, scy, skx, sky;
|
||||||
double dimOT, dimOR, dimTX, dimRX, ratio;
|
float dimOT, dimOR, dimTX, dimRX, ratio;
|
||||||
DmtxVector2 vOT, vOR, vTX, vRX, vTmp;
|
DmtxVector2 vOT, vOR, vTX, vRX, vTmp;
|
||||||
DmtxMatrix3 m, mtxy, mphi, mshx, mscx, mscy, mscxy, msky, mskx;
|
DmtxMatrix3 m, mtxy, mphi, mshx, mscx, mscy, mscxy, msky, mskx;
|
||||||
|
|
||||||
xMax = (double)(dmtxDecodeGetProp(dec, DmtxPropWidth) - 1);
|
xMax = (float)(dmtxDecodeGetProp(dec, DmtxPropWidth) - 1);
|
||||||
yMax = (double)(dmtxDecodeGetProp(dec, DmtxPropHeight) - 1);
|
yMax = (float)(dmtxDecodeGetProp(dec, DmtxPropHeight) - 1);
|
||||||
|
|
||||||
if(p00.X < 0.0 || p00.Y < 0.0 || p00.X > xMax || p00.Y > yMax ||
|
if(p00.X < 0.0 || p00.Y < 0.0 || p00.X > xMax || p00.Y > yMax ||
|
||||||
p01.X < 0.0 || p01.Y < 0.0 || p01.X > xMax || p01.Y > yMax ||
|
p01.X < 0.0 || p01.Y < 0.0 || p01.X > xMax || p01.Y > yMax ||
|
||||||
@ -2663,15 +2656,15 @@ dmtxRegionUpdateCorners(DmtxDecode *dec, DmtxRegion *reg, DmtxVector2 p00,
|
|||||||
extern DmtxPassFail
|
extern DmtxPassFail
|
||||||
dmtxRegionUpdateXfrms(DmtxDecode *dec, DmtxRegion *reg)
|
dmtxRegionUpdateXfrms(DmtxDecode *dec, DmtxRegion *reg)
|
||||||
{
|
{
|
||||||
double radians;
|
float radians;
|
||||||
DmtxRay2 rLeft, rBottom, rTop, rRight;
|
DmtxRay2 rLeft, rBottom, rTop, rRight;
|
||||||
DmtxVector2 p00, p10, p11, p01;
|
DmtxVector2 p00, p10, p11, p01;
|
||||||
|
|
||||||
assert(reg->leftKnown != 0 && reg->bottomKnown != 0);
|
assert(reg->leftKnown != 0 && reg->bottomKnown != 0);
|
||||||
|
|
||||||
/* Build ray representing left edge */
|
/* Build ray representing left edge */
|
||||||
rLeft.p.X = (double)reg->leftLoc.X;
|
rLeft.p.X = (float)reg->leftLoc.X;
|
||||||
rLeft.p.Y = (double)reg->leftLoc.Y;
|
rLeft.p.Y = (float)reg->leftLoc.Y;
|
||||||
radians = reg->leftAngle * (M_PI/DMTX_HOUGH_RES);
|
radians = reg->leftAngle * (M_PI/DMTX_HOUGH_RES);
|
||||||
rLeft.v.X = cos(radians);
|
rLeft.v.X = cos(radians);
|
||||||
rLeft.v.Y = sin(radians);
|
rLeft.v.Y = sin(radians);
|
||||||
@ -2679,8 +2672,8 @@ dmtxRegionUpdateXfrms(DmtxDecode *dec, DmtxRegion *reg)
|
|||||||
rLeft.tMax = dmtxVector2Norm(&rLeft.v);
|
rLeft.tMax = dmtxVector2Norm(&rLeft.v);
|
||||||
|
|
||||||
/* Build ray representing bottom edge */
|
/* Build ray representing bottom edge */
|
||||||
rBottom.p.X = (double)reg->bottomLoc.X;
|
rBottom.p.X = (float)reg->bottomLoc.X;
|
||||||
rBottom.p.Y = (double)reg->bottomLoc.Y;
|
rBottom.p.Y = (float)reg->bottomLoc.Y;
|
||||||
radians = reg->bottomAngle * (M_PI/DMTX_HOUGH_RES);
|
radians = reg->bottomAngle * (M_PI/DMTX_HOUGH_RES);
|
||||||
rBottom.v.X = cos(radians);
|
rBottom.v.X = cos(radians);
|
||||||
rBottom.v.Y = sin(radians);
|
rBottom.v.Y = sin(radians);
|
||||||
@ -2689,8 +2682,8 @@ dmtxRegionUpdateXfrms(DmtxDecode *dec, DmtxRegion *reg)
|
|||||||
|
|
||||||
/* Build ray representing top edge */
|
/* Build ray representing top edge */
|
||||||
if(reg->topKnown != 0) {
|
if(reg->topKnown != 0) {
|
||||||
rTop.p.X = (double)reg->topLoc.X;
|
rTop.p.X = (float)reg->topLoc.X;
|
||||||
rTop.p.Y = (double)reg->topLoc.Y;
|
rTop.p.Y = (float)reg->topLoc.Y;
|
||||||
radians = reg->topAngle * (M_PI/DMTX_HOUGH_RES);
|
radians = reg->topAngle * (M_PI/DMTX_HOUGH_RES);
|
||||||
rTop.v.X = cos(radians);
|
rTop.v.X = cos(radians);
|
||||||
rTop.v.Y = sin(radians);
|
rTop.v.Y = sin(radians);
|
||||||
@ -2698,8 +2691,8 @@ dmtxRegionUpdateXfrms(DmtxDecode *dec, DmtxRegion *reg)
|
|||||||
rTop.tMax = dmtxVector2Norm(&rTop.v);
|
rTop.tMax = dmtxVector2Norm(&rTop.v);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rTop.p.X = (double)reg->locT.X;
|
rTop.p.X = (float)reg->locT.X;
|
||||||
rTop.p.Y = (double)reg->locT.Y;
|
rTop.p.Y = (float)reg->locT.Y;
|
||||||
radians = reg->bottomAngle * (M_PI/DMTX_HOUGH_RES);
|
radians = reg->bottomAngle * (M_PI/DMTX_HOUGH_RES);
|
||||||
rTop.v.X = cos(radians);
|
rTop.v.X = cos(radians);
|
||||||
rTop.v.Y = sin(radians);
|
rTop.v.Y = sin(radians);
|
||||||
@ -2709,8 +2702,8 @@ dmtxRegionUpdateXfrms(DmtxDecode *dec, DmtxRegion *reg)
|
|||||||
|
|
||||||
/* Build ray representing right edge */
|
/* Build ray representing right edge */
|
||||||
if(reg->rightKnown != 0) {
|
if(reg->rightKnown != 0) {
|
||||||
rRight.p.X = (double)reg->rightLoc.X;
|
rRight.p.X = (float)reg->rightLoc.X;
|
||||||
rRight.p.Y = (double)reg->rightLoc.Y;
|
rRight.p.Y = (float)reg->rightLoc.Y;
|
||||||
radians = reg->rightAngle * (M_PI/DMTX_HOUGH_RES);
|
radians = reg->rightAngle * (M_PI/DMTX_HOUGH_RES);
|
||||||
rRight.v.X = cos(radians);
|
rRight.v.X = cos(radians);
|
||||||
rRight.v.Y = sin(radians);
|
rRight.v.Y = sin(radians);
|
||||||
@ -2718,8 +2711,8 @@ dmtxRegionUpdateXfrms(DmtxDecode *dec, DmtxRegion *reg)
|
|||||||
rRight.tMax = dmtxVector2Norm(&rRight.v);
|
rRight.tMax = dmtxVector2Norm(&rRight.v);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rRight.p.X = (double)reg->locR.X;
|
rRight.p.X = (float)reg->locR.X;
|
||||||
rRight.p.Y = (double)reg->locR.Y;
|
rRight.p.Y = (float)reg->locR.Y;
|
||||||
radians = reg->leftAngle * (M_PI/DMTX_HOUGH_RES);
|
radians = reg->leftAngle * (M_PI/DMTX_HOUGH_RES);
|
||||||
rRight.v.X = cos(radians);
|
rRight.v.X = cos(radians);
|
||||||
rRight.v.Y = sin(radians);
|
rRight.v.Y = sin(radians);
|
||||||
@ -2750,8 +2743,8 @@ dmtxRegionUpdateXfrms(DmtxDecode *dec, DmtxRegion *reg)
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static double
|
static float
|
||||||
RightAngleTrueness(DmtxVector2 c0, DmtxVector2 c1, DmtxVector2 c2, double angle)
|
RightAngleTrueness(DmtxVector2 c0, DmtxVector2 c1, DmtxVector2 c2, float angle)
|
||||||
{
|
{
|
||||||
DmtxVector2 vA, vB;
|
DmtxVector2 vA, vB;
|
||||||
DmtxMatrix3 m;
|
DmtxMatrix3 m;
|
||||||
@ -2782,8 +2775,8 @@ ReadModuleColor(DmtxDecode *dec, DmtxRegion *reg, int symbolRow, int symbolCol,
|
|||||||
int i;
|
int i;
|
||||||
int symbolRows, symbolCols;
|
int symbolRows, symbolCols;
|
||||||
int color, colorTmp;
|
int color, colorTmp;
|
||||||
double sampleX[] = { 0.5, 0.4, 0.5, 0.6, 0.5 };
|
float sampleX[] = { 0.5, 0.4, 0.5, 0.6, 0.5 };
|
||||||
double sampleY[] = { 0.5, 0.5, 0.4, 0.5, 0.6 };
|
float sampleY[] = { 0.5, 0.5, 0.4, 0.5, 0.6 };
|
||||||
DmtxVector2 p;
|
DmtxVector2 p;
|
||||||
|
|
||||||
symbolRows = dmtxGetSymbolAttribute(DmtxSymAttribSymbolRows, sizeIdx);
|
symbolRows = dmtxGetSymbolAttribute(DmtxSymAttribSymbolRows, sizeIdx);
|
||||||
@ -5506,11 +5499,11 @@ dmtxImageContainsInt(DmtxImage *img, int margin, int x, int y)
|
|||||||
* \return DmtxTrue | DmtxFalse
|
* \return DmtxTrue | DmtxFalse
|
||||||
*/
|
*/
|
||||||
extern DmtxBoolean
|
extern DmtxBoolean
|
||||||
dmtxImageContainsFloat(DmtxImage *img, double x, double y)
|
dmtxImageContainsFloat(DmtxImage *img, float x, float y)
|
||||||
{
|
{
|
||||||
assert(img != NULL);
|
assert(img != NULL);
|
||||||
|
|
||||||
if(x >= 0.0 && x < (double)img->width && y >= 0.0 && y < (double)img->height)
|
if(x >= 0.0 && x < (float)img->width && y >= 0.0 && y < (float)img->height)
|
||||||
return DmtxTrue;
|
return DmtxTrue;
|
||||||
|
|
||||||
return DmtxFalse;
|
return DmtxFalse;
|
||||||
@ -5769,7 +5762,7 @@ dmtxVector2Sub(DmtxVector2 *vOut, const DmtxVector2 *v1, const DmtxVector2 *v2)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
extern DmtxVector2 *
|
extern DmtxVector2 *
|
||||||
dmtxVector2ScaleBy(DmtxVector2 *v, double s)
|
dmtxVector2ScaleBy(DmtxVector2 *v, float s)
|
||||||
{
|
{
|
||||||
v->X *= s;
|
v->X *= s;
|
||||||
v->Y *= s;
|
v->Y *= s;
|
||||||
@ -5782,7 +5775,7 @@ dmtxVector2ScaleBy(DmtxVector2 *v, double s)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
extern DmtxVector2 *
|
extern DmtxVector2 *
|
||||||
dmtxVector2Scale(DmtxVector2 *vOut, const DmtxVector2 *v, double s)
|
dmtxVector2Scale(DmtxVector2 *vOut, const DmtxVector2 *v, float s)
|
||||||
{
|
{
|
||||||
*vOut = *v;
|
*vOut = *v;
|
||||||
|
|
||||||
@ -5793,7 +5786,7 @@ dmtxVector2Scale(DmtxVector2 *vOut, const DmtxVector2 *v, double s)
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
extern double
|
extern float
|
||||||
dmtxVector2Cross(const DmtxVector2 *v1, const DmtxVector2 *v2)
|
dmtxVector2Cross(const DmtxVector2 *v1, const DmtxVector2 *v2)
|
||||||
{
|
{
|
||||||
return (v1->X * v2->Y) - (v1->Y * v2->X);
|
return (v1->X * v2->Y) - (v1->Y * v2->X);
|
||||||
@ -5803,10 +5796,10 @@ dmtxVector2Cross(const DmtxVector2 *v1, const DmtxVector2 *v2)
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
extern double
|
extern float
|
||||||
dmtxVector2Norm(DmtxVector2 *v)
|
dmtxVector2Norm(DmtxVector2 *v)
|
||||||
{
|
{
|
||||||
double mag;
|
float mag;
|
||||||
|
|
||||||
mag = dmtxVector2Mag(v);
|
mag = dmtxVector2Mag(v);
|
||||||
|
|
||||||
@ -5822,7 +5815,7 @@ dmtxVector2Norm(DmtxVector2 *v)
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
extern double
|
extern float
|
||||||
dmtxVector2Dot(const DmtxVector2 *v1, const DmtxVector2 *v2)
|
dmtxVector2Dot(const DmtxVector2 *v1, const DmtxVector2 *v2)
|
||||||
{
|
{
|
||||||
return (v1->X * v2->X) + (v1->Y * v2->Y);
|
return (v1->X * v2->X) + (v1->Y * v2->Y);
|
||||||
@ -5832,7 +5825,7 @@ dmtxVector2Dot(const DmtxVector2 *v1, const DmtxVector2 *v2)
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
extern double
|
extern float
|
||||||
dmtxVector2Mag(const DmtxVector2 *v)
|
dmtxVector2Mag(const DmtxVector2 *v)
|
||||||
{
|
{
|
||||||
return sqrt(v->X * v->X + v->Y * v->Y);
|
return sqrt(v->X * v->X + v->Y * v->Y);
|
||||||
@ -5842,7 +5835,7 @@ dmtxVector2Mag(const DmtxVector2 *v)
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
extern double
|
extern float
|
||||||
dmtxDistanceFromRay2(const DmtxRay2 *r, const DmtxVector2 *q)
|
dmtxDistanceFromRay2(const DmtxRay2 *r, const DmtxVector2 *q)
|
||||||
{
|
{
|
||||||
DmtxVector2 vSubTmp;
|
DmtxVector2 vSubTmp;
|
||||||
@ -5857,7 +5850,7 @@ dmtxDistanceFromRay2(const DmtxRay2 *r, const DmtxVector2 *q)
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
extern double
|
extern float
|
||||||
dmtxDistanceAlongRay2(const DmtxRay2 *r, const DmtxVector2 *q)
|
dmtxDistanceAlongRay2(const DmtxRay2 *r, const DmtxVector2 *q)
|
||||||
{
|
{
|
||||||
DmtxVector2 vSubTmp;
|
DmtxVector2 vSubTmp;
|
||||||
@ -5879,7 +5872,7 @@ dmtxDistanceAlongRay2(const DmtxRay2 *r, const DmtxVector2 *q)
|
|||||||
extern DmtxPassFail
|
extern DmtxPassFail
|
||||||
dmtxRay2Intersect(DmtxVector2 *point, const DmtxRay2 *p0, const DmtxRay2 *p1)
|
dmtxRay2Intersect(DmtxVector2 *point, const DmtxRay2 *p0, const DmtxRay2 *p1)
|
||||||
{
|
{
|
||||||
double numer, denom;
|
float numer, denom;
|
||||||
DmtxVector2 w;
|
DmtxVector2 w;
|
||||||
|
|
||||||
denom = dmtxVector2Cross(&(p1->v), &(p0->v));
|
denom = dmtxVector2Cross(&(p1->v), &(p0->v));
|
||||||
@ -5897,7 +5890,7 @@ dmtxRay2Intersect(DmtxVector2 *point, const DmtxRay2 *p0, const DmtxRay2 *p1)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
extern DmtxPassFail
|
extern DmtxPassFail
|
||||||
dmtxPointAlongRay2(DmtxVector2 *point, const DmtxRay2 *r, double t)
|
dmtxPointAlongRay2(DmtxVector2 *point, const DmtxRay2 *r, float t)
|
||||||
{
|
{
|
||||||
DmtxVector2 vTmp;
|
DmtxVector2 vTmp;
|
||||||
|
|
||||||
@ -5988,7 +5981,7 @@ dmtxMatrix3Identity(DmtxMatrix3 m)
|
|||||||
* (0,0) (1,0) (0,0) (1,0)
|
* (0,0) (1,0) (0,0) (1,0)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void dmtxMatrix3Translate(DmtxMatrix3 m, double tx, double ty)
|
void dmtxMatrix3Translate(DmtxMatrix3 m, float tx, float ty)
|
||||||
{
|
{
|
||||||
dmtxMatrix3Identity(m);
|
dmtxMatrix3Identity(m);
|
||||||
m[2][0] = tx;
|
m[2][0] = tx;
|
||||||
@ -6015,9 +6008,9 @@ void dmtxMatrix3Translate(DmtxMatrix3 m, double tx, double ty)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
extern void
|
extern void
|
||||||
dmtxMatrix3Rotate(DmtxMatrix3 m, double angle)
|
dmtxMatrix3Rotate(DmtxMatrix3 m, float angle)
|
||||||
{
|
{
|
||||||
double sinAngle, cosAngle;
|
float sinAngle, cosAngle;
|
||||||
|
|
||||||
sinAngle = sin(angle);
|
sinAngle = sin(angle);
|
||||||
cosAngle = cos(angle);
|
cosAngle = cos(angle);
|
||||||
@ -6051,7 +6044,7 @@ dmtxMatrix3Rotate(DmtxMatrix3 m, double angle)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
extern void
|
extern void
|
||||||
dmtxMatrix3Scale(DmtxMatrix3 m, double sx, double sy)
|
dmtxMatrix3Scale(DmtxMatrix3 m, float sx, float sy)
|
||||||
{
|
{
|
||||||
dmtxMatrix3Identity(m);
|
dmtxMatrix3Identity(m);
|
||||||
m[0][0] = sx;
|
m[0][0] = sx;
|
||||||
@ -6070,7 +6063,7 @@ dmtxMatrix3Scale(DmtxMatrix3 m, double sx, double sy)
|
|||||||
* | 0 0 1 |
|
* | 0 0 1 |
|
||||||
*/
|
*/
|
||||||
extern void
|
extern void
|
||||||
dmtxMatrix3Shear(DmtxMatrix3 m, double shx, double shy)
|
dmtxMatrix3Shear(DmtxMatrix3 m, float shx, float shy)
|
||||||
{
|
{
|
||||||
dmtxMatrix3Identity(m);
|
dmtxMatrix3Identity(m);
|
||||||
m[1][0] = shx;
|
m[1][0] = shx;
|
||||||
@ -6104,7 +6097,7 @@ dmtxMatrix3Shear(DmtxMatrix3 m, double shx, double shy)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
extern void
|
extern void
|
||||||
dmtxMatrix3LineSkewTop(DmtxMatrix3 m, double b0, double b1, double sz)
|
dmtxMatrix3LineSkewTop(DmtxMatrix3 m, float b0, float b1, float sz)
|
||||||
{
|
{
|
||||||
assert(b0 >= DmtxAlmostZero);
|
assert(b0 >= DmtxAlmostZero);
|
||||||
|
|
||||||
@ -6123,7 +6116,7 @@ dmtxMatrix3LineSkewTop(DmtxMatrix3 m, double b0, double b1, double sz)
|
|||||||
* \return void
|
* \return void
|
||||||
*/
|
*/
|
||||||
extern void
|
extern void
|
||||||
dmtxMatrix3LineSkewTopInv(DmtxMatrix3 m, double b0, double b1, double sz)
|
dmtxMatrix3LineSkewTopInv(DmtxMatrix3 m, float b0, float b1, float sz)
|
||||||
{
|
{
|
||||||
assert(b1 >= DmtxAlmostZero);
|
assert(b1 >= DmtxAlmostZero);
|
||||||
|
|
||||||
@ -6142,7 +6135,7 @@ dmtxMatrix3LineSkewTopInv(DmtxMatrix3 m, double b0, double b1, double sz)
|
|||||||
* \return void
|
* \return void
|
||||||
*/
|
*/
|
||||||
extern void
|
extern void
|
||||||
dmtxMatrix3LineSkewSide(DmtxMatrix3 m, double b0, double b1, double sz)
|
dmtxMatrix3LineSkewSide(DmtxMatrix3 m, float b0, float b1, float sz)
|
||||||
{
|
{
|
||||||
assert(b0 >= DmtxAlmostZero);
|
assert(b0 >= DmtxAlmostZero);
|
||||||
|
|
||||||
@ -6161,7 +6154,7 @@ dmtxMatrix3LineSkewSide(DmtxMatrix3 m, double b0, double b1, double sz)
|
|||||||
* \return void
|
* \return void
|
||||||
*/
|
*/
|
||||||
extern void
|
extern void
|
||||||
dmtxMatrix3LineSkewSideInv(DmtxMatrix3 m, double b0, double b1, double sz)
|
dmtxMatrix3LineSkewSideInv(DmtxMatrix3 m, float b0, float b1, float sz)
|
||||||
{
|
{
|
||||||
assert(b1 >= DmtxAlmostZero);
|
assert(b1 >= DmtxAlmostZero);
|
||||||
|
|
||||||
@ -6182,7 +6175,7 @@ extern void
|
|||||||
dmtxMatrix3Multiply(DmtxMatrix3 mOut, DmtxMatrix3 m0, DmtxMatrix3 m1)
|
dmtxMatrix3Multiply(DmtxMatrix3 mOut, DmtxMatrix3 m0, DmtxMatrix3 m1)
|
||||||
{
|
{
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
double val;
|
float val;
|
||||||
|
|
||||||
for(i = 0; i < 3; i++) {
|
for(i = 0; i < 3; i++) {
|
||||||
for(j = 0; j < 3; j++) {
|
for(j = 0; j < 3; j++) {
|
||||||
@ -6220,7 +6213,7 @@ dmtxMatrix3MultiplyBy(DmtxMatrix3 m0, DmtxMatrix3 m1)
|
|||||||
extern int
|
extern int
|
||||||
dmtxMatrix3VMultiply(DmtxVector2 *vOut, DmtxVector2 *vIn, DmtxMatrix3 m)
|
dmtxMatrix3VMultiply(DmtxVector2 *vOut, DmtxVector2 *vIn, DmtxMatrix3 m)
|
||||||
{
|
{
|
||||||
double w;
|
float w;
|
||||||
|
|
||||||
w = vIn->X*m[0][2] + vIn->Y*m[1][2] + m[2][2];
|
w = vIn->X*m[0][2] + vIn->Y*m[1][2] + m[2][2];
|
||||||
if(fabs(w) <= DmtxAlmostZero) {
|
if(fabs(w) <= DmtxAlmostZero) {
|
||||||
|
|||||||
@ -26,13 +26,6 @@
|
|||||||
#define malloc(size) ({ void *_r = umm_malloc(size); if(!_r) fb_alloc_fail(); _r; })
|
#define malloc(size) ({ void *_r = umm_malloc(size); if(!_r) fb_alloc_fail(); _r; })
|
||||||
#define realloc(ptr, size) ({ void *_r = umm_realloc((ptr), (size)); if(!_r) fb_alloc_fail(); _r; })
|
#define realloc(ptr, size) ({ void *_r = umm_realloc((ptr), (size)); if(!_r) fb_alloc_fail(); _r; })
|
||||||
#define calloc(num, item_size) ({ void *_r = umm_calloc((num), (item_size)); if(!_r) fb_alloc_fail(); _r; })
|
#define calloc(num, item_size) ({ void *_r = umm_calloc((num), (item_size)); if(!_r) fb_alloc_fail(); _r; })
|
||||||
#define double float
|
|
||||||
#undef DBL_MIN
|
|
||||||
#define DBL_MIN FLT_MIN
|
|
||||||
#undef DBL_MAX
|
|
||||||
#define DBL_MAX FLT_MAX
|
|
||||||
#undef DBL_EPSILON
|
|
||||||
#define DBL_EPSILON FLT_EPSILON
|
|
||||||
#define sqrt(x) fast_sqrtf(x)
|
#define sqrt(x) fast_sqrtf(x)
|
||||||
#define floor(x) fast_floorf(x)
|
#define floor(x) fast_floorf(x)
|
||||||
#define ceil(x) fast_ceilf(x)
|
#define ceil(x) fast_ceilf(x)
|
||||||
@ -174,7 +167,7 @@
|
|||||||
'reg_img' image, when asked for.
|
'reg_img' image, when asked for.
|
||||||
Suggested value: NULL
|
Suggested value: NULL
|
||||||
|
|
||||||
@return A double array of size 7 x n_out, containing the list
|
@return A float array of size 7 x n_out, containing the list
|
||||||
of line segments detected. The array contains first
|
of line segments detected. The array contains first
|
||||||
7 values of line segment number 1, then the 7 values
|
7 values of line segment number 1, then the 7 values
|
||||||
of line segment number 2, and so on, and it finish
|
of line segment number 2, and so on, and it finish
|
||||||
@ -189,10 +182,10 @@
|
|||||||
line segment number 'n+1' are obtained with
|
line segment number 'n+1' are obtained with
|
||||||
'out[7*n+0]' to 'out[7*n+6]'.
|
'out[7*n+0]' to 'out[7*n+6]'.
|
||||||
*/
|
*/
|
||||||
double * LineSegmentDetection( int * n_out,
|
float * LineSegmentDetection( int * n_out,
|
||||||
unsigned char * img, int X, int Y,
|
unsigned char * img, int X, int Y,
|
||||||
double scale, double sigma_scale, double quant,
|
float scale, float sigma_scale, float quant,
|
||||||
double ang_th, double log_eps, double density_th,
|
float ang_th, float log_eps, float density_th,
|
||||||
int n_bins,
|
int n_bins,
|
||||||
int ** reg_img, int * reg_x, int * reg_y );
|
int ** reg_img, int * reg_x, int * reg_y );
|
||||||
|
|
||||||
@ -242,7 +235,7 @@ double * LineSegmentDetection( int * n_out,
|
|||||||
'reg_img' image, when asked for.
|
'reg_img' image, when asked for.
|
||||||
Suggested value: NULL
|
Suggested value: NULL
|
||||||
|
|
||||||
@return A double array of size 7 x n_out, containing the list
|
@return A float array of size 7 x n_out, containing the list
|
||||||
of line segments detected. The array contains first
|
of line segments detected. The array contains first
|
||||||
7 values of line segment number 1, then the 7 values
|
7 values of line segment number 1, then the 7 values
|
||||||
of line segment number 2, and so on, and it finish
|
of line segment number 2, and so on, and it finish
|
||||||
@ -257,8 +250,8 @@ double * LineSegmentDetection( int * n_out,
|
|||||||
line segment number 'n+1' are obtained with
|
line segment number 'n+1' are obtained with
|
||||||
'out[7*n+0]' to 'out[7*n+6]'.
|
'out[7*n+0]' to 'out[7*n+6]'.
|
||||||
*/
|
*/
|
||||||
double * lsd_scale_region( int * n_out,
|
float * lsd_scale_region( int * n_out,
|
||||||
unsigned char * img, int X, int Y, double scale,
|
unsigned char * img, int X, int Y, float scale,
|
||||||
int ** reg_img, int * reg_x, int * reg_y );
|
int ** reg_img, int * reg_x, int * reg_y );
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
@ -283,7 +276,7 @@ double * lsd_scale_region( int * n_out,
|
|||||||
is applied.
|
is applied.
|
||||||
Suggested value: 0.8
|
Suggested value: 0.8
|
||||||
|
|
||||||
@return A double array of size 7 x n_out, containing the list
|
@return A float array of size 7 x n_out, containing the list
|
||||||
of line segments detected. The array contains first
|
of line segments detected. The array contains first
|
||||||
7 values of line segment number 1, then the 7 values
|
7 values of line segment number 1, then the 7 values
|
||||||
of line segment number 2, and so on, and it finish
|
of line segment number 2, and so on, and it finish
|
||||||
@ -298,7 +291,7 @@ double * lsd_scale_region( int * n_out,
|
|||||||
line segment number 'n+1' are obtained with
|
line segment number 'n+1' are obtained with
|
||||||
'out[7*n+0]' to 'out[7*n+6]'.
|
'out[7*n+0]' to 'out[7*n+6]'.
|
||||||
*/
|
*/
|
||||||
double * lsd_scale(int * n_out, unsigned char * img, int X, int Y, double scale);
|
float * lsd_scale(int * n_out, unsigned char * img, int X, int Y, float scale);
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
/** LSD Simple Interface
|
/** LSD Simple Interface
|
||||||
@ -314,7 +307,7 @@ double * lsd_scale(int * n_out, unsigned char * img, int X, int Y, double scale)
|
|||||||
|
|
||||||
@param Y Y size of the image: the number of rows.
|
@param Y Y size of the image: the number of rows.
|
||||||
|
|
||||||
@return A double array of size 7 x n_out, containing the list
|
@return A float array of size 7 x n_out, containing the list
|
||||||
of line segments detected. The array contains first
|
of line segments detected. The array contains first
|
||||||
7 values of line segment number 1, then the 7 values
|
7 values of line segment number 1, then the 7 values
|
||||||
of line segment number 2, and so on, and it finish
|
of line segment number 2, and so on, and it finish
|
||||||
@ -329,7 +322,7 @@ double * lsd_scale(int * n_out, unsigned char * img, int X, int Y, double scale)
|
|||||||
line segment number 'n+1' are obtained with
|
line segment number 'n+1' are obtained with
|
||||||
'out[7*n+0]' to 'out[7*n+6]'.
|
'out[7*n+0]' to 'out[7*n+6]'.
|
||||||
*/
|
*/
|
||||||
double * lsd(int * n_out, unsigned char * img, int X, int Y);
|
float * lsd(int * n_out, unsigned char * img, int X, int Y);
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -510,9 +503,9 @@ struct lsd_point {int16_t x,y;};
|
|||||||
should be related to the cumulated rounding error in the chain of
|
should be related to the cumulated rounding error in the chain of
|
||||||
computation. Here, as a simplification, a fixed factor is used.
|
computation. Here, as a simplification, a fixed factor is used.
|
||||||
*/
|
*/
|
||||||
static int double_equal(double a, double b)
|
static int double_equal(float a, float b)
|
||||||
{
|
{
|
||||||
double abs_diff,aa,bb,abs_max;
|
float abs_diff,aa,bb,abs_max;
|
||||||
|
|
||||||
/* trivial case */
|
/* trivial case */
|
||||||
if( a == b ) return TRUE;
|
if( a == b ) return TRUE;
|
||||||
@ -522,21 +515,21 @@ static int double_equal(double a, double b)
|
|||||||
bb = fabs(b);
|
bb = fabs(b);
|
||||||
abs_max = aa > bb ? aa : bb;
|
abs_max = aa > bb ? aa : bb;
|
||||||
|
|
||||||
/* DBL_MIN is the smallest normalized number, thus, the smallest
|
/* FLT_MIN is the smallest normalized number, thus, the smallest
|
||||||
number whose relative error is bounded by DBL_EPSILON. For
|
number whose relative error is bounded by FLT_EPSILON. For
|
||||||
smaller numbers, the same quantization steps as for DBL_MIN
|
smaller numbers, the same quantization steps as for FLT_MIN
|
||||||
are used. Then, for smaller numbers, a meaningful "relative"
|
are used. Then, for smaller numbers, a meaningful "relative"
|
||||||
error should be computed by dividing the difference by DBL_MIN. */
|
error should be computed by dividing the difference by FLT_MIN. */
|
||||||
if( abs_max < DBL_MIN ) abs_max = DBL_MIN;
|
if( abs_max < FLT_MIN ) abs_max = FLT_MIN;
|
||||||
|
|
||||||
/* equal if relative error <= factor x eps */
|
/* equal if relative error <= factor x eps */
|
||||||
return (abs_diff / abs_max) <= (RELATIVE_ERROR_FACTOR * DBL_EPSILON);
|
return (abs_diff / abs_max) <= (RELATIVE_ERROR_FACTOR * FLT_EPSILON);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
/** Computes Euclidean distance between point (x1,y1) and point (x2,y2).
|
/** Computes Euclidean distance between point (x1,y1) and point (x2,y2).
|
||||||
*/
|
*/
|
||||||
static double dist(double x1, double y1, double x2, double y2)
|
static float dist(float x1, float y1, float x2, float y2)
|
||||||
{
|
{
|
||||||
return sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) );
|
return sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) );
|
||||||
}
|
}
|
||||||
@ -572,7 +565,7 @@ typedef struct ntuple_list_s
|
|||||||
unsigned int size;
|
unsigned int size;
|
||||||
unsigned int max_size;
|
unsigned int max_size;
|
||||||
unsigned int dim;
|
unsigned int dim;
|
||||||
double * values;
|
float * values;
|
||||||
} * ntuple_list;
|
} * ntuple_list;
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
@ -607,7 +600,7 @@ static ntuple_list new_ntuple_list(unsigned int dim)
|
|||||||
n_tuple->dim = dim;
|
n_tuple->dim = dim;
|
||||||
|
|
||||||
/* get memory for tuples */
|
/* get memory for tuples */
|
||||||
n_tuple->values = (double *) malloc( dim*n_tuple->max_size * sizeof(double) );
|
n_tuple->values = (float *) malloc( dim*n_tuple->max_size * sizeof(float) );
|
||||||
if( n_tuple->values == NULL ) error("not enough memory.");
|
if( n_tuple->values == NULL ) error("not enough memory.");
|
||||||
|
|
||||||
return n_tuple;
|
return n_tuple;
|
||||||
@ -626,16 +619,16 @@ static void enlarge_ntuple_list(ntuple_list n_tuple)
|
|||||||
n_tuple->max_size *= 2;
|
n_tuple->max_size *= 2;
|
||||||
|
|
||||||
/* realloc memory */
|
/* realloc memory */
|
||||||
n_tuple->values = (double *) realloc( (void *) n_tuple->values,
|
n_tuple->values = (float *) realloc( (void *) n_tuple->values,
|
||||||
n_tuple->dim * n_tuple->max_size * sizeof(double) );
|
n_tuple->dim * n_tuple->max_size * sizeof(float) );
|
||||||
if( n_tuple->values == NULL ) error("not enough memory.");
|
if( n_tuple->values == NULL ) error("not enough memory.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
/** Add a 7-tuple to an n-tuple list.
|
/** Add a 7-tuple to an n-tuple list.
|
||||||
*/
|
*/
|
||||||
static void add_7tuple( ntuple_list out, double v1, double v2, double v3,
|
static void add_7tuple( ntuple_list out, float v1, float v2, float v3,
|
||||||
double v4, double v5, double v6, double v7 )
|
float v4, float v5, float v6, float v7 )
|
||||||
{
|
{
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
if( out == NULL ) error("add_7tuple: invalid n-tuple input.");
|
if( out == NULL ) error("add_7tuple: invalid n-tuple input.");
|
||||||
@ -827,7 +820,7 @@ static image_int new_image_int_ini( unsigned int xsize, unsigned int ysize,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
/** double image data type
|
/** float image data type
|
||||||
|
|
||||||
The pixel value at (x,y) is accessed by:
|
The pixel value at (x,y) is accessed by:
|
||||||
|
|
||||||
@ -837,7 +830,7 @@ static image_int new_image_int_ini( unsigned int xsize, unsigned int ysize,
|
|||||||
*/
|
*/
|
||||||
typedef struct image_double_s
|
typedef struct image_double_s
|
||||||
{
|
{
|
||||||
double * data;
|
float * data;
|
||||||
unsigned int xsize,ysize;
|
unsigned int xsize,ysize;
|
||||||
} * image_double;
|
} * image_double;
|
||||||
|
|
||||||
@ -865,7 +858,7 @@ static image_double new_image_double(unsigned int xsize, unsigned int ysize)
|
|||||||
/* get memory */
|
/* get memory */
|
||||||
image = (image_double) malloc( sizeof(struct image_double_s) );
|
image = (image_double) malloc( sizeof(struct image_double_s) );
|
||||||
if( image == NULL ) error("not enough memory.");
|
if( image == NULL ) error("not enough memory.");
|
||||||
image->data = (double *) calloc( (size_t) (xsize*ysize), sizeof(double) );
|
image->data = (float *) calloc( (size_t) (xsize*ysize), sizeof(float) );
|
||||||
if( image->data == NULL ) error("not enough memory.");
|
if( image->data == NULL ) error("not enough memory.");
|
||||||
|
|
||||||
/* set image size */
|
/* set image size */
|
||||||
@ -880,7 +873,7 @@ static image_double new_image_double(unsigned int xsize, unsigned int ysize)
|
|||||||
with the data pointed by 'data'.
|
with the data pointed by 'data'.
|
||||||
*/
|
*/
|
||||||
static image_double new_image_double_ptr( unsigned int xsize,
|
static image_double new_image_double_ptr( unsigned int xsize,
|
||||||
unsigned int ysize, double * data )
|
unsigned int ysize, float * data )
|
||||||
{
|
{
|
||||||
image_double image;
|
image_double image;
|
||||||
|
|
||||||
@ -914,10 +907,10 @@ static image_double new_image_double_ptr( unsigned int xsize,
|
|||||||
in the middle point between values 'kernel->values[0]'
|
in the middle point between values 'kernel->values[0]'
|
||||||
and 'kernel->values[1]'.
|
and 'kernel->values[1]'.
|
||||||
*/
|
*/
|
||||||
static void gaussian_kernel(ntuple_list kernel, double sigma, double mean)
|
static void gaussian_kernel(ntuple_list kernel, float sigma, float mean)
|
||||||
{
|
{
|
||||||
double sum = 0.0;
|
float sum = 0.0;
|
||||||
double val;
|
float val;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
@ -930,7 +923,7 @@ static void gaussian_kernel(ntuple_list kernel, double sigma, double mean)
|
|||||||
kernel->size = 1;
|
kernel->size = 1;
|
||||||
for(i=0;i<kernel->dim;i++)
|
for(i=0;i<kernel->dim;i++)
|
||||||
{
|
{
|
||||||
val = ( (double) i - mean ) / sigma;
|
val = ( (float) i - mean ) / sigma;
|
||||||
kernel->values[i] = exp( -0.5 * val * val );
|
kernel->values[i] = exp( -0.5 * val * val );
|
||||||
sum += kernel->values[i];
|
sum += kernel->values[i];
|
||||||
}
|
}
|
||||||
@ -977,14 +970,14 @@ static void gaussian_kernel(ntuple_list kernel, double sigma, double mean)
|
|||||||
in the x axis, and then the combined Gaussian kernel and sampling
|
in the x axis, and then the combined Gaussian kernel and sampling
|
||||||
in the y axis.
|
in the y axis.
|
||||||
*/
|
*/
|
||||||
static image_double gaussian_sampler( image_double in, double scale,
|
static image_double gaussian_sampler( image_double in, float scale,
|
||||||
double sigma_scale )
|
float sigma_scale )
|
||||||
{
|
{
|
||||||
image_double aux,out;
|
image_double aux,out;
|
||||||
ntuple_list kernel;
|
ntuple_list kernel;
|
||||||
unsigned int N,M,h,n,x,y,i;
|
unsigned int N,M,h,n,x,y,i;
|
||||||
int xc,yc,j,double_x_size,double_y_size;
|
int xc,yc,j,double_x_size,double_y_size;
|
||||||
double sigma,xx,yy,sum,prec;
|
float sigma,xx,yy,sum,prec;
|
||||||
|
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
if( in == NULL || in->data == NULL || in->xsize == 0 || in->ysize == 0 )
|
if( in == NULL || in->data == NULL || in->xsize == 0 || in->ysize == 0 )
|
||||||
@ -994,8 +987,8 @@ static image_double gaussian_sampler( image_double in, double scale,
|
|||||||
error("gaussian_sampler: 'sigma_scale' must be positive.");
|
error("gaussian_sampler: 'sigma_scale' must be positive.");
|
||||||
|
|
||||||
/* compute new image size and get memory for images */
|
/* compute new image size and get memory for images */
|
||||||
if( in->xsize * scale > (double) UINT_MAX ||
|
if( in->xsize * scale > (float) UINT_MAX ||
|
||||||
in->ysize * scale > (double) UINT_MAX )
|
in->ysize * scale > (float) UINT_MAX )
|
||||||
error("gaussian_sampler: the output image size exceeds the handled size.");
|
error("gaussian_sampler: the output image size exceeds the handled size.");
|
||||||
N = (unsigned int) ceil( in->xsize * scale );
|
N = (unsigned int) ceil( in->xsize * scale );
|
||||||
M = (unsigned int) ceil( in->ysize * scale );
|
M = (unsigned int) ceil( in->ysize * scale );
|
||||||
@ -1017,7 +1010,7 @@ static image_double gaussian_sampler( image_double in, double scale,
|
|||||||
n = 1+2*h; /* kernel size */
|
n = 1+2*h; /* kernel size */
|
||||||
kernel = new_ntuple_list(n);
|
kernel = new_ntuple_list(n);
|
||||||
|
|
||||||
/* auxiliary double image size variables */
|
/* auxiliary float image size variables */
|
||||||
double_x_size = (int) (2 * in->xsize);
|
double_x_size = (int) (2 * in->xsize);
|
||||||
double_y_size = (int) (2 * in->ysize);
|
double_y_size = (int) (2 * in->ysize);
|
||||||
|
|
||||||
@ -1029,11 +1022,11 @@ static image_double gaussian_sampler( image_double in, double scale,
|
|||||||
xx is the corresponding x-value in the original size image.
|
xx is the corresponding x-value in the original size image.
|
||||||
xc is the integer value, the pixel coordinate of xx.
|
xc is the integer value, the pixel coordinate of xx.
|
||||||
*/
|
*/
|
||||||
xx = (double) x / scale;
|
xx = (float) x / scale;
|
||||||
/* coordinate (0.0,0.0) is in the center of pixel (0,0),
|
/* coordinate (0.0,0.0) is in the center of pixel (0,0),
|
||||||
so the pixel with xc=0 get the values of xx from -0.5 to 0.5 */
|
so the pixel with xc=0 get the values of xx from -0.5 to 0.5 */
|
||||||
xc = (int) floor( xx + 0.5 );
|
xc = (int) floor( xx + 0.5 );
|
||||||
gaussian_kernel( kernel, sigma, (double) h + xx - (double) xc );
|
gaussian_kernel( kernel, sigma, (float) h + xx - (float) xc );
|
||||||
/* the kernel must be computed for each x because the fine
|
/* the kernel must be computed for each x because the fine
|
||||||
offset xx-xc is different in each case */
|
offset xx-xc is different in each case */
|
||||||
|
|
||||||
@ -1063,11 +1056,11 @@ static image_double gaussian_sampler( image_double in, double scale,
|
|||||||
yy is the corresponding x-value in the original size image.
|
yy is the corresponding x-value in the original size image.
|
||||||
yc is the integer value, the pixel coordinate of xx.
|
yc is the integer value, the pixel coordinate of xx.
|
||||||
*/
|
*/
|
||||||
yy = (double) y / scale;
|
yy = (float) y / scale;
|
||||||
/* coordinate (0.0,0.0) is in the center of pixel (0,0),
|
/* coordinate (0.0,0.0) is in the center of pixel (0,0),
|
||||||
so the pixel with yc=0 get the values of yy from -0.5 to 0.5 */
|
so the pixel with yc=0 get the values of yy from -0.5 to 0.5 */
|
||||||
yc = (int) floor( yy + 0.5 );
|
yc = (int) floor( yy + 0.5 );
|
||||||
gaussian_kernel( kernel, sigma, (double) h + yy - (double) yc );
|
gaussian_kernel( kernel, sigma, (float) h + yy - (float) yc );
|
||||||
/* the kernel must be computed for each y because the fine
|
/* the kernel must be computed for each y because the fine
|
||||||
offset yy-yc is different in each case */
|
offset yy-yc is different in each case */
|
||||||
|
|
||||||
@ -1118,13 +1111,13 @@ static image_double gaussian_sampler( image_double in, double scale,
|
|||||||
- a pointer 'mem_p' to the memory used by 'list_p' to be able to
|
- a pointer 'mem_p' to the memory used by 'list_p' to be able to
|
||||||
free the memory when it is not used anymore.
|
free the memory when it is not used anymore.
|
||||||
*/
|
*/
|
||||||
static image_int ll_angle( image_char in, double threshold,
|
static image_int ll_angle( image_char in, float threshold,
|
||||||
struct coorlist ** list_p, void ** mem_p,
|
struct coorlist ** list_p, void ** mem_p,
|
||||||
image_int * modgrad, unsigned int n_bins )
|
image_int * modgrad, unsigned int n_bins )
|
||||||
{
|
{
|
||||||
image_int g;
|
image_int g;
|
||||||
unsigned int n,p,x,y,adr,i;
|
unsigned int n,p,x,y,adr,i;
|
||||||
double com1,com2,gx,gy,norm,norm2;
|
float com1,com2,gx,gy,norm,norm2;
|
||||||
/* the rest of the variables are used for pseudo-ordering
|
/* the rest of the variables are used for pseudo-ordering
|
||||||
the gradient magnitude values */
|
the gradient magnitude values */
|
||||||
int list_count = 0;
|
int list_count = 0;
|
||||||
@ -1133,7 +1126,7 @@ static image_int ll_angle( image_char in, double threshold,
|
|||||||
struct coorlist ** range_l_e; /* array of pointers to end of bin list */
|
struct coorlist ** range_l_e; /* array of pointers to end of bin list */
|
||||||
struct coorlist * start;
|
struct coorlist * start;
|
||||||
struct coorlist * end;
|
struct coorlist * end;
|
||||||
double max_grad = 0.0;
|
float max_grad = 0.0;
|
||||||
|
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
if( in == NULL || in->data == NULL || in->xsize == 0 || in->ysize == 0 )
|
if( in == NULL || in->data == NULL || in->xsize == 0 || in->ysize == 0 )
|
||||||
@ -1215,7 +1208,7 @@ static image_int ll_angle( image_char in, double threshold,
|
|||||||
norm = (*modgrad)->data[y*p+x];
|
norm = (*modgrad)->data[y*p+x];
|
||||||
|
|
||||||
/* store the point in the right bin according to its norm */
|
/* store the point in the right bin according to its norm */
|
||||||
i = (unsigned int) (norm * (double) n_bins / max_grad);
|
i = (unsigned int) (norm * (float) n_bins / max_grad);
|
||||||
if( i >= n_bins ) i = n_bins-1;
|
if( i >= n_bins ) i = n_bins-1;
|
||||||
if( range_l_e[i] == NULL )
|
if( range_l_e[i] == NULL )
|
||||||
range_l_s[i] = range_l_e[i] = list+list_count++;
|
range_l_s[i] = range_l_e[i] = list+list_count++;
|
||||||
@ -1259,10 +1252,10 @@ static image_int ll_angle( image_char in, double threshold,
|
|||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
/** Is point (x,y) aligned to angle theta, up to precision 'prec'?
|
/** Is point (x,y) aligned to angle theta, up to precision 'prec'?
|
||||||
*/
|
*/
|
||||||
static int isaligned( int x, int y, image_int angles, double theta,
|
static int isaligned( int x, int y, image_int angles, float theta,
|
||||||
double prec )
|
float prec )
|
||||||
{
|
{
|
||||||
double a;
|
float a;
|
||||||
|
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
if( angles == NULL || angles->data == NULL )
|
if( angles == NULL || angles->data == NULL )
|
||||||
@ -1297,7 +1290,7 @@ static int isaligned( int x, int y, image_int angles, double theta,
|
|||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
/** Absolute value angle difference.
|
/** Absolute value angle difference.
|
||||||
*/
|
*/
|
||||||
static double angle_diff(double a, double b)
|
static float angle_diff(float a, float b)
|
||||||
{
|
{
|
||||||
a -= b;
|
a -= b;
|
||||||
while( a <= -M_PI ) a += M_2__PI;
|
while( a <= -M_PI ) a += M_2__PI;
|
||||||
@ -1309,7 +1302,7 @@ static double angle_diff(double a, double b)
|
|||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
/** Signed angle difference.
|
/** Signed angle difference.
|
||||||
*/
|
*/
|
||||||
static double angle_diff_signed(double a, double b)
|
static float angle_diff_signed(float a, float b)
|
||||||
{
|
{
|
||||||
a -= b;
|
a -= b;
|
||||||
while( a <= -M_PI ) a += M_2__PI;
|
while( a <= -M_PI ) a += M_2__PI;
|
||||||
@ -1346,19 +1339,19 @@ static double angle_diff_signed(double a, double b)
|
|||||||
q5 = 83.8676043424,
|
q5 = 83.8676043424,
|
||||||
q6 = 2.50662827511.
|
q6 = 2.50662827511.
|
||||||
*/
|
*/
|
||||||
static double log_gamma_lanczos(double x)
|
static float log_gamma_lanczos(float x)
|
||||||
{
|
{
|
||||||
static double q[7] = { 75122.6331530, 80916.6278952, 36308.2951477,
|
static float q[7] = { 75122.6331530, 80916.6278952, 36308.2951477,
|
||||||
8687.24529705, 1168.92649479, 83.8676043424,
|
8687.24529705, 1168.92649479, 83.8676043424,
|
||||||
2.50662827511 };
|
2.50662827511 };
|
||||||
double a = (x+0.5) * log(x+5.5) - (x+5.5);
|
float a = (x+0.5) * log(x+5.5) - (x+5.5);
|
||||||
double b = 0.0;
|
float b = 0.0;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
for(n=0;n<7;n++)
|
for(n=0;n<7;n++)
|
||||||
{
|
{
|
||||||
a -= log( x + (double) n );
|
a -= log( x + (float) n );
|
||||||
b += q[n] * pow( x, (double) n );
|
b += q[n] * pow( x, (float) n );
|
||||||
}
|
}
|
||||||
return a + log(b);
|
return a + log(b);
|
||||||
}
|
}
|
||||||
@ -1380,7 +1373,7 @@ static double log_gamma_lanczos(double x)
|
|||||||
@f]
|
@f]
|
||||||
This formula is a good approximation when x > 15.
|
This formula is a good approximation when x > 15.
|
||||||
*/
|
*/
|
||||||
static double log_gamma_windschitl(double x)
|
static float log_gamma_windschitl(float x)
|
||||||
{
|
{
|
||||||
return 0.918938533204673 + (x-0.5)*log(x) - x
|
return 0.918938533204673 + (x-0.5)*log(x) - x
|
||||||
+ 0.5*x*log( x*sinh(1/x) + 1/(810.0*pow(x,6.0)) );
|
+ 0.5*x*log( x*sinh(1/x) + 1/(810.0*pow(x,6.0)) );
|
||||||
@ -1440,11 +1433,11 @@ static double log_gamma_windschitl(double x)
|
|||||||
of the terms are neglected based on a bound to the error obtained
|
of the terms are neglected based on a bound to the error obtained
|
||||||
(an error of 10% in the result is accepted).
|
(an error of 10% in the result is accepted).
|
||||||
*/
|
*/
|
||||||
static double nfa(int n, int k, double p, double logNT)
|
static float nfa(int n, int k, float p, float logNT)
|
||||||
{
|
{
|
||||||
// static double inv[TABSIZE]; /* table to keep computed inverse values */
|
// static float inv[TABSIZE]; /* table to keep computed inverse values */
|
||||||
double tolerance = 0.1; /* an error of 10% in the result is accepted */
|
float tolerance = 0.1; /* an error of 10% in the result is accepted */
|
||||||
double log1term,term,bin_term,mult_term,bin_tail,err,p_term;
|
float log1term,term,bin_term,mult_term,bin_tail,err,p_term;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
@ -1453,7 +1446,7 @@ static double nfa(int n, int k, double p, double logNT)
|
|||||||
|
|
||||||
/* trivial cases */
|
/* trivial cases */
|
||||||
if( n==0 || k==0 ) return -logNT;
|
if( n==0 || k==0 ) return -logNT;
|
||||||
if( n==k ) return -logNT - (double) n * log10(p);
|
if( n==k ) return -logNT - (float) n * log10(p);
|
||||||
|
|
||||||
/* probability term */
|
/* probability term */
|
||||||
p_term = p / (1.0-p);
|
p_term = p / (1.0-p);
|
||||||
@ -1466,15 +1459,15 @@ static double nfa(int n, int k, double p, double logNT)
|
|||||||
bincoef(n,k) = gamma(n+1) / ( gamma(k+1) * gamma(n-k+1) ).
|
bincoef(n,k) = gamma(n+1) / ( gamma(k+1) * gamma(n-k+1) ).
|
||||||
We use this to compute the first term. Actually the log of it.
|
We use this to compute the first term. Actually the log of it.
|
||||||
*/
|
*/
|
||||||
log1term = log_gamma( (double) n + 1.0 ) - log_gamma( (double) k + 1.0 )
|
log1term = log_gamma( (float) n + 1.0 ) - log_gamma( (float) k + 1.0 )
|
||||||
- log_gamma( (double) (n-k) + 1.0 )
|
- log_gamma( (float) (n-k) + 1.0 )
|
||||||
+ (double) k * log(p) + (double) (n-k) * log(1.0-p);
|
+ (float) k * log(p) + (float) (n-k) * log(1.0-p);
|
||||||
term = exp(log1term);
|
term = exp(log1term);
|
||||||
|
|
||||||
/* in some cases no more computations are needed */
|
/* in some cases no more computations are needed */
|
||||||
if( double_equal(term,0.0) ) /* the first term is almost zero */
|
if( double_equal(term,0.0) ) /* the first term is almost zero */
|
||||||
{
|
{
|
||||||
if( (double) k > (double) n * p ) /* at begin or end of the tail? */
|
if( (float) k > (float) n * p ) /* at begin or end of the tail? */
|
||||||
return -log1term / M_LN10 - logNT; /* end: use just the first term */
|
return -log1term / M_LN10 - logNT; /* end: use just the first term */
|
||||||
else
|
else
|
||||||
return -logNT; /* begin: the tail is roughly 1 */
|
return -logNT; /* begin: the tail is roughly 1 */
|
||||||
@ -1497,10 +1490,10 @@ static double nfa(int n, int k, double p, double logNT)
|
|||||||
because divisions are expensive.
|
because divisions are expensive.
|
||||||
p/(1-p) is computed only once and stored in 'p_term'.
|
p/(1-p) is computed only once and stored in 'p_term'.
|
||||||
*/
|
*/
|
||||||
// bin_term = (double) (n-i+1) * ( i<TABSIZE ?
|
// bin_term = (float) (n-i+1) * ( i<TABSIZE ?
|
||||||
// ( inv[i]!=0.0 ? inv[i] : ( inv[i] = 1.0 / (double) i ) ) :
|
// ( inv[i]!=0.0 ? inv[i] : ( inv[i] = 1.0 / (float) i ) ) :
|
||||||
// 1.0 / (double) i );
|
// 1.0 / (float) i );
|
||||||
bin_term = (double) (n-i+1) * ( 1.0 / (double) i );
|
bin_term = (float) (n-i+1) * ( 1.0 / (float) i );
|
||||||
|
|
||||||
mult_term = bin_term * p_term;
|
mult_term = bin_term * p_term;
|
||||||
term *= mult_term;
|
term *= mult_term;
|
||||||
@ -1511,7 +1504,7 @@ static double nfa(int n, int k, double p, double logNT)
|
|||||||
Then, the error on the binomial tail when truncated at
|
Then, the error on the binomial tail when truncated at
|
||||||
the i term can be bounded by a geometric series of form
|
the i term can be bounded by a geometric series of form
|
||||||
term_i * sum mult_term_i^j. */
|
term_i * sum mult_term_i^j. */
|
||||||
err = term * ( ( 1.0 - pow( mult_term, (double) (n-i+1) ) ) /
|
err = term * ( ( 1.0 - pow( mult_term, (float) (n-i+1) ) ) /
|
||||||
(1.0-mult_term) - 1.0 );
|
(1.0-mult_term) - 1.0 );
|
||||||
|
|
||||||
/* One wants an error at most of tolerance*final_result, or:
|
/* One wants an error at most of tolerance*final_result, or:
|
||||||
@ -1538,13 +1531,13 @@ static double nfa(int n, int k, double p, double logNT)
|
|||||||
*/
|
*/
|
||||||
struct rect
|
struct rect
|
||||||
{
|
{
|
||||||
double x1,y1,x2,y2; /* first and second point of the line segment */
|
float x1,y1,x2,y2; /* first and second point of the line segment */
|
||||||
double width; /* rectangle width */
|
float width; /* rectangle width */
|
||||||
double x,y; /* center of the rectangle */
|
float x,y; /* center of the rectangle */
|
||||||
double theta; /* angle */
|
float theta; /* angle */
|
||||||
double dx,dy; /* (dx,dy) is vector oriented as the line segment */
|
float dx,dy; /* (dx,dy) is vector oriented as the line segment */
|
||||||
double prec; /* tolerance angle */
|
float prec; /* tolerance angle */
|
||||||
double p; /* probability of a point with angle within 'prec' */
|
float p; /* probability of a point with angle within 'prec' */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
@ -1628,9 +1621,9 @@ static void rect_copy(struct rect * in, struct rect * out)
|
|||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
double vx[4]; /* rectangle's corner X coordinates in circular order */
|
float vx[4]; /* rectangle's corner X coordinates in circular order */
|
||||||
double vy[4]; /* rectangle's corner Y coordinates in circular order */
|
float vy[4]; /* rectangle's corner Y coordinates in circular order */
|
||||||
double ys,ye; /* start and end Y values of current 'column' */
|
float ys,ye; /* start and end Y values of current 'column' */
|
||||||
int x,y; /* coordinates of currently explored pixel */
|
int x,y; /* coordinates of currently explored pixel */
|
||||||
} rect_iter;
|
} rect_iter;
|
||||||
|
|
||||||
@ -1644,7 +1637,7 @@ typedef struct
|
|||||||
- x1 <= x
|
- x1 <= x
|
||||||
- x <= x2
|
- x <= x2
|
||||||
*/
|
*/
|
||||||
static double inter_low(double x, double x1, double y1, double x2, double y2)
|
static float inter_low(float x, float x1, float y1, float x2, float y2)
|
||||||
{
|
{
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
// if( x1 > x2 || x < x1 || x > x2 )
|
// if( x1 > x2 || x < x1 || x > x2 )
|
||||||
@ -1654,7 +1647,7 @@ static double inter_low(double x, double x1, double y1, double x2, double y2)
|
|||||||
if( double_equal(x1,x2) && y1<y2 ) return y1;
|
if( double_equal(x1,x2) && y1<y2 ) return y1;
|
||||||
if( double_equal(x1,x2) && y1>y2 ) return y2;
|
if( double_equal(x1,x2) && y1>y2 ) return y2;
|
||||||
// return y1 + (x-x1) * (y2-y1) / (x2-x1);
|
// return y1 + (x-x1) * (y2-y1) / (x2-x1);
|
||||||
double result = y1 + (x-x1) * (y2-y1) / (x2-x1);
|
float result = y1 + (x-x1) * (y2-y1) / (x2-x1);
|
||||||
if (isnan(result) || isinf(result)) return (y1<y2) ? y1 : ((y1>y2) ? y2 : 0);
|
if (isnan(result) || isinf(result)) return (y1<y2) ? y1 : ((y1>y2) ? y2 : 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1669,7 +1662,7 @@ static double inter_low(double x, double x1, double y1, double x2, double y2)
|
|||||||
- x1 <= x
|
- x1 <= x
|
||||||
- x <= x2
|
- x <= x2
|
||||||
*/
|
*/
|
||||||
static double inter_hi(double x, double x1, double y1, double x2, double y2)
|
static float inter_hi(float x, float x1, float y1, float x2, float y2)
|
||||||
{
|
{
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
// if( x1 > x2 || x < x1 || x > x2 )
|
// if( x1 > x2 || x < x1 || x > x2 )
|
||||||
@ -1679,7 +1672,7 @@ static double inter_hi(double x, double x1, double y1, double x2, double y2)
|
|||||||
if( double_equal(x1,x2) && y1<y2 ) return y2;
|
if( double_equal(x1,x2) && y1<y2 ) return y2;
|
||||||
if( double_equal(x1,x2) && y1>y2 ) return y1;
|
if( double_equal(x1,x2) && y1>y2 ) return y1;
|
||||||
// return y1 + (x-x1) * (y2-y1) / (x2-x1);
|
// return y1 + (x-x1) * (y2-y1) / (x2-x1);
|
||||||
double result = y1 + (x-x1) * (y2-y1) / (x2-x1);
|
float result = y1 + (x-x1) * (y2-y1) / (x2-x1);
|
||||||
if (isnan(result) || isinf(result)) return (y1<y2) ? y2 : ((y1>y2) ? y1 : 0);
|
if (isnan(result) || isinf(result)) return (y1<y2) ? y2 : ((y1>y2) ? y1 : 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1706,7 +1699,7 @@ static int ri_end(rect_iter * i)
|
|||||||
/* if the current x value is larger than the largest
|
/* if the current x value is larger than the largest
|
||||||
x value in the rectangle (vx[2]), we know the full
|
x value in the rectangle (vx[2]), we know the full
|
||||||
exploration of the rectangle is finished. */
|
exploration of the rectangle is finished. */
|
||||||
return (double)(i->x) > i->vx[2];
|
return (float)(i->x) > i->vx[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
@ -1726,7 +1719,7 @@ static void ri_inc(rect_iter * i)
|
|||||||
/* if the end of the current 'column' is reached,
|
/* if the end of the current 'column' is reached,
|
||||||
and it is not the end of exploration,
|
and it is not the end of exploration,
|
||||||
advance to the next 'column' */
|
advance to the next 'column' */
|
||||||
while( (double) (i->y) > i->ye && !ri_end(i) )
|
while( (float) (i->y) > i->ye && !ri_end(i) )
|
||||||
{
|
{
|
||||||
/* increase x, next 'column' */
|
/* increase x, next 'column' */
|
||||||
i->x++;
|
i->x++;
|
||||||
@ -1749,10 +1742,10 @@ static void ri_inc(rect_iter * i)
|
|||||||
or last 'columns') then we pick the lower value of the side
|
or last 'columns') then we pick the lower value of the side
|
||||||
by using 'inter_low'.
|
by using 'inter_low'.
|
||||||
*/
|
*/
|
||||||
if( (double) i->x < i->vx[3] )
|
if( (float) i->x < i->vx[3] )
|
||||||
i->ys = inter_low((double)i->x,i->vx[0],i->vy[0],i->vx[3],i->vy[3]);
|
i->ys = inter_low((float)i->x,i->vx[0],i->vy[0],i->vx[3],i->vy[3]);
|
||||||
else
|
else
|
||||||
i->ys = inter_low((double)i->x,i->vx[3],i->vy[3],i->vx[2],i->vy[2]);
|
i->ys = inter_low((float)i->x,i->vx[3],i->vy[3],i->vx[2],i->vy[2]);
|
||||||
|
|
||||||
/* update upper y limit (end) for the new 'column'.
|
/* update upper y limit (end) for the new 'column'.
|
||||||
|
|
||||||
@ -1769,10 +1762,10 @@ static void ri_inc(rect_iter * i)
|
|||||||
or last 'columns') then we pick the lower value of the side
|
or last 'columns') then we pick the lower value of the side
|
||||||
by using 'inter_low'.
|
by using 'inter_low'.
|
||||||
*/
|
*/
|
||||||
if( (double)i->x < i->vx[1] )
|
if( (float)i->x < i->vx[1] )
|
||||||
i->ye = inter_hi((double)i->x,i->vx[0],i->vy[0],i->vx[1],i->vy[1]);
|
i->ye = inter_hi((float)i->x,i->vx[0],i->vy[0],i->vx[1],i->vy[1]);
|
||||||
else
|
else
|
||||||
i->ye = inter_hi((double)i->x,i->vx[1],i->vy[1],i->vx[2],i->vy[2]);
|
i->ye = inter_hi((float)i->x,i->vx[1],i->vy[1],i->vx[2],i->vy[2]);
|
||||||
|
|
||||||
/* new y */
|
/* new y */
|
||||||
i->y = (int) ceil(i->ys);
|
i->y = (int) ceil(i->ys);
|
||||||
@ -1786,7 +1779,7 @@ static void ri_inc(rect_iter * i)
|
|||||||
*/
|
*/
|
||||||
static rect_iter * ri_ini(struct rect * r)
|
static rect_iter * ri_ini(struct rect * r)
|
||||||
{
|
{
|
||||||
double vx[4],vy[4];
|
float vx[4],vy[4];
|
||||||
int n,offset;
|
int n,offset;
|
||||||
rect_iter * i;
|
rect_iter * i;
|
||||||
|
|
||||||
@ -1844,7 +1837,7 @@ static rect_iter * ri_ini(struct rect * r)
|
|||||||
*/
|
*/
|
||||||
i->x = (int) ceil(i->vx[0]) - 1;
|
i->x = (int) ceil(i->vx[0]) - 1;
|
||||||
i->y = (int) ceil(i->vy[0]);
|
i->y = (int) ceil(i->vy[0]);
|
||||||
i->ys = i->ye = -DBL_MAX;
|
i->ys = i->ye = -FLT_MAX;
|
||||||
|
|
||||||
/* advance to the first pixel */
|
/* advance to the first pixel */
|
||||||
ri_inc(i);
|
ri_inc(i);
|
||||||
@ -1855,7 +1848,7 @@ static rect_iter * ri_ini(struct rect * r)
|
|||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
/** Compute a rectangle's NFA value.
|
/** Compute a rectangle's NFA value.
|
||||||
*/
|
*/
|
||||||
static double rect_nfa(struct rect * rec, image_int angles, double logNT)
|
static float rect_nfa(struct rect * rec, image_int angles, float logNT)
|
||||||
{
|
{
|
||||||
rect_iter * i;
|
rect_iter * i;
|
||||||
int pts = 0;
|
int pts = 0;
|
||||||
@ -1941,13 +1934,13 @@ static double rect_nfa(struct rect * rec, image_int angles, double logNT)
|
|||||||
When |Ixx| > |Iyy| we use the first, otherwise the second (just to
|
When |Ixx| > |Iyy| we use the first, otherwise the second (just to
|
||||||
get better numeric precision).
|
get better numeric precision).
|
||||||
*/
|
*/
|
||||||
static double get_theta( struct lsd_point * reg, int reg_size, double x, double y,
|
static float get_theta( struct lsd_point * reg, int reg_size, float x, float y,
|
||||||
image_int modgrad, double reg_angle, double prec )
|
image_int modgrad, float reg_angle, float prec )
|
||||||
{
|
{
|
||||||
double lambda,theta,weight;
|
float lambda,theta,weight;
|
||||||
double Ixx = 0.0;
|
float Ixx = 0.0;
|
||||||
double Iyy = 0.0;
|
float Iyy = 0.0;
|
||||||
double Ixy = 0.0;
|
float Ixy = 0.0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
@ -1961,9 +1954,9 @@ static double get_theta( struct lsd_point * reg, int reg_size, double x, double
|
|||||||
for(i=0; i<reg_size; i++)
|
for(i=0; i<reg_size; i++)
|
||||||
{
|
{
|
||||||
weight = modgrad->data[ reg[i].x + reg[i].y * modgrad->xsize ];
|
weight = modgrad->data[ reg[i].x + reg[i].y * modgrad->xsize ];
|
||||||
Ixx += ( (double) reg[i].y - y ) * ( (double) reg[i].y - y ) * weight;
|
Ixx += ( (float) reg[i].y - y ) * ( (float) reg[i].y - y ) * weight;
|
||||||
Iyy += ( (double) reg[i].x - x ) * ( (double) reg[i].x - x ) * weight;
|
Iyy += ( (float) reg[i].x - x ) * ( (float) reg[i].x - x ) * weight;
|
||||||
Ixy -= ( (double) reg[i].x - x ) * ( (double) reg[i].y - y ) * weight;
|
Ixy -= ( (float) reg[i].x - x ) * ( (float) reg[i].y - y ) * weight;
|
||||||
}
|
}
|
||||||
if( double_equal(Ixx,0.0) && double_equal(Iyy,0.0) && double_equal(Ixy,0.0) )
|
if( double_equal(Ixx,0.0) && double_equal(Iyy,0.0) && double_equal(Ixy,0.0) )
|
||||||
error("get_theta: null inertia matrix.");
|
error("get_theta: null inertia matrix.");
|
||||||
@ -1985,10 +1978,10 @@ static double get_theta( struct lsd_point * reg, int reg_size, double x, double
|
|||||||
/** Computes a rectangle that covers a region of points.
|
/** Computes a rectangle that covers a region of points.
|
||||||
*/
|
*/
|
||||||
static void region2rect( struct lsd_point * reg, int reg_size,
|
static void region2rect( struct lsd_point * reg, int reg_size,
|
||||||
image_int modgrad, double reg_angle,
|
image_int modgrad, float reg_angle,
|
||||||
double prec, double p, struct rect * rec )
|
float prec, float p, struct rect * rec )
|
||||||
{
|
{
|
||||||
double x,y,dx,dy,l,w,theta,weight,sum,l_min,l_max,w_min,w_max;
|
float x,y,dx,dy,l,w,theta,weight,sum,l_min,l_max,w_min,w_max;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
@ -2012,8 +2005,8 @@ static void region2rect( struct lsd_point * reg, int reg_size,
|
|||||||
for(i=0; i<reg_size; i++)
|
for(i=0; i<reg_size; i++)
|
||||||
{
|
{
|
||||||
weight = modgrad->data[ reg[i].x + reg[i].y * modgrad->xsize ];
|
weight = modgrad->data[ reg[i].x + reg[i].y * modgrad->xsize ];
|
||||||
x += (double) reg[i].x * weight;
|
x += (float) reg[i].x * weight;
|
||||||
y += (double) reg[i].y * weight;
|
y += (float) reg[i].y * weight;
|
||||||
sum += weight;
|
sum += weight;
|
||||||
}
|
}
|
||||||
if( sum <= 0.0 ) error("region2rect: weights sum equal to zero.");
|
if( sum <= 0.0 ) error("region2rect: weights sum equal to zero.");
|
||||||
@ -2040,8 +2033,8 @@ static void region2rect( struct lsd_point * reg, int reg_size,
|
|||||||
l_min = l_max = w_min = w_max = 0.0;
|
l_min = l_max = w_min = w_max = 0.0;
|
||||||
for(i=0; i<reg_size; i++)
|
for(i=0; i<reg_size; i++)
|
||||||
{
|
{
|
||||||
l = ( (double) reg[i].x - x) * dx + ( (double) reg[i].y - y) * dy;
|
l = ( (float) reg[i].x - x) * dx + ( (float) reg[i].y - y) * dy;
|
||||||
w = -( (double) reg[i].x - x) * dy + ( (double) reg[i].y - y) * dx;
|
w = -( (float) reg[i].x - x) * dy + ( (float) reg[i].y - y) * dx;
|
||||||
|
|
||||||
if( l > l_max ) l_max = l;
|
if( l > l_max ) l_max = l;
|
||||||
if( l < l_min ) l_min = l;
|
if( l < l_min ) l_min = l;
|
||||||
@ -2078,10 +2071,10 @@ static void region2rect( struct lsd_point * reg, int reg_size,
|
|||||||
tolerance 'prec', starting at point (x,y).
|
tolerance 'prec', starting at point (x,y).
|
||||||
*/
|
*/
|
||||||
static void region_grow( int x, int y, image_int angles, struct lsd_point * reg,
|
static void region_grow( int x, int y, image_int angles, struct lsd_point * reg,
|
||||||
int * reg_size, double * reg_angle, image_char used,
|
int * reg_size, float * reg_angle, image_char used,
|
||||||
double prec )
|
float prec )
|
||||||
{
|
{
|
||||||
double sumdx,sumdy;
|
float sumdx,sumdy;
|
||||||
int xx,yy,i;
|
int xx,yy,i;
|
||||||
|
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
@ -2131,13 +2124,13 @@ static void region_grow( int x, int y, image_int angles, struct lsd_point * reg,
|
|||||||
/** Try some rectangles variations to improve NFA value. Only if the
|
/** Try some rectangles variations to improve NFA value. Only if the
|
||||||
rectangle is not meaningful (i.e., log_nfa <= log_eps).
|
rectangle is not meaningful (i.e., log_nfa <= log_eps).
|
||||||
*/
|
*/
|
||||||
static double rect_improve( struct rect * rec, image_int angles,
|
static float rect_improve( struct rect * rec, image_int angles,
|
||||||
double logNT, double log_eps )
|
float logNT, float log_eps )
|
||||||
{
|
{
|
||||||
struct rect r;
|
struct rect r;
|
||||||
double log_nfa,log_nfa_new;
|
float log_nfa,log_nfa_new;
|
||||||
double delta = 0.5;
|
float delta = 0.5;
|
||||||
double delta_2 = delta / 2.0;
|
float delta_2 = delta / 2.0;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
log_nfa = rect_nfa(rec,angles,logNT);
|
log_nfa = rect_nfa(rec,angles,logNT);
|
||||||
@ -2245,12 +2238,12 @@ static double rect_improve( struct rect * rec, image_int angles,
|
|||||||
density of region points or to discard the region if too small.
|
density of region points or to discard the region if too small.
|
||||||
*/
|
*/
|
||||||
static int reduce_region_radius( struct lsd_point * reg, int * reg_size,
|
static int reduce_region_radius( struct lsd_point * reg, int * reg_size,
|
||||||
image_int modgrad, double reg_angle,
|
image_int modgrad, float reg_angle,
|
||||||
double prec, double p, struct rect * rec,
|
float prec, float p, struct rect * rec,
|
||||||
image_char used, image_int angles,
|
image_char used, image_int angles,
|
||||||
double density_th )
|
float density_th )
|
||||||
{
|
{
|
||||||
double density,rad1,rad2,rad,xc,yc;
|
float density,rad1,rad2,rad,xc,yc;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
@ -2265,15 +2258,15 @@ static int reduce_region_radius( struct lsd_point * reg, int * reg_size,
|
|||||||
error("reduce_region_radius: invalid image 'angles'.");
|
error("reduce_region_radius: invalid image 'angles'.");
|
||||||
|
|
||||||
/* compute region points density */
|
/* compute region points density */
|
||||||
density = (double) *reg_size /
|
density = (float) *reg_size /
|
||||||
( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
|
( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
|
||||||
|
|
||||||
/* if the density criterion is satisfied there is nothing to do */
|
/* if the density criterion is satisfied there is nothing to do */
|
||||||
if( density >= density_th ) return TRUE;
|
if( density >= density_th ) return TRUE;
|
||||||
|
|
||||||
/* compute region's radius */
|
/* compute region's radius */
|
||||||
xc = (double) reg[0].x;
|
xc = (float) reg[0].x;
|
||||||
yc = (double) reg[0].y;
|
yc = (float) reg[0].y;
|
||||||
rad1 = dist( xc, yc, rec->x1, rec->y1 );
|
rad1 = dist( xc, yc, rec->x1, rec->y1 );
|
||||||
rad2 = dist( xc, yc, rec->x2, rec->y2 );
|
rad2 = dist( xc, yc, rec->x2, rec->y2 );
|
||||||
rad = rad1 > rad2 ? rad1 : rad2;
|
rad = rad1 > rad2 ? rad1 : rad2;
|
||||||
@ -2285,7 +2278,7 @@ static int reduce_region_radius( struct lsd_point * reg, int * reg_size,
|
|||||||
|
|
||||||
/* remove points from the region and update 'used' map */
|
/* remove points from the region and update 'used' map */
|
||||||
for(i=0; i<*reg_size; i++)
|
for(i=0; i<*reg_size; i++)
|
||||||
if( dist( xc, yc, (double) reg[i].x, (double) reg[i].y ) > rad )
|
if( dist( xc, yc, (float) reg[i].x, (float) reg[i].y ) > rad )
|
||||||
{
|
{
|
||||||
/* point not kept, mark it as NOTUSED */
|
/* point not kept, mark it as NOTUSED */
|
||||||
used->data[ reg[i].x + reg[i].y * used->xsize ] = NOTUSED;
|
used->data[ reg[i].x + reg[i].y * used->xsize ] = NOTUSED;
|
||||||
@ -2304,7 +2297,7 @@ static int reduce_region_radius( struct lsd_point * reg, int * reg_size,
|
|||||||
region2rect(reg,*reg_size,modgrad,reg_angle,prec,p,rec);
|
region2rect(reg,*reg_size,modgrad,reg_angle,prec,p,rec);
|
||||||
|
|
||||||
/* re-compute region points density */
|
/* re-compute region points density */
|
||||||
density = (double) *reg_size /
|
density = (float) *reg_size /
|
||||||
( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
|
( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2323,10 +2316,10 @@ static int reduce_region_radius( struct lsd_point * reg, int * reg_size,
|
|||||||
'reduce_region_radius' is called to try to satisfy this condition.
|
'reduce_region_radius' is called to try to satisfy this condition.
|
||||||
*/
|
*/
|
||||||
static int refine( struct lsd_point * reg, int * reg_size, image_int modgrad,
|
static int refine( struct lsd_point * reg, int * reg_size, image_int modgrad,
|
||||||
double reg_angle, double prec, double p, struct rect * rec,
|
float reg_angle, float prec, float p, struct rect * rec,
|
||||||
image_char used, image_int angles, double density_th )
|
image_char used, image_int angles, float density_th )
|
||||||
{
|
{
|
||||||
double angle,ang_d,mean_angle,tau,density,xc,yc,ang_c,sum,s_sum;
|
float angle,ang_d,mean_angle,tau,density,xc,yc,ang_c,sum,s_sum;
|
||||||
int i,n;
|
int i,n;
|
||||||
|
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
@ -2340,7 +2333,7 @@ static int refine( struct lsd_point * reg, int * reg_size, image_int modgrad,
|
|||||||
error("refine: invalid image 'angles'.");
|
error("refine: invalid image 'angles'.");
|
||||||
|
|
||||||
/* compute region points density */
|
/* compute region points density */
|
||||||
density = (double) *reg_size /
|
density = (float) *reg_size /
|
||||||
( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
|
( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
|
||||||
|
|
||||||
/* if the density criterion is satisfied there is nothing to do */
|
/* if the density criterion is satisfied there is nothing to do */
|
||||||
@ -2349,15 +2342,15 @@ static int refine( struct lsd_point * reg, int * reg_size, image_int modgrad,
|
|||||||
/*------ First try: reduce angle tolerance ------*/
|
/*------ First try: reduce angle tolerance ------*/
|
||||||
|
|
||||||
/* compute the new mean angle and tolerance */
|
/* compute the new mean angle and tolerance */
|
||||||
xc = (double) reg[0].x;
|
xc = (float) reg[0].x;
|
||||||
yc = (double) reg[0].y;
|
yc = (float) reg[0].y;
|
||||||
ang_c = degToRad(angles->data[ reg[0].x + reg[0].y * angles->xsize ]);
|
ang_c = degToRad(angles->data[ reg[0].x + reg[0].y * angles->xsize ]);
|
||||||
sum = s_sum = 0.0;
|
sum = s_sum = 0.0;
|
||||||
n = 0;
|
n = 0;
|
||||||
for(i=0; i<*reg_size; i++)
|
for(i=0; i<*reg_size; i++)
|
||||||
{
|
{
|
||||||
used->data[ reg[i].x + reg[i].y * used->xsize ] = NOTUSED;
|
used->data[ reg[i].x + reg[i].y * used->xsize ] = NOTUSED;
|
||||||
if( dist( xc, yc, (double) reg[i].x, (double) reg[i].y ) < rec->width )
|
if( dist( xc, yc, (float) reg[i].x, (float) reg[i].y ) < rec->width )
|
||||||
{
|
{
|
||||||
angle = degToRad(angles->data[ reg[i].x + reg[i].y * angles->xsize ]);
|
angle = degToRad(angles->data[ reg[i].x + reg[i].y * angles->xsize ]);
|
||||||
ang_d = angle_diff_signed(angle,ang_c);
|
ang_d = angle_diff_signed(angle,ang_c);
|
||||||
@ -2366,8 +2359,8 @@ static int refine( struct lsd_point * reg, int * reg_size, image_int modgrad,
|
|||||||
++n;
|
++n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mean_angle = sum / (double) n;
|
mean_angle = sum / (float) n;
|
||||||
tau = 2.0 * sqrt( (s_sum - 2.0 * mean_angle * sum) / (double) n
|
tau = 2.0 * sqrt( (s_sum - 2.0 * mean_angle * sum) / (float) n
|
||||||
+ mean_angle*mean_angle ); /* 2 * standard deviation */
|
+ mean_angle*mean_angle ); /* 2 * standard deviation */
|
||||||
|
|
||||||
/* find a new region from the same starting point and new angle tolerance */
|
/* find a new region from the same starting point and new angle tolerance */
|
||||||
@ -2380,7 +2373,7 @@ static int refine( struct lsd_point * reg, int * reg_size, image_int modgrad,
|
|||||||
region2rect(reg,*reg_size,modgrad,reg_angle,prec,p,rec);
|
region2rect(reg,*reg_size,modgrad,reg_angle,prec,p,rec);
|
||||||
|
|
||||||
/* re-compute region points density */
|
/* re-compute region points density */
|
||||||
density = (double) *reg_size /
|
density = (float) *reg_size /
|
||||||
( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
|
( dist(rec->x1,rec->y1,rec->x2,rec->y2) * rec->width );
|
||||||
|
|
||||||
/*------ Second try: reduce region radius ------*/
|
/*------ Second try: reduce region radius ------*/
|
||||||
@ -2400,16 +2393,16 @@ static int refine( struct lsd_point * reg, int * reg_size, image_int modgrad,
|
|||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
/** LSD full interface.
|
/** LSD full interface.
|
||||||
*/
|
*/
|
||||||
double * LineSegmentDetection( int * n_out,
|
float * LineSegmentDetection( int * n_out,
|
||||||
unsigned char * img, int X, int Y,
|
unsigned char * img, int X, int Y,
|
||||||
double scale, double sigma_scale, double quant,
|
float scale, float sigma_scale, float quant,
|
||||||
double ang_th, double log_eps, double density_th,
|
float ang_th, float log_eps, float density_th,
|
||||||
int n_bins,
|
int n_bins,
|
||||||
int ** reg_img, int * reg_x, int * reg_y )
|
int ** reg_img, int * reg_x, int * reg_y )
|
||||||
{
|
{
|
||||||
image_char image;
|
image_char image;
|
||||||
ntuple_list out = new_ntuple_list(7);
|
ntuple_list out = new_ntuple_list(7);
|
||||||
double * return_value;
|
float * return_value;
|
||||||
image_int scaled_image,angles,modgrad;
|
image_int scaled_image,angles,modgrad;
|
||||||
image_char used;
|
image_char used;
|
||||||
image_int region = NULL;
|
image_int region = NULL;
|
||||||
@ -2419,7 +2412,7 @@ double * LineSegmentDetection( int * n_out,
|
|||||||
struct lsd_point * reg;
|
struct lsd_point * reg;
|
||||||
int reg_size,min_reg_size,i;
|
int reg_size,min_reg_size,i;
|
||||||
unsigned int xsize,ysize;
|
unsigned int xsize,ysize;
|
||||||
double rho,reg_angle,prec,p,log_nfa,logNT;
|
float rho,reg_angle,prec,p,log_nfa,logNT;
|
||||||
int ls_count = 0; /* line segments are numbered 1,2,3,... */
|
int ls_count = 0; /* line segments are numbered 1,2,3,... */
|
||||||
|
|
||||||
|
|
||||||
@ -2469,7 +2462,7 @@ double * LineSegmentDetection( int * n_out,
|
|||||||
whose logarithm value is
|
whose logarithm value is
|
||||||
log10(11) + 5/2 * (log10(X) + log10(Y)).
|
log10(11) + 5/2 * (log10(X) + log10(Y)).
|
||||||
*/
|
*/
|
||||||
logNT = 5.0 * ( log10( (double) xsize ) + log10( (double) ysize ) ) / 2.0
|
logNT = 5.0 * ( log10( (float) xsize ) + log10( (float) ysize ) ) / 2.0
|
||||||
+ log10(11.0);
|
+ log10(11.0);
|
||||||
min_reg_size = (int) (-logNT/log10(p)); /* minimal number of points in region
|
min_reg_size = (int) (-logNT/log10(p)); /* minimal number of points in region
|
||||||
that can give a meaningful event */
|
that can give a meaningful event */
|
||||||
@ -2487,7 +2480,7 @@ double * LineSegmentDetection( int * n_out,
|
|||||||
for(; list_p != NULL; list_p = list_p->next )
|
for(; list_p != NULL; list_p = list_p->next )
|
||||||
if( used->data[ list_p->x + list_p->y * used->xsize ] == NOTUSED &&
|
if( used->data[ list_p->x + list_p->y * used->xsize ] == NOTUSED &&
|
||||||
degToRad(angles->data[ list_p->x + list_p->y * angles->xsize ]) != NOTDEF )
|
degToRad(angles->data[ list_p->x + list_p->y * angles->xsize ]) != NOTDEF )
|
||||||
/* there is no risk of double comparison problems here
|
/* there is no risk of float comparison problems here
|
||||||
because we are only interested in the exact NOTDEF value */
|
because we are only interested in the exact NOTDEF value */
|
||||||
{
|
{
|
||||||
/* find the region of connected point and ~equal angle */
|
/* find the region of connected point and ~equal angle */
|
||||||
@ -2587,18 +2580,18 @@ double * LineSegmentDetection( int * n_out,
|
|||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
/** LSD Simple Interface with Scale and Region output.
|
/** LSD Simple Interface with Scale and Region output.
|
||||||
*/
|
*/
|
||||||
double * lsd_scale_region( int * n_out,
|
float * lsd_scale_region( int * n_out,
|
||||||
unsigned char * img, int X, int Y, double scale,
|
unsigned char * img, int X, int Y, float scale,
|
||||||
int ** reg_img, int * reg_x, int * reg_y )
|
int ** reg_img, int * reg_x, int * reg_y )
|
||||||
{
|
{
|
||||||
/* LSD parameters */
|
/* LSD parameters */
|
||||||
double sigma_scale = 0.6; /* Sigma for Gaussian filter is computed as
|
float sigma_scale = 0.6; /* Sigma for Gaussian filter is computed as
|
||||||
sigma = sigma_scale/scale. */
|
sigma = sigma_scale/scale. */
|
||||||
double quant = 2.0; /* Bound to the quantization error on the
|
float quant = 2.0; /* Bound to the quantization error on the
|
||||||
gradient norm. */
|
gradient norm. */
|
||||||
double ang_th = 22.5; /* Gradient angle tolerance in degrees. */
|
float ang_th = 22.5; /* Gradient angle tolerance in degrees. */
|
||||||
double log_eps = 0.0; /* Detection threshold: -log10(NFA) > log_eps */
|
float log_eps = 0.0; /* Detection threshold: -log10(NFA) > log_eps */
|
||||||
double density_th = 0.7; /* Minimal density of region points in rectangle. */
|
float density_th = 0.7; /* Minimal density of region points in rectangle. */
|
||||||
int n_bins = 1024; /* Number of bins in pseudo-ordering of gradient
|
int n_bins = 1024; /* Number of bins in pseudo-ordering of gradient
|
||||||
modulus. */
|
modulus. */
|
||||||
|
|
||||||
@ -2610,7 +2603,7 @@ double * lsd_scale_region( int * n_out,
|
|||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
/** LSD Simple Interface with Scale.
|
/** LSD Simple Interface with Scale.
|
||||||
*/
|
*/
|
||||||
double * lsd_scale(int * n_out, unsigned char * img, int X, int Y, double scale)
|
float * lsd_scale(int * n_out, unsigned char * img, int X, int Y, float scale)
|
||||||
{
|
{
|
||||||
return lsd_scale_region(n_out,img,X,Y,scale,NULL,NULL,NULL);
|
return lsd_scale_region(n_out,img,X,Y,scale,NULL,NULL,NULL);
|
||||||
}
|
}
|
||||||
@ -2618,10 +2611,10 @@ double * lsd_scale(int * n_out, unsigned char * img, int X, int Y, double scale)
|
|||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
/** LSD Simple Interface.
|
/** LSD Simple Interface.
|
||||||
*/
|
*/
|
||||||
double * lsd(int * n_out, unsigned char * img, int X, int Y)
|
float * lsd(int * n_out, unsigned char * img, int X, int Y)
|
||||||
{
|
{
|
||||||
/* LSD parameters */
|
/* LSD parameters */
|
||||||
double scale = 0.8; /* Scale the image by Gaussian filter to 'scale'. */
|
float scale = 0.8; /* Scale the image by Gaussian filter to 'scale'. */
|
||||||
|
|
||||||
return lsd_scale(n_out,img,X,Y,scale);
|
return lsd_scale(n_out,img,X,Y,scale);
|
||||||
}
|
}
|
||||||
@ -2672,7 +2665,7 @@ void imlib_lsd_find_line_segments(list_t *out, image_t *ptr, rectangle_t *roi, u
|
|||||||
}
|
}
|
||||||
|
|
||||||
int n_ls;
|
int n_ls;
|
||||||
double *ls = LineSegmentDetection(&n_ls, grayscale_image_tmp, roi->w, roi->h, 0.8, 0.6, 2.0, 22.5, 0.0, 0.7, 1024, NULL, NULL, NULL);
|
float *ls = LineSegmentDetection(&n_ls, grayscale_image_tmp, roi->w, roi->h, 0.8, 0.6, 2.0, 22.5, 0.0, 0.7, 1024, NULL, NULL, NULL);
|
||||||
list_init(out, sizeof(find_lines_list_lnk_data_t));
|
list_init(out, sizeof(find_lines_list_lnk_data_t));
|
||||||
|
|
||||||
for (int i = 0, j = n_ls; i < j; i++) {
|
for (int i = 0, j = n_ls; i < j; i++) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user