Changeset 7089
- Timestamp:
- May 8, 2006, 5:16:52 PM (20 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/imageops/psImageConvolve.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/imageops/psImageConvolve.c
r7077 r7089 5 5 * @author Robert DeSonia, MHPCC 6 6 * 7 * @version $Revision: 1.3 4$ $Name: not supported by cvs2svn $8 * @date $Date: 2006-05-0 5 23:55:56$7 * @version $Revision: 1.35 $ $Name: not supported by cvs2svn $ 8 * @date $Date: 2006-05-09 03:16:52 $ 9 9 * 10 10 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 588 588 589 589 // relevant terms 590 int Nrange = sigma*Nsigma + 0.5; // Number of pixels either side 590 int Nrange = sigma*Nsigma + 0.5; // Number of pixels either side for convolution kernel 591 591 int Npixel = 2*Nrange + 1; // Total number of pixels in convolution kernel 592 592 int Nx = image->numCols; // Number of columns … … 596 596 case PS_TYPE_##TYPE: { \ 597 597 /* generate normalized gaussian */ \ 598 psVector *gaussnorm = psVectorAlloc (Npixel, PS_TYPE_##TYPE); \598 psVector *gaussnorm = psVectorAlloc(Npixel, PS_TYPE_##TYPE); \ 599 599 gaussnorm->n = gaussnorm->nalloc; \ 600 double sum = 0.0; \ 601 double factor = -0.5/(sigma*sigma); \ 602 for (int i = -Nrange; i < Nrange + 1; i++) { \ 603 gaussnorm->data.TYPE[i+Nrange] = exp (factor*i*i); \ 604 sum += gaussnorm->data.TYPE[i+Nrange]; \ 605 } \ 606 for (int i = -Nrange; i < Nrange + 1; i++) { \ 607 gaussnorm->data.TYPE[i+Nrange] /= sum; \ 600 { \ 601 double sum = 0.0; \ 602 double factor = -0.5/(sigma*sigma); \ 603 for (int i = -Nrange; i < Nrange + 1; i++) { \ 604 gaussnorm->data.TYPE[i+Nrange] = exp(factor*i*i); \ 605 sum += gaussnorm->data.TYPE[i+Nrange]; \ 606 } \ 607 for (int i = -Nrange; i < Nrange + 1; i++) { \ 608 gaussnorm->data.TYPE[i+Nrange] /= sum; \ 609 } \ 608 610 } \ 609 611 ps##TYPE *gauss = &gaussnorm->data.TYPE[Nrange]; \ 610 612 \ 611 /* smooth in X direction */ \ 612 psVector *temp = psVectorAlloc (Nx, PS_TYPE_##TYPE); \ 613 temp->n = temp->nalloc; \ 614 for (int j = 0; j < Ny; j++) { \ 615 ps##TYPE *vi = image->data.TYPE[j]; \ 616 ps##TYPE *vo = temp->data.TYPE; \ 617 /* smooth first Nrange pixels, with renorm */ \ 618 int xMax = PS_MIN(Nrange, Nx); \ 619 for (int i = 0; i < xMax; i++, vi++, vo++) { \ 620 ps##TYPE *vr = vi - i; \ 621 ps##TYPE *vg = gauss - i; \ 622 double g = 0; \ 623 double s = 0; \ 624 for (int n = -i; n < Nrange + 1; n++, vr++, vg++) { \ 625 s += *vg * *vr; \ 626 g += *vg; \ 613 /* Smooth in X direction */ \ 614 { \ 615 psVector *calculation = psVectorAlloc(Nx, PS_TYPE_##TYPE); \ 616 calculation->n = calculation->nalloc; \ 617 for (int j = 0; j < Ny; j++) { \ 618 ps##TYPE *vi = image->data.TYPE[j]; \ 619 ps##TYPE *vo = calculation->data.TYPE; \ 620 int xMax = PS_MIN(Nrange, Nx); \ 621 int convRange = PS_MIN(Nrange + 1, Nx); \ 622 /* Smooth first Nrange pixels, with renorm */ \ 623 for (int i = 0; i < xMax; i++, vi++, vo++) { \ 624 ps##TYPE *vr = vi - i; \ 625 ps##TYPE *vg = gauss - i; \ 626 double g = 0.0; \ 627 double s = 0.0; \ 628 for (int n = -i; n < convRange; n++, vr++, vg++) { \ 629 s += *vg * *vr; \ 630 g += *vg; \ 631 } \ 632 *vo = s / g; \ 627 633 } \ 628 *vo = s / g; \ 629 } \ 630 /* smooth middle pixels */ \ 631 for (int i = Nrange; i < Nx - Nrange; i++, vi++, vo++) { \ 632 ps##TYPE *vr = vi - Nrange; \ 633 ps##TYPE *vg = gauss - Nrange; \ 634 double s = 0; \ 635 for (int n = -Nrange; n < Nrange + 1; n++, vr++, vg++) { \ 636 s += *vg * *vr; \ 634 /* If that's all the pixels we have, then we're done already */ \ 635 if (Nx > Nrange) { \ 636 /* Smooth middle pixels */ \ 637 for (int i = Nrange; i < Nx - Nrange; i++, vi++, vo++) { \ 638 ps##TYPE *vr = vi - Nrange; \ 639 ps##TYPE *vg = gauss - Nrange; \ 640 double s = 0; \ 641 for (int n = -Nrange; n < Nrange + 1; n++, vr++, vg++) { \ 642 s += *vg * *vr; \ 643 } \ 644 *vo = s; \ 645 } \ 646 /* Smooth last Nrange pixels, with renorm */ \ 647 /* XXX does this miss the last column? */ \ 648 for (int i = Nx - Nrange; i < Nx; i++, vi++, vo++) { \ 649 ps##TYPE *vr = vi - Nrange; \ 650 ps##TYPE *vg = gauss - Nrange; \ 651 double g = 0.0; \ 652 double s = 0.0; \ 653 for (int n = -Nrange; n < Nx - i; n++, vr++, vg++) { \ 654 s += *vg * *vr; \ 655 g += *vg; \ 656 } \ 657 *vo = s / g; \ 658 } \ 637 659 } \ 638 *vo = s; \ 639 } \ 640 /* smooth last Nrange pixels, with renorm */ \ 641 /* XXX does this miss the last column? */ \ 642 for (int i = PS_MAX(Nx - Nrange, 0); i < Nx; i++, vi++, vo++) { \ 643 ps##TYPE *vr = vi - Nrange; \ 644 ps##TYPE *vg = gauss - Nrange; \ 645 double g = 0; \ 646 double s = 0; \ 647 for (int n = -Nrange; n < Nx - i - 1; n++, vr++, vg++) { \ 648 s += *vg * *vr; \ 649 g += *vg; \ 650 } \ 651 *vo = s / g; \ 652 } \ 653 memcpy (image->data.TYPE[j], temp->data.TYPE, Nx*sizeof(ps##TYPE)); \ 654 } \ 655 psFree (temp); \ 656 \ 657 /* smooth in Y direction */ \ 658 psArray *temprows = psArrayAlloc (Nrange); \ 659 temprows->n = Nrange; \ 660 memcpy(image->data.TYPE[j], calculation->data.TYPE, Nx*sizeof(ps##TYPE)); \ 661 } \ 662 psFree(calculation); \ 663 } \ 664 \ 665 /* Smooth in Y direction */ \ 666 psArray *rows = psArrayAlloc(Nrange); \ 667 rows->n = Nrange; \ 668 /* Smooth the first Nrange pixels, with renorm */ \ 660 669 int yMax = PS_MIN(Nrange, Ny); \ 670 int convRange = PS_MIN(Nrange + 1, Ny); \ 661 671 for (int j = 0; j < yMax; j++) { \ 662 temp = psVectorAlloc (Nx, PS_TYPE_##TYPE); \ 663 temp->n = temp->nalloc; \ 664 /* zero the output row */ \ 665 memset (temp->data.TYPE, 0, Nx*sizeof(PS_TYPE_##TYPE)); \ 666 for (int n = -j, sum = 0; n < Nrange + 1; n++) { sum += gauss[n]; } \ 667 for (int n = -j; n < Nrange + 1; n++) { \ 672 psVector *calculation = psVectorAlloc(Nx, PS_TYPE_##TYPE); \ 673 calculation->n = calculation->nalloc; \ 674 /* Zero the output row */ \ 675 memset(calculation->data.TYPE, 0, Nx*sizeof(ps##TYPE)); \ 676 double sum = 0.0; \ 677 for (int n = -j; n < convRange; n++) { sum += gauss[n]; } \ 678 for (int n = -j; n < convRange; n++) { \ 668 679 ps##TYPE *vi = image->data.TYPE[j+n]; \ 669 ps##TYPE *vo = temp->data.TYPE; \670 double g = gauss[n] ; \680 ps##TYPE *vo = calculation->data.TYPE; \ 681 double g = gauss[n] / sum; \ 671 682 for (int i = 0; i < Nx; i++, vi++, vo++) { \ 672 683 *vo += *vi * g; \ 673 684 } \ 674 685 } \ 675 /* save output rows on temp array */ \ 676 temprows->data[j] = temp; \ 677 } \ 678 for (int j = Nrange; j < Ny - Nrange; j++) { \ 679 /* save the Nrange-offset output row, then zero */ \ 680 int Nr = j % Nrange; \ 681 temp = temprows->data[Nr]; \ 682 memcpy (image->data.TYPE[j-Nrange], temp->data.TYPE, Nx*sizeof(ps##TYPE)); \ 683 memset (temp->data.TYPE, 0, Nx*sizeof(PS_TYPE_##TYPE)); \ 684 for (int n = -Nrange; n < Nrange + 1; n++) { \ 685 ps##TYPE *vi = image->data.TYPE[j+n]; \ 686 ps##TYPE *vo = temp->data.TYPE; \ 687 double g = gauss[n]; \ 688 for (int i = 0; i < Nx; i++, vi++, vo++) { \ 689 *vo += *vi * g; \ 686 /* Save output rows on temp array of rows */ \ 687 rows->data[j] = calculation; \ 688 } \ 689 if (Ny < Nrange) { \ 690 /* Need to save the first bit, then we're done */ \ 691 for (int j = 0; j < Ny; j++) { \ 692 psVector *save = rows->data[j]; \ 693 memcpy(image->data.TYPE[j], save->data.TYPE, Nx*sizeof(ps##TYPE)); \ 694 } \ 695 } else { \ 696 /* Smooth middle pixels */ \ 697 psVector *calculation = psVectorAlloc(Nx, PS_TYPE_##TYPE); \ 698 for (int j = Nrange; j < Ny - Nrange; j++) { \ 699 memset(calculation->data.TYPE, 0, Nx*sizeof(ps##TYPE)); \ 700 for (int n = -Nrange; n < Nrange + 1; n++) { \ 701 ps##TYPE *vi = image->data.TYPE[j+n]; \ 702 ps##TYPE *vo = calculation->data.TYPE; \ 703 double g = gauss[n]; \ 704 for (int i = 0; i < Nx; i++, vi++, vo++) { \ 705 *vo += *vi * g; \ 706 } \ 690 707 } \ 691 } \ 692 } \ 693 for (int j = PS_MAX(Ny - Nrange, 0); j < Ny; j++) { \ 694 /* save the Nrange-offset output row, then zero */ \ 695 int Nr = j % Nrange; \ 696 temp = temprows->data[Nr]; \ 697 memcpy (image->data.TYPE[j-Nrange], temp->data.TYPE, Nx*sizeof(ps##TYPE)); \ 698 memset (temp->data.TYPE, 0, Nx*sizeof(PS_TYPE_##TYPE)); \ 699 for (int n = -Nrange, sum = 0; n < Ny - j - 1; n++) { sum += gauss[n]; } \ 700 for (int n = -Nrange; n < Ny - j - 1; n++) { \ 701 ps##TYPE *vi = image->data.TYPE[j+n]; \ 702 ps##TYPE *vo = temp->data.TYPE; \ 703 double g = gauss[n]; \ 704 for (int i = 0; i < Nx; i++, vi++, vo++) { \ 705 *vo += *vi * g; \ 708 /* Write the output row */ \ 709 int Nr = j % Nrange; \ 710 psVector *save = rows->data[Nr]; \ 711 memcpy(image->data.TYPE[j-Nrange], save->data.TYPE, Nx*sizeof(ps##TYPE)); \ 712 /* Juggle the pointers, so that next run we use the one we just wrote */ \ 713 rows->data[Nr] = calculation; \ 714 calculation = save; \ 715 } \ 716 /* Smooth last Nrange pixels, with renorm */ \ 717 for (int j = Ny - Nrange; j < Ny; j++) { \ 718 /* save the Nrange-offset output row, then zero */ \ 719 memset(calculation->data.TYPE, 0, Nx*sizeof(ps##TYPE)); \ 720 double sum = 0.0; \ 721 for (int n = -Nrange; n < Ny - j; n++) { sum += gauss[n]; } \ 722 for (int n = -Nrange; n < Ny - j; n++) { \ 723 ps##TYPE *vi = image->data.TYPE[j+n]; \ 724 ps##TYPE *vo = calculation->data.TYPE; \ 725 double g = gauss[n] / sum; \ 726 for (int i = 0; i < Nx; i++, vi++, vo++) { \ 727 *vo += *vi * g; \ 728 } \ 706 729 } \ 707 } \ 708 } \ 709 for (int j = Ny; j < Ny + Nrange; j++) { \ 710 /* save the Nrange-offset output row, then zero */ \ 711 int Nr = j % Nrange; \ 712 temp = temprows->data[Nr]; \ 713 memcpy (image->data.TYPE[j-Nrange], temp->data.TYPE, Nx*sizeof(ps##TYPE)); \ 714 } \ 715 psFree (temprows); \ 716 psFree (gaussnorm); \ 730 /* Write the output row */ \ 731 int Nr = j % Nrange; \ 732 psVector *save = rows->data[Nr]; \ 733 memcpy(image->data.TYPE[j-Nrange], save->data.TYPE, Nx*sizeof(ps##TYPE)); \ 734 /* Juggle the pointers, so that next run we use the one we just wrote */ \ 735 rows->data[Nr] = calculation; \ 736 calculation = save; \ 737 } \ 738 psFree(calculation); \ 739 /* Write the remaining rows */ \ 740 for (int j = Ny; j < Ny + Nrange; j++) { \ 741 int Nr = j % Nrange; \ 742 psVector *save = rows->data[Nr]; \ 743 memcpy(image->data.TYPE[j-Nrange], save->data.TYPE, Nx*sizeof(ps##TYPE)); \ 744 } \ 745 } \ 746 psFree(rows); \ 747 psFree(gaussnorm); \ 717 748 break; \ 718 749 }
Note:
See TracChangeset
for help on using the changeset viewer.
