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:
iabdalkader 2019-09-06 15:48:31 +02:00
parent fa2ffaa655
commit 7eaeefacb1
3 changed files with 791 additions and 811 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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) {

View File

@ -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++) {