Changeset 11153 for trunk/psLib/src/imageops/psImageConvolve.c
- Timestamp:
- Jan 18, 2007, 6:30:33 PM (19 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/imageops/psImageConvolve.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/imageops/psImageConvolve.c
r10999 r11153 5 5 * @author Robert DeSonia, MHPCC 6 6 * 7 * @version $Revision: 1.4 1$ $Name: not supported by cvs2svn $8 * @date $Date: 2007-01- 09 22:38:52$7 * @version $Revision: 1.42 $ $Name: not supported by cvs2svn $ 8 * @date $Date: 2007-01-19 04:30:33 $ 9 9 * 10 10 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 671 671 return true; 672 672 } 673 674 bool psImageSmoothMaskF32 (psImage *image, 675 psImage *mask, 676 psMaskType maskVal, 677 double sigma, 678 double Nsigma) 679 { 680 PS_ASSERT_IMAGE_NON_NULL(image, NULL); 681 PS_ASSERT_IMAGE_NON_NULL(mask, NULL); 682 683 // relevant terms 684 int Nrange = sigma*Nsigma + 0.5; // Number of pixels either side for convolution kernel 685 int Npixel = 2*Nrange + 1; // Total number of pixels in convolution kernel 686 int Nx = image->numCols; // Number of columns 687 int Ny = image->numRows; // Number of rows 688 689 /* generate normalized gaussian */ 690 psVector *gaussnorm = psVectorAlloc(Npixel, PS_TYPE_F32); 691 { 692 double sum = 0.0; 693 double factor = -0.5/(sigma*sigma); 694 for (int i = -Nrange; i < Nrange + 1; i++) { 695 gaussnorm->data.F32[i+Nrange] = exp(factor*i*i); 696 sum += gaussnorm->data.F32[i+Nrange]; 697 } 698 for (int i = -Nrange; i < Nrange + 1; i++) { 699 gaussnorm->data.F32[i+Nrange] /= sum; 700 } 701 } 702 psF32 *gauss = &gaussnorm->data.F32[Nrange]; 703 704 /** Smooth in X direction **/ 705 psVector *calculation = psVectorAlloc(Nx, PS_TYPE_F32); 706 for (int j = 0; j < Ny; j++) { 707 psU8 *vm = mask->data.U8[j]; 708 psF32 *vi = image->data.F32[j]; 709 psF32 *vo = calculation->data.F32; 710 // loop over all pixels in the row 711 for (int i = 0; i < Nx; i++, vi++, vo++, vm++) { 712 int offset = PS_MIN (i, Nrange); 713 psU8 *sm = vm - offset; 714 psF32 *si = vi - offset; 715 psF32 *sg = gauss - offset; 716 double g = 0.0; 717 double s = 0.0; 718 // loop over all valid pixels in the smoothing kernel 719 int xMin = PS_MAX (i - Nrange, 0); 720 int xMax = PS_MIN (i + Nrange + 1, Nx); 721 for (int n = xMin; n < xMax; n++, sm++, si++, sg++) { 722 if (*sm & maskVal) 723 continue; 724 s += *sg * *si; 725 g += *sg; 726 } 727 *vo = (g > 0) ? s / g : 0.0; 728 } 729 memcpy(image->data.F32[j], calculation->data.F32, Nx*sizeof(psF32)); 730 } 731 psFree(calculation); 732 733 /** Smooth in Y direction **/ 734 // allocate and save Nrange extra row vectors for storage. these will be 735 // written over the output rows only after we are Nrange rows beyond them 736 int Nsave = Nrange + 1; 737 psArray *rows = psArrayAlloc(Nsave); 738 for (int i = 0; i < Nsave; i++) { 739 rows->data[i] = psVectorAlloc(Nx, PS_TYPE_F32); 740 } 741 742 psVector *outsum = psVectorAlloc(Nx, PS_TYPE_F32); 743 for (int j = 0; j < Ny; j++) { 744 psVector *output = rows->data[j % Nsave]; 745 memset (output->data.F32, 0, Nx*sizeof(psF32)); 746 memset (outsum->data.F32, 0, Nx*sizeof(psF32)); 747 int yMin = PS_MAX (j - Nrange, 0); 748 int yMax = PS_MIN (j + Nrange + 1, Ny); 749 for (int n = yMin; n < yMax; n++) { 750 psU8 *vm = mask->data.U8[n]; 751 psF32 *vi = image->data.F32[n]; 752 psF32 *vo = output->data.F32; 753 psF32 *vs = outsum->data.F32; 754 double g = gauss[n - j]; 755 for (int i = 0; i < Nx; i++, vi++, vo++, vm++, vs++) { 756 if (*vm & maskVal) 757 continue; 758 *vo += *vi * g; 759 *vs += g; 760 } 761 } 762 // renormalize the row 763 psF32 *vo = output->data.F32; 764 psF32 *vs = outsum->data.F32; 765 for (int i = 0; i < Nx; i++, vo++, vs++) { 766 *vo = (*vs > 0) ? *vo / *vs : 0.0; 767 } 768 769 // Write the output row 770 if (j - Nrange >= 0) { 771 int Nout = (j - Nrange) % Nsave; 772 psVector *save = rows->data[Nout]; 773 memcpy(image->data.F32[j-Nrange], save->data.F32, Nx*sizeof(psF32)); 774 } 775 } 776 777 // Write the remaining output rows 778 for (int j = PS_MAX(0, Ny - Nrange); j < Ny; j++) { 779 psVector *save = rows->data[j % Nsave]; 780 memcpy(image->data.F32[j], save->data.F32, Nx*sizeof(psF32)); 781 } 782 psFree(rows); 783 psFree(outsum); 784 psFree(gaussnorm); 785 return true; 786 }
Note:
See TracChangeset
for help on using the changeset viewer.
