Changeset 32724
- Timestamp:
- Nov 20, 2011, 2:24:57 PM (14 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/imageops/psImageConvolve.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/imageops/psImageConvolve.c
r32714 r32724 765 765 } 766 766 767 // XXX NOTE : work to do : figure out the actual containers needed in there, pre-allocate them 768 bool psImageSmooth_PreAlloc_F32(psImage *image, double sigma, double Nsigma) 769 { 770 PS_ASSERT_IMAGE_NON_NULL(image, NULL); 771 // assert on data type 772 773 // relevant terms 774 int Nrange = sigma*Nsigma + 0.5; // Number of pixels either side for convolution kernel 775 int Nx = image->numCols; // Number of columns 776 int Ny = image->numRows; // Number of rows 777 778 IMAGE_SMOOTH_GAUSS(gaussnorm, Nrange, sigma, F32); 779 psF32 *gauss = &gaussnorm->data.F32[Nrange]; 780 781 // use a temp running buffer for X and Y directions. 782 psF32 *resultX = (psF32 *) psAlloc(Nx * sizeof(psF32)); 783 memset (resultX, 0, Nx*sizeof(psF32)); 784 psF32 *resultY = (psF32 *) psAlloc(Ny * sizeof(psF32)); 785 memset (resultY, 0, Ny*sizeof(psF32)); 786 787 /* Smooth in X direction */ 788 { 789 for (int j = 0; j < Ny; j++) { 790 psF32 *vi = image->data.F32[j]; 791 int xMax = PS_MIN(Nrange, Nx); 792 int convRange = PS_MIN(Nrange + 1, Nx); 793 /* Smooth first Nrange pixels, with renorm */ 794 for (int i = 0; i < xMax; i++, vi++) { 795 psF32 *vr = vi - i; 796 psF32 *vg = gauss - i; 797 double g = 0.0; 798 double s = 0.0; 799 for (int n = -i; n < convRange; n++, vr++, vg++) { 800 s += *vg * *vr; 801 g += *vg; 802 } 803 resultX[i] = s / g; 804 } 805 /* If that's all the pixels we have, then we're done already */ 806 if (Nx > Nrange) { 807 /* Smooth middle pixels */ 808 for (int i = Nrange; i < Nx - Nrange; i++, vi++) { 809 psF32 *vr = vi - Nrange; 810 psF32 *vg = gauss - Nrange; 811 double s = 0; 812 for (int n = -Nrange; n < Nrange + 1; n++, vr++, vg++) { 813 s += *vg * *vr; 814 } 815 resultX[i] = s; 816 } 817 /* Smooth last Nrange pixels, with renorm */ 818 for (int i = Nx - Nrange; i < Nx; i++, vi++) { 819 psF32 *vr = vi - Nrange; 820 psF32 *vg = gauss - Nrange; 821 double g = 0.0; 822 double s = 0.0; 823 for (int n = -Nrange; n < Nx - i; n++, vr++, vg++) { 824 s += *vg * *vr; 825 g += *vg; 826 } 827 resultX[i] = s / g; 828 } 829 } 830 memcpy(image->data.F32[j], resultX, Nx*sizeof(psF32)); 831 } 832 } 833 834 // this section probably hits the cache poorly for large images, but is probably OK for small ones 835 /* Smooth in Y direction */ 836 { 837 for (int i = 0; i < Nx; i++) { 838 int yMax = PS_MIN(Nrange, Ny); 839 int convRange = PS_MIN(Nrange + 1, Ny); 840 /* Smooth first Nrange pixels, with renorm */ 841 for (int j = 0; j < yMax; j++) { 842 psF32 *vg = gauss - j; 843 double g = 0.0; 844 double s = 0.0; 845 for (int n = -j; n < convRange; n++, vg++) { 846 psF32 vr = image->data.F32[j+n][i]; 847 s += *vg * vr; 848 g += *vg; 849 } 850 resultY[j] = s / g; 851 } 852 /* If that's all the pixels we have, then we're done already */ 853 if (Ny > Nrange) { 854 /* Smooth middle pixels */ 855 for (int j = Nrange; j < Ny - Nrange; j++) { 856 psF32 *vg = gauss - Nrange; 857 double s = 0; 858 for (int n = -Nrange; n < Nrange + 1; n++, vg++) { 859 psF32 vr = image->data.F32[j+n][i]; 860 s += *vg * vr; 861 } 862 resultY[j] = s; 863 } 864 /* Smooth last Nrange pixels, with renorm */ 865 for (int j = Ny - Nrange; j < Ny; j++) { 866 psF32 *vg = gauss - Nrange; 867 double g = 0.0; 868 double s = 0.0; 869 for (int n = -Nrange; n < Ny - j; n++, vg++) { 870 psF32 vr = image->data.F32[j+n][i]; 871 s += *vg * vr; 872 g += *vg; 873 } 874 resultY[j] = s / g; 875 } 876 } 877 // loop here 878 for (int j = 0; j < Ny; j++) { 879 image->data.F32[j][i] = resultY[j]; 880 } 881 } 882 } 883 884 psFree(resultX); 885 psFree(resultY); 886 psFree(gaussnorm); 887 888 return true; 889 } 890 767 891 static bool imageSmoothMaskPixels(psVector *out, const psImage *image, const psImage *mask, 768 892 psImageMaskType maskVal, const psVector *x, const psVector *y,
Note:
See TracChangeset
for help on using the changeset viewer.
