Changeset 36375 for trunk/psLib
- Timestamp:
- Dec 10, 2013, 2:55:11 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 9 edited
- 2 copied
-
. (modified) (1 prop)
-
psLib/src/imageops/Makefile.am (modified) (1 diff)
-
psLib/src/imageops/psImageConvolve.c (modified) (7 diffs)
-
psLib/src/imageops/psImageConvolve.h (modified) (4 diffs)
-
psLib/src/imageops/psImageConvolve2dCache.c (copied) (copied from branches/eam_branches/ipp-20130904/psLib/src/imageops/psImageConvolve2dCache.c )
-
psLib/src/math/psEllipse.c (modified) (5 diffs)
-
psLib/src/math/psEllipse.h (modified) (2 diffs)
-
psLib/src/math/psMixtureModels.c (modified) (1 prop)
-
psLib/test/imageops (modified) (1 prop)
-
psLib/test/imageops/Makefile.am (modified) (1 diff)
-
psLib/test/imageops/tap_psImageConvolve2dCache.c (copied) (copied from branches/eam_branches/ipp-20130904/psLib/test/imageops/tap_psImageConvolve2dCache.c )
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
trunk/psLib/src/imageops/Makefile.am
r21207 r36375 7 7 psImageBackground.c \ 8 8 psImageConvolve.c \ 9 psImageConvolve2dCache.c \ 9 10 psImageCovariance.c \ 10 11 psImageGeomManip.c \ -
trunk/psLib/src/imageops/psImageConvolve.c
r35767 r36375 36 36 #define MIN_GAUSS_FRAC 0.25 // Minimum Gaussian fraction to accept when smoothing 37 37 38 39 40 38 static bool threaded = false; // Run image convolution threaded? 41 39 static pthread_mutex_t threadMutex = PTHREAD_MUTEX_INITIALIZER; 42 43 40 44 41 static void kernelFree(psKernel *kernel) … … 780 777 } 781 778 782 void psImageSmooth _PreAlloc_DataFree (psImageSmooth_PreAlloc_Data *smdata) {779 void psImageSmoothCacheDataFree (psImageSmoothCacheData *smdata) { 783 780 psFree (smdata->resultX); 784 781 psFree (smdata->resultY); … … 786 783 } 787 784 788 psImageSmooth_PreAlloc_Data *psImageSmooth_PreAlloc_DataAlloc (psImage *image, double sigma, double Nsigma) { 789 790 psImageSmooth_PreAlloc_Data *smdata = psAlloc(sizeof(psImageSmooth_PreAlloc_Data)); 791 psMemSetDeallocator(smdata, (psFreeFunc) psImageSmooth_PreAlloc_DataFree); 785 // allocate the psImageSmoothCache data structure, but do not define the kernel 786 psImageSmoothCacheData *psImageSmoothCacheAlloc (psImage *image, double sigma, double Nsigma) { 787 788 psImageSmoothCacheData *smdata = psAlloc(sizeof(psImageSmoothCacheData)); 789 psMemSetDeallocator(smdata, (psFreeFunc) psImageSmoothCacheDataFree); 790 791 smdata->kernel = NULL; 792 792 793 793 if (!image) { … … 796 796 smdata->Nx = 0; 797 797 smdata->Ny = 0; 798 smdata->kernel = NULL;799 798 smdata->resultX = NULL; 800 799 smdata->resultY = NULL; … … 807 806 smdata->Ny = image->numRows; // Number of rows 808 807 809 IMAGE_SMOOTH_GAUSS(smdata->kernel, smdata->Nrange, sigma, F32); 808 // XXX drop this : we now require a call to a kernel-creation function (like psImageSmoothCacheKernel_Gauss) 809 // IMAGE_SMOOTH_GAUSS(smdata->kernel, smdata->Nrange, sigma, F32); 810 810 811 811 // use a temp running buffer for X and Y directions. … … 819 819 } 820 820 821 // generate a Gaussian smoothing kernel for supplied sigma. sigma here does not need to match 822 // that used to allocate the structure, but it is recommended 823 bool psImageSmoothCacheKernel_Gauss (psImageSmoothCacheData *smdata, float sigma) { 824 // check for NULL structure elements? 825 psFree (smdata->kernel); 826 IMAGE_SMOOTH_GAUSS(smdata->kernel, smdata->Nrange, sigma, F32); 827 return true; 828 } 829 821 830 // we can use the same DATA structure on multiple images of the same size 822 bool psImageSmooth _PreAlloc_F32(psImage *image, psImageSmooth_PreAlloc_Data *smdata)831 bool psImageSmoothCache_F32(psImage *image, psImageSmoothCacheData *smdata) 823 832 { 824 833 PS_ASSERT_IMAGE_NON_NULL(image, false); 834 PS_ASSERT_VECTOR_NON_NULL(smdata->kernel, false); 825 835 // assert on data type 826 836 … … 2156 2166 return threaded; 2157 2167 } 2158 -
trunk/psLib/src/imageops/psImageConvolve.h
r35767 r36375 26 26 #define PS_TYPE_KERNEL_NAME "psF32" ///< the data type for kernel as a string */ 27 27 28 /// a structure to contain data related to image smoothing with a 1D gauss kernel28 /// a structure to contain data related to image smoothing with a pre-cached 1D gauss kernel 29 29 typedef struct { 30 30 int Nx; … … 34 34 psF32 *resultY; 35 35 psVector *kernel; 36 } psImageSmooth_PreAlloc_Data; 36 } psImageSmoothCacheData; 37 38 /// a structure to contain data related to image smoothing with a pre-cached 1D gauss kernel 39 typedef struct { 40 float Nsigma; 41 int Ns; // number of pixel radii 42 float *radflux; // conv kernel in special positions 43 } psImageSmooth2dCacheData; 37 44 38 45 /// A convolution kernel … … 306 313 ); 307 314 308 psImageSmooth_PreAlloc_Data *psImageSmooth_PreAlloc_DataAlloc (psImage *image, double sigma, double Nsigma); 309 bool psImageSmooth_PreAlloc_F32(psImage *image, psImageSmooth_PreAlloc_Data *smdata); 315 psImageSmoothCacheData *psImageSmoothCacheAlloc (psImage *image, double sigma, double Nsigma); 316 bool psImageSmoothCache_F32(psImage *image, psImageSmoothCacheData *smdata); 317 bool psImageSmoothCacheKernel_Gauss (psImageSmoothCacheData *smdata, float sigma); 310 318 311 319 /// Control threading for image convolution functions … … 318 326 bool psImageConvolveGetThreads(void); 319 327 328 psImageSmooth2dCacheData *psImageSmooth2dCacheAlloc (float Nsigma); 329 bool psImageSmooth2dCacheKernel_PS1_V1 (psImageSmooth2dCacheData *smdata, float sigma, float kappa); 330 bool psImageSmooth2dCacheKernel_Gauss (psImageSmooth2dCacheData *smdata, float sigma); 331 bool psImageSmooth2dCache_F32(psImage *image, psImageSmooth2dCacheData *smdata); 332 320 333 /// @} 321 334 #endif // #ifndef PS_IMAGE_CONVOLVE_H -
trunk/psLib/src/math/psEllipse.c
r35555 r36375 12 12 // f = exp(-z) where z describes the elliptical contour at any flux level: 13 13 14 // NOTE: major, minor are the 1-sigma lengths in the major,minor directions assuming the 15 // moments represent a Gaussian profile 16 14 17 // sigma shape: z = 0.5((x/sx)^2 + (y/sy)^2 + sxy*x*y) 15 18 // sigma axes : z = 0.5((x/sa)^2 + (y/sb)^2), x,y rotated by theta … … 17 20 // polarization : e0, e1, e2 18 21 19 // ellipse rotation (major, minor, theta) -> (x2, y2, xy) 22 // ellipse rotation (major, minor, theta) -> (Mxx, Mxy, Myy) 23 psEllipseMoments psEllipseAxesToMoments(psEllipseAxes axes) 24 { 25 psEllipseMoments moments; 26 27 double f1 = PS_SQR(axes.major) + PS_SQR(axes.minor); 28 double f2 = PS_SQR(axes.major) - PS_SQR(axes.minor); 29 30 moments.x2 = +0.5*f1 + 0.5*f2*cos(2*axes.theta); 31 moments.y2 = +0.5*f1 - 0.5*f2*cos(2*axes.theta); 32 moments.xy = +0.5*f2*sin(2*axes.theta); 33 34 assert (isfinite(moments.x2)); 35 assert (isfinite(moments.y2)); 36 assert (isfinite(moments.xy)); 37 38 return moments; 39 } 40 41 // ellipse rotation (Mxx, Mxy, Myy) -> (major, minor, theta). 42 psEllipseAxes psEllipseMomentsToAxes(psEllipseMoments moments, double maxAR) 43 { 44 psEllipseAxes axes; 45 psEllipseAxes badValue = {NAN, NAN, NAN}; 46 47 if (!isfinite(moments.x2)) return badValue; 48 if (!isfinite(moments.y2)) return badValue; 49 if (!isfinite(moments.xy)) return badValue; 50 51 if (moments.x2 < 0) return badValue; 52 if (moments.y2 < 0) return badValue; 53 54 double g1 = moments.x2 + moments.y2; 55 double g2 = moments.x2 - moments.y2; 56 double g3 = sqrt(PS_SQR(g2) + 4*PS_SQR(moments.xy)); 57 58 axes.major = sqrt (0.5*(g1 + g3)); 59 axes.theta = +0.5 * atan2 (+2.0*moments.xy, g2); // theta in radians 60 61 // long, thin objects are likely to have a poorly measured minor axis 62 // the angle and major axis are likely to be ok. 63 // restrict the axis ratio 64 double rAR2 = (g1 - g3) / (g1 + g3); 65 if (rAR2 < 1.0/PS_SQR(maxAR)) { 66 axes.minor = axes.major / maxAR; 67 } else { 68 axes.minor = sqrt (0.5*(g1 - g3)); 69 } 70 71 assert (isfinite(axes.major)); 72 assert (isfinite(axes.minor)); 73 assert (isfinite(axes.theta)); 74 75 return axes; 76 } 77 78 // ellipse rotation (major, minor, theta) -> (sx, sy, sxy) 79 // theta is postive rotation of major axis away from x-axis 80 psEllipseShape psEllipseAxesToShape(psEllipseAxes axes) 81 { 82 psEllipseShape shape; 83 psEllipseShape badValue = {NAN, NAN, NAN}; 84 85 if (!isfinite(axes.minor)) return badValue; 86 if (!isfinite(axes.major)) return badValue; 87 if (!isfinite(axes.theta)) return badValue; 88 89 if (axes.minor <= 0) return badValue; 90 if (axes.major <= 0) return badValue; 91 92 double f1 = 1.0 / PS_SQR(axes.minor) + 1.0 / PS_SQR(axes.major); 93 double f2 = 1.0 / PS_SQR(axes.minor) - 1.0 / PS_SQR(axes.major); 94 95 double sxr = 0.5*f1 - 0.5*f2*cos(2*axes.theta); 96 double syr = 0.5*f1 + 0.5*f2*cos(2*axes.theta); 97 98 // sxr, syr cannot be < 0 (f1 >= f2) 99 100 shape.sx = +1.0 / sqrt(sxr); 101 shape.sy = +1.0 / sqrt(syr); 102 shape.sxy = -0.5*f2*sin(2*axes.theta); 103 104 assert (isfinite(shape.sx)); 105 assert (isfinite(shape.sy)); 106 assert (isfinite(shape.sxy)); 107 108 return shape; 109 } 110 111 // ellipse derotation (sx, sy, sxy) -> (major, minor, theta) 112 psEllipseAxes psEllipseShapeToAxes(psEllipseShape shape, double maxAR) 113 { 114 psEllipseAxes axes; 115 116 double f1 = 1.0 / PS_SQR(shape.sy) + 1.0 / PS_SQR(shape.sx); 117 double f2 = 1.0 / PS_SQR(shape.sy) - 1.0 / PS_SQR(shape.sx); 118 double f3 = sqrt(PS_SQR(f2) + 4*PS_SQR(shape.sxy)); 119 120 axes.minor = sqrt (2.0 / (f1 + f3)); 121 axes.theta = -0.5 * atan2 (+2.0*shape.sxy, f2); 122 123 // long, thin objects are likely to have a poorly measured major axis 124 // the angle and minor axis are likely to be ok. 125 // restrict the axis ratio 126 double rAR2 = (f1 - f3) / (f1 + f3); 127 if (rAR2 < 1.0/PS_SQR(maxAR)) { 128 axes.major = axes.minor * maxAR; 129 } else { 130 axes.major = sqrt (2.0 / (f1 - f3)); 131 } 132 133 assert (isfinite(axes.theta)); 134 assert (isfinite(axes.major)); 135 assert (isfinite(axes.minor)); 136 137 return axes; 138 } 139 140 // ellipse rotation (major, minor, theta) -> (e0, e1, e2) 20 141 psEllipsePol psEllipseAxesToPol(psEllipseAxes axes) 21 142 { … … 35 156 } 36 157 37 // ellipse rotation (major, minor, theta) -> (x2, y2, xy) 38 psEllipsePol psEllipseShapeToPol(psEllipseShape shape) 39 { 40 psEllipsePol pol; 41 42 double r = 1.0 / (1.0 - PS_SQR(shape.sx)*PS_SQR(shape.sy)*PS_SQR(shape.sxy)); 43 44 pol.e0 = r*(PS_SQR(shape.sx) + PS_SQR(shape.sy)); 45 pol.e1 = r*(PS_SQR(shape.sx) - PS_SQR(shape.sy)); 46 // XXX I do not understand this negative sign 47 pol.e2 = -r*(2.0*PS_SQR(shape.sx)*PS_SQR(shape.sy)*shape.sxy); 48 49 assert (isfinite(pol.e0)); 50 assert (isfinite(pol.e1)); 51 assert (isfinite(pol.e2)); 52 53 return pol; 54 } 55 56 // ellipse rotation (major, minor, theta) -> (x2, y2, xy) 57 // XXXX handle case where e0 < LIMIT 158 // ellipse rotation (e0, e1, e2) -> (major, minor, theta) 58 159 psEllipseAxes psEllipsePolToAxes(const psEllipsePol pol, 59 160 const float minMinorAxis) … … 96 197 } 97 198 98 // ellipse rotation (major, minor, theta) -> (x2, y2, xy) 99 psEllipseMoments psEllipseAxesToMoments(psEllipseAxes axes) 100 { 101 psEllipseMoments moments; 102 103 double f1 = PS_SQR(axes.major) + PS_SQR(axes.minor); 104 double f2 = PS_SQR(axes.major) - PS_SQR(axes.minor); 105 106 moments.x2 = +0.5*f1 + 0.5*f2*cos(2*axes.theta); 107 moments.y2 = +0.5*f1 - 0.5*f2*cos(2*axes.theta); 108 moments.xy = +0.5*f2*sin(2*axes.theta); 109 110 assert (isfinite(moments.x2)); 111 assert (isfinite(moments.y2)); 112 assert (isfinite(moments.xy)); 113 114 return moments; 115 } 116 117 // ellipse rotation (x2, y2, xy) -> (major, minor, theta). NOTE: major, minor are the 118 // 1-sigma lengths in the major,minor directions assuming the moments represent a Gaussian 119 // profile 120 psEllipseAxes psEllipseMomentsToAxes(psEllipseMoments moments, double maxAR) 121 { 122 psEllipseAxes axes; 123 psEllipseAxes badValue = {NAN, NAN, NAN}; 124 125 if (!isfinite(moments.x2)) return badValue; 126 if (!isfinite(moments.y2)) return badValue; 127 if (!isfinite(moments.xy)) return badValue; 128 129 if (moments.x2 < 0) return badValue; 130 if (moments.y2 < 0) return badValue; 131 132 double g1 = moments.x2 + moments.y2; 133 double g2 = moments.x2 - moments.y2; 134 double g3 = sqrt(PS_SQR(g2) + 4*PS_SQR(moments.xy)); 135 136 axes.major = sqrt (0.5*(g1 + g3)); 137 axes.theta = +0.5 * atan2 (+2.0*moments.xy, g2); // theta in radians 138 139 // long, thin objects are likely to have a poorly measured minor axis 140 // the angle and major axis are likely to be ok. 141 // restrict the axis ratio 142 double rAR2 = (g1 - g3) / (g1 + g3); 143 if (rAR2 < 1.0/PS_SQR(maxAR)) { 144 axes.minor = axes.major / maxAR; 145 } else { 146 axes.minor = sqrt (0.5*(g1 - g3)); 147 } 148 149 assert (isfinite(axes.major)); 150 assert (isfinite(axes.minor)); 151 assert (isfinite(axes.theta)); 152 153 return axes; 154 } 155 156 // ellipse rotation (major, minor, theta) -> (sx, sy, sxy) 157 // theta is postive rotation of major axis away from x-axis 158 psEllipseShape psEllipseAxesToShape(psEllipseAxes axes) 199 // ellipse rotation (sx, sy, sxy) -> (e0, e1, e2) 200 psEllipsePol psEllipseShapeToPol(psEllipseShape shape) 201 { 202 psEllipsePol pol; 203 204 double r = 1.0 / (1.0 - PS_SQR(shape.sx)*PS_SQR(shape.sy)*PS_SQR(shape.sxy)); 205 206 pol.e0 = r*(PS_SQR(shape.sx) + PS_SQR(shape.sy)); 207 pol.e1 = r*(PS_SQR(shape.sx) - PS_SQR(shape.sy)); 208 // XXX I do not understand this negative sign 209 pol.e2 = -r*(2.0*PS_SQR(shape.sx)*PS_SQR(shape.sy)*shape.sxy); 210 211 assert (isfinite(pol.e0)); 212 assert (isfinite(pol.e1)); 213 assert (isfinite(pol.e2)); 214 215 return pol; 216 } 217 218 // ellipse rotation (e0, e1, e2) -> (sx, sy, sxy) 219 psEllipseShape psEllipsePolToShape(psEllipsePol pol) 159 220 { 160 221 psEllipseShape shape; 161 psEllipseShape badValue = {NAN, NAN, NAN}; 162 163 if (!isfinite(axes.minor)) return badValue; 164 if (!isfinite(axes.major)) return badValue; 165 if (!isfinite(axes.theta)) return badValue; 166 167 if (axes.minor <= 0) return badValue; 168 if (axes.major <= 0) return badValue; 169 170 double f1 = 1.0 / PS_SQR(axes.minor) + 1.0 / PS_SQR(axes.major); 171 double f2 = 1.0 / PS_SQR(axes.minor) - 1.0 / PS_SQR(axes.major); 172 173 double sxr = 0.5*f1 - 0.5*f2*cos(2*axes.theta); 174 double syr = 0.5*f1 + 0.5*f2*cos(2*axes.theta); 175 176 // sxr, syr cannot be < 0 (f1 >= f2) 177 178 shape.sx = +1.0 / sqrt(sxr); 179 shape.sy = +1.0 / sqrt(syr); 180 shape.sxy = -0.5*f2*sin(2*axes.theta); 222 223 double q = sqrt (PS_SQR(pol.e1) + PS_SQR(pol.e2)); 224 double p = PS_SQR(pol.e0) + PS_SQR(q) - 2.0*q*pol.e0; 225 226 // double f1 = 4*pol.e0 / p; 227 // double f2 = 4*q / p; 228 229 double sxr = 2.0*(pol.e0 - pol.e1) / p; 230 double syr = 2.0*(pol.e0 + pol.e1) / p; 231 232 shape.sx = sqrt(1.0 / sxr); 233 shape.sy = sqrt(1.0 / syr); 234 235 shape.sxy = -2.0 * pol.e2 / p; 181 236 182 237 assert (isfinite(shape.sx)); … … 187 242 } 188 243 189 // ellipse derotation (sx, sy, sxy) -> (major, minor, theta)190 psEllipseAxes psEllipseShapeToAxes(psEllipseShape shape, double maxAR)191 {192 psEllipseAxes axes;193 194 double f1 = 1.0 / PS_SQR(shape.sy) + 1.0 / PS_SQR(shape.sx);195 double f2 = 1.0 / PS_SQR(shape.sy) - 1.0 / PS_SQR(shape.sx);196 double f3 = sqrt(PS_SQR(f2) + 4*PS_SQR(shape.sxy));197 198 axes.minor = sqrt (2.0 / (f1 + f3));199 axes.theta = -0.5 * atan2 (+2.0*shape.sxy, f2);200 201 // long, thin objects are likely to have a poorly measured major axis202 // the angle and minor axis are likely to be ok.203 // restrict the axis ratio204 double rAR2 = (f1 - f3) / (f1 + f3);205 if (rAR2 < 1.0/PS_SQR(maxAR)) {206 axes.major = axes.minor * maxAR;207 } else {208 axes.major = sqrt (2.0 / (f1 - f3));209 }210 211 assert (isfinite(axes.theta));212 assert (isfinite(axes.major));213 assert (isfinite(axes.minor));214 215 return axes;216 }217 218 244 // XXX keep this construction? 219 245 // force the axis ratio to be less than 10 -
trunk/psLib/src/math/psEllipse.h
r19996 r36375 38 38 } psEllipseShape; 39 39 40 /// Ellipse defined in terms of polari sations40 /// Ellipse defined in terms of polarizations 41 41 typedef struct { 42 42 double e0; ///< Scale (Mxx + Myy) … … 65 65 ); 66 66 67 /// Convert axes to polari sation representation67 /// Convert axes to polarization representation 68 68 psEllipsePol psEllipseAxesToPol(psEllipseAxes axes ///< Axes of ellipse 69 69 ); 70 70 71 /// Convert shape to polarisation representation 71 /// Convert polarization to axes representation 72 psEllipseAxes psEllipsePolToAxes(const psEllipsePol pol, ///< Polarization of ellipse 73 const float minMinorAxis ///< Minimum allowed minor axis 74 ); 75 76 /// Convert shape to polarization representation 72 77 psEllipsePol psEllipseShapeToPol(psEllipseShape shape ///< Shape of ellipse 73 78 ); 74 79 75 /// Convert polarisation to axes representation 76 /// 77 /// XXX This API goes against the PS convention of outputs being first. 78 psEllipseAxes psEllipsePolToAxes(const psEllipsePol pol, ///< Polarisation of ellipse 79 const float minMinorAxis ///< Minimum allowed minor axis 80 ); 80 /// Convert shape to polarization representation 81 psEllipseShape psEllipsePolToShape(psEllipsePol pol ///< Shape of ellipse 82 ); 81 83 82 84 /// @} -
trunk/psLib/src/math/psMixtureModels.c
- Property svn:mergeinfo changed
/branches/eam_branches/ipp-20130904/psLib/src/math/psMixtureModels.c (added) merged: 36197,36256,36369
- Property svn:mergeinfo changed
-
trunk/psLib/test/imageops
- Property svn:ignore
-
old new 25 25 tap_psImageConvolve 26 26 tap_psImageConvolve2 27 tap_psImageConvolve2dCache 27 28 convolutionBench 28 29 tap_psImageInterpolate2
-
- Property svn:ignore
-
trunk/psLib/test/imageops/Makefile.am
r35767 r36375 22 22 tap_psImageConvolve \ 23 23 tap_psImageConvolve2 \ 24 tap_psImageConvolve2dCache \ 24 25 tap_psImagePixelExtract \ 25 26 tap_psImageInterpolate2 \
Note:
See TracChangeset
for help on using the changeset viewer.
