Changeset 21335 for trunk/psLib/src/imageops/psImageConvolve.c
- Timestamp:
- Feb 5, 2009, 12:36:19 PM (17 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/imageops/psImageConvolve.c (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/imageops/psImageConvolve.c
r21183 r21335 7 7 /// @author Eugene Magnier, IfA 8 8 /// 9 /// @version $Revision: 1.8 2$ $Name: not supported by cvs2svn $10 /// @date $Date: 2009-0 1-27 06:39:37$9 /// @version $Revision: 1.83 $ $Name: not supported by cvs2svn $ 10 /// @date $Date: 2009-02-05 22:36:19 $ 11 11 /// 12 12 /// Copyright 2004-2007 Institute for Astronomy, University of Hawaii … … 131 131 132 132 133 psKernel *psKernelGenerate(const psVector *tShifts, 134 const psVector *xShifts, 135 const psVector *yShifts, 136 float totalTime, 137 bool xyRelative) 133 psKernel *psKernelGenerate(const psVector *tShifts, const psVector *xShifts, const psVector *yShifts, 134 float totalTime, bool xyRelative) 138 135 { 139 136 PS_ASSERT_VECTOR_NON_NULL(tShifts, NULL); … … 232 229 } 233 230 234 psImage *psImageConvolveDirect(psImage *out, 235 const psImage *in, 236 const psKernel *kernel) 231 psImage *psImageConvolveDirect(psImage *out, const psImage *in, const psKernel *kernel) 237 232 { 238 233 PS_ASSERT_IMAGE_NON_NULL(in, NULL); … … 466 461 } 467 462 468 bool psImageSmooth(psImage *image, 469 double sigma, 470 double Nsigma) 463 464 // Generate normalised Gaussian vector 465 #define IMAGE_SMOOTH_GAUSS(TARGET, SIZE, SIGMA, TYPE) \ 466 psVector *TARGET = psVectorAlloc(2 * SIZE + 1, PS_TYPE_##TYPE); /* Gaussian */ \ 467 double sum = 0.0; /* Sum of Gaussian, for normalisation */ \ 468 double factor = -0.5/PS_SQR(SIGMA); /* Multiplier for exponential */ \ 469 for (int i = -SIZE, j = 0; i <= SIZE; i++, j++) { \ 470 sum += TARGET->data.TYPE[j] = exp(factor * PS_SQR(i)); \ 471 } \ 472 for (int i = 0; i <= 2 * SIZE + 1; i++) { \ 473 TARGET->data.TYPE[i] /= sum; \ 474 } 475 476 psKernel *psImageSmoothKernel(float sigma, float nSigma) 477 { 478 PS_ASSERT_FLOAT_LARGER_THAN(sigma, 0.0, NULL); 479 PS_ASSERT_FLOAT_LARGER_THAN(nSigma, 0.0, NULL); 480 481 int size = sigma * nSigma + 0.5; // Half-size of kernel 482 psKernel *kernel = psKernelAlloc(-size, size, -size, size); // Kernel to return 483 484 IMAGE_SMOOTH_GAUSS(gaussNorm, size, sigma, F32); 485 psF32 *gauss = &gaussNorm->data.F32[size]; // Convenient kernel-like indexing for Gaussian 486 for (int y = -size; y <= size; y++) { 487 for (int x = -size; x <= size; x++) { 488 kernel->kernel[y][x] = gauss[y] * gauss[x]; 489 } 490 } 491 psFree(gaussNorm); 492 493 return kernel; 494 } 495 496 497 bool psImageSmooth(psImage *image, double sigma, double Nsigma) 471 498 { 472 499 PS_ASSERT_IMAGE_NON_NULL(image, NULL); … … 474 501 // relevant terms 475 502 int Nrange = sigma*Nsigma + 0.5; // Number of pixels either side for convolution kernel 476 int Npixel = 2*Nrange + 1; // Total number of pixels in convolution kernel477 503 int Nx = image->numCols; // Number of columns 478 504 int Ny = image->numRows; // Number of rows 479 505 480 #define IMAGESMOOTH_CASE(TYPE) \481 case PS_TYPE_##TYPE: { \506 #define IMAGESMOOTH_CASE(TYPE) \ 507 case PS_TYPE_##TYPE: { \ 482 508 /* generate normalized gaussian */ \ 483 psVector *gaussnorm = psVectorAlloc(Npixel, PS_TYPE_##TYPE); \ 484 { \ 485 double sum = 0.0; \ 486 double factor = -0.5/(sigma*sigma); \ 487 for (int i = -Nrange; i < Nrange + 1; i++) { \ 488 gaussnorm->data.TYPE[i+Nrange] = exp(factor*i*i); \ 489 sum += gaussnorm->data.TYPE[i+Nrange]; \ 490 } \ 491 for (int i = -Nrange; i < Nrange + 1; i++) { \ 492 gaussnorm->data.TYPE[i+Nrange] /= sum; \ 493 } \ 494 } \ 509 IMAGE_SMOOTH_GAUSS(gaussnorm, Nrange, sigma, TYPE) \ 495 510 ps##TYPE *gauss = &gaussnorm->data.TYPE[Nrange]; \ 496 511 \ … … 711 726 } 712 727 713 psImage *psImageSmoothMask(psImage *output, 714 const psImage *image, 715 const psImage *mask, 716 psImageMaskType maskVal, 717 float sigma, 718 float numSigma, 719 float minGauss) 728 psImage *psImageSmoothMask(psImage *output, const psImage *image, const psImage *mask, 729 psImageMaskType maskVal, float sigma, float numSigma, float minGauss) 720 730 { 721 731 PS_ASSERT_IMAGE_NON_NULL(image, NULL); … … 726 736 int numCols = image->numCols, numRows = image->numRows; // Size of image 727 737 int xLast = numCols - 1, yLast = numRows - 1; // Last index 728 729 // relevant terms730 738 int size = sigma * numSigma + 0.5; // Half-size of kernel 731 int fullSize = 2*size + 1; // Total number of pixels in convolution kernel732 739 733 740 // Generate normalized gaussian 734 psVector *gaussNorm = psVectorAlloc(fullSize + 1, PS_TYPE_F32); // Normalised Gaussian 735 { 736 double sum = 0.0; 737 double norm = -0.5/(sigma*sigma); 738 for (int i = 0, u = -size; i <= fullSize; i++, u++) { 739 float value = expf(norm*PS_SQR(u)); 740 gaussNorm->data.F32[i] = value; 741 sum += value; 742 } 743 sum = 1.0 / sum; 744 for (int i = 0; i <= fullSize; i++) { 745 gaussNorm->data.F32[i] *= sum; 746 } 747 } 741 IMAGE_SMOOTH_GAUSS(gaussNorm, size, sigma, F32); 748 742 const psF32 *gauss = &gaussNorm->data.F32[size]; // Gaussian convolution kernel 749 743 … … 828 822 } 829 823 830 bool psImageSmoothMask_ScanRows_F32 (psImage *calculation, 831 psImage *calcMask, 832 const psImage *image, 833 const psImage *mask, 834 psImageMaskType maskVal, 835 psVector *gaussNorm, 836 float minGauss, 837 int size, 838 int rowStart, 839 int rowStop) 824 bool psImageSmoothMask_ScanRows_F32(psImage *calculation, psImage *calcMask, const psImage *image, 825 const psImage *mask, psImageMaskType maskVal, psVector *gaussNorm, 826 float minGauss, int size, int rowStart, int rowStop) 840 827 { 841 828 const psF32 *gauss = &gaussNorm->data.F32[size]; // Gaussian convolution kernel … … 873 860 } 874 861 875 bool psImageSmoothMask_ScanCols_F32 (psImage *output, 876 psImage *calculation, 877 psImage *calcMask, 878 psImageMaskType maskVal, 879 psVector *gaussNorm, 880 float minGauss, 881 int size, 882 int colStart, 883 int colStop) 862 bool psImageSmoothMask_ScanCols_F32(psImage *output, psImage *calculation, psImage *calcMask, 863 psImageMaskType maskVal, psVector *gaussNorm, float minGauss, 864 int size, int colStart, int colStop) 884 865 { 885 866 const psF32 *gauss = &gaussNorm->data.F32[size]; // Gaussian convolution kernel … … 953 934 } 954 935 955 psImage *psImageSmoothMask_Threaded(psImage *output, 956 const psImage *image, 957 const psImage *mask, 958 psImageMaskType maskVal, 959 float sigma, 960 float numSigma, 961 float minGauss) 936 psImage *psImageSmoothMask_Threaded(psImage *output, const psImage *image, const psImage *mask, 937 psImageMaskType maskVal, float sigma, float numSigma, float minGauss) 962 938 { 963 939 PS_ASSERT_IMAGE_NON_NULL(image, NULL); … … 971 947 int scanCols = nThreads ? (numCols / 4 / nThreads) : numCols; 972 948 int scanRows = nThreads ? (numRows / 4 / nThreads) : numRows; 973 974 // relevant terms975 949 int size = sigma * numSigma + 0.5; // Half-size of kernel 976 int fullSize = 2*size + 1; // Total number of pixels in convolution kernel977 950 978 951 // Generate normalized gaussian 979 psVector *gaussNorm = psVectorAlloc(fullSize + 1, PS_TYPE_F32); // Normalised Gaussian 980 { 981 double sum = 0.0; 982 double norm = -0.5/(sigma*sigma); 983 for (int i = 0, u = -size; i <= fullSize; i++, u++) { 984 float value = expf(norm*PS_SQR(u)); 985 gaussNorm->data.F32[i] = value; 986 sum += value; 987 } 988 sum = 1.0 / sum; 989 for (int i = 0; i <= fullSize; i++) { 990 gaussNorm->data.F32[i] *= sum; 991 } 992 } 952 IMAGE_SMOOTH_GAUSS(gaussNorm, size, sigma, F32); 993 953 994 954 switch (image->type.type) { … … 1089 1049 1090 1050 1091 bool psImageSmoothMaskF32 (psImage *image, 1092 psImage *mask, 1093 psImageMaskType maskVal, 1094 double sigma, 1095 double Nsigma) 1051 bool psImageSmoothMaskF32(psImage *image, psImage *mask, psImageMaskType maskVal, 1052 double sigma, double Nsigma) 1096 1053 { 1097 1054 PS_ASSERT_IMAGE_NON_NULL(image, NULL); … … 1100 1057 // relevant terms 1101 1058 int Nrange = sigma*Nsigma + 0.5; // Number of pixels either side for convolution kernel 1102 int Npixel = 2*Nrange + 1; // Total number of pixels in convolution kernel1103 1059 int Nx = image->numCols; // Number of columns 1104 1060 int Ny = image->numRows; // Number of rows 1105 1061 1106 1062 /* generate normalized gaussian */ 1107 psVector *gaussnorm = psVectorAlloc(Npixel, PS_TYPE_F32); 1108 { 1109 double sum = 0.0; 1110 double factor = -0.5/(sigma*sigma); 1111 for (int i = -Nrange; i < Nrange + 1; i++) { 1112 gaussnorm->data.F32[i+Nrange] = exp(factor*i*i); 1113 sum += gaussnorm->data.F32[i+Nrange]; 1114 } 1115 for (int i = -Nrange; i < Nrange + 1; i++) { 1116 gaussnorm->data.F32[i+Nrange] /= sum; 1117 } 1118 } 1063 IMAGE_SMOOTH_GAUSS(gaussnorm, Nrange, sigma, F32); 1119 1064 psF32 *gauss = &gaussnorm->data.F32[Nrange]; 1120 1065 … … 1148 1093 psFree(calculation); 1149 1094 1150 // XXX test1151 if (0) {1152 psFree(gaussnorm);1153 return true;1154 }1155 1156 1095 /** Smooth in Y direction **/ 1157 1096 // allocate and save Nrange extra row vectors for storage. these will be
Note:
See TracChangeset
for help on using the changeset viewer.
