PlugIn Algorithm Median (con't, part 2)

From MIPAV
Revision as of 15:06, 16 February 2012 by Angelfish100 (Talk)

(diff) <previousrevision> | Latest revision (diff) | <nextrevision> (diff)
Jump to: navigation, search

PlugIn Algorithm Median (con't, part 2)

400
401 if (sliceFiltering){
402 for ( currentSlice = 0; currentSlice < numberOfSlices && !threadStopped;
403 currentSlice ){
404 sliceFilter(buffer, resultBuffer, currentSlice*imageSliceLength,
405 "slice " String.valueOf(currentSlice 1));
406 }
407 }
408 else { // volume kernel requested
409 volumeFilter(buffer, resultBuffer);
410 }
411
412 if (threadStopped) {
413 finalize();
414 return;
415 }
416
417 try {
418 srcImage.importData(0, resultBuffer, true);
419 }
420 catch (IOException error) {
421 buffer = null;
422 resultBuffer = null;
423 errorCleanUp("Algorithm Median: source image locked", true);
424 setThreadStopped(true);
425 return;
426 }
427
428 progressBar.dispose();
429 setCompleted(true);
430 }
431
432 /**
433 * This function produces a new image that has been median filtered and places
434 * filtered image in the destination image.
435 */
436 private void calcStoreInDest2D(){
437
438 int length; // total number of data-elements (pixels) in
439 // image
440 float buffer[]; // data-buffer (for pixel data) which is the
441 // "heart" of
442 // the image
443 float resultBuffer[]; // copy-to buffer (for pixel data) for image data
444 // after filtering
445
|- |
446 try { destImage.setLock(ModelStorageBase.RW_LOCKED); }
447 catch (IOException error){
448 errorCleanUp("Algorithm Median reports: destination image locked", false);
449 return;
450 }
451 try {
452 if (!isColorImage) {
453 // image length is length in 2 dims
454 length = srcImage.getExtents()[0]
455 *srcImage.getExtents()[1];
456 }
457 else { // if (isColorImage) {
458 // image length is length in 2 dims
459 // by 4 color elements per pixel
460 length = srcImage.getExtents()[0]
461 *srcImage.getExtents()[1]
462 *4; // 1 each for ARGB
463 }
464 buffer = new float[length];
465 resultBuffer = new float[length];
466 srcImage.exportData(0,length, buffer); // locks and releases lock
467 }
468 catch (IOException error) {
469 buffer = null;
470 resultBuffer = null;
471 errorCleanUp("Algorithm Median reports: source image locked", true);
472 return;
473 }
474 catch (OutOfMemoryError e){
475 buffer = null;
476 resultBuffer = null;
477 errorCleanUp("Algorithm Median reports: out of memory", true);
478 return;
479 }
480
481 this.buildProgressBar();
482 sliceFilter(buffer, resultBuffer, 0, "image"); // filter image based on provided
483 // info
484 destImage.releaseLock(); // we didn't want to allow the image
485 // to be adjusted by someone else
486 progressBar.dispose();
487 if (threadStopped) {
488 finalize();
489 return;
490 }
491
492 try { // but now place buffer data into the
493 // image
494 destImage.importData(0, resultBuffer, true);
495 }
496 catch (IOException error) {
497 buffer = null;
498 resultBuffer = null;
499 errorCleanUp("Algorithm Median reports: destination image still locked",
500 true);
501 return;
502 }
503
Â
Â
|- |
504 setCompleted(true);
505 }
506
507 /**
508 * This function produces a new volume image that has been median filtered.
509 * Image can be filtered by filtering each slice individually, or by filtering using
510 * a kernel-volume.
511 */
512 private void calcStoreInDest3D(){
513
514 int length;
515 int imageSliceLength = valuesPerPixel *
516 srcImage.getExtents()[0]*srcImage.getExtents()[1]; // cover case of color image
517 float buffer[];
518 float resultBuffer[];
519
520 try { destImage.setLock(ModelStorageBase.RW_LOCKED); }
521 catch (IOException error){
522 errorCleanUp("Algorithm Median reports: destination image locked", false);
523 return;
524 }
525 try {
526 if (!isColorImage) {
527 // image length is length in 3 dims
528 length = srcImage.getExtents()[0]
529 *srcImage.getExtents()[1]
530 *srcImage.getExtents()[2];
531 }
532 else { // if (isColorImage) {
533 // image length is length in 3 dims
534 // by 4 color elements per pixel
535 length = srcImage.getExtents()[0]
536 *srcImage.getExtents()[1]
537 *srcImage.getExtents()[2]
538 *4; // 1 each for ARGB
539 }
540 buffer = new float[length];
541 srcImage.exportData(0,length, buffer); // locks and releases lock
542 this.buildProgressBar();
543 }
544 catch (IOException error) {
545 buffer = null;
546 resultBuffer = null;
547 errorCleanUp("Algorithm Median: source image locked", true);
548 return;
549 }
550 catch (OutOfMemoryError e){
551 buffer = null;
552 resultBuffer = null;
553 errorCleanUp("Algorithm Median: Out of memory creating process buffer",
554 true);
555 return;
556 }
557
Â
|- |
Â
|- |
558
559 try { resultBuffer = new float[length];}
560 catch(OutOfMemoryError e){
561 buffer = null;
562 resultBuffer = null;
563 errorCleanUp("Algorithm Median reports: Out of memory because of
564 resultBuffer", true);
565 return;
566 }
567
568 if (sliceFiltering){
569 for ( currentSlice = 0; currentSlice < numberOfSlices && !threadStopped;
570 currentSlice ) {
571 sliceFilter(buffer, resultBuffer, currentSlice*imageSliceLength,
572 "slice " String.valueOf(currentSlice 1));
573 }
574 }
575 else { // requested volume filter
576 if (isColorImage) // for color image
577 volumeColorFilter(buffer, resultBuffer);
578 else // for mono image
579 volumeFilter(buffer, resultBuffer);
580 }
581
582 destImage.releaseLock();
583
584 if (threadStopped) {
585 finalize();
586 return;
587 }
588
589 try{destImage.importData(0, resultBuffer, true);}
590 catch (IOException e)
591 {
592 buffer = null;
593 resultBuffer = null;
594 errorCleanUp("Algorithm Median reports: destination image still locked",
595 true);
596 return;
597 }
598 progressBar.dispose();
599 setCompleted(true);
600 }
601
602 /**
603 * Allows a single slice to be filtered. Note that a progressBar must be created
604 * first.
605 * @param srcBuffer Source buffer.
606 * @param destBuffer Destination Buffer.
607 * @param bufferStartingPoint Starting point for the buffer.
608 * @param msgString A text message that can be displayed as a message text
609 * in the progressBar.
610 */
611 private final void sliceFilter(float srcBuffer[],
612 float destBuffer[],
613 int bufferStartingPoint,
|- |
614 String msgString) {
615 int i, a, pass; // counting.... i is the offset
616 // from the bufferStartingPoint
617 // a adds support for 3D filtering by counting is as the pixel at the starting
618 point plus the counter offset
619 int buffStart = bufferStartingPoint; // data element at the buffer. a =
620 // bufferStartingPoint i
621 int sliceLength = srcImage.getSliceSize();
622 int imageSliceLength = sliceLength * valuesPerPixel; // since there are 4 values
623 // for every color pixel.
624 int kCenter = maskCenter; // to find the middle pixel of the
625 // kernel-mask
626 int width = srcImage.getExtents()[0]; // width of slice in number of pixels (
627 int height = srcImage.getExtents()[1]; // height of slice in number of pixels
628 int sliceWidth = width * valuesPerPixel; // width of slice, which, in color
629 // images is (4*width)
630 int sliceHeight = height; // height of image, which, actually
631 // doesn't change
632 initialIndex = 0; // first element is alpha
633
634 float tempBuffer[];
635
636 float average; // arithmetic mean
637 float sigma; // standard deviation
638
639 float maskedList[]; // list of buffer-values that were
640 // showing inside the mask
641
642 int row, col; // row and column vars for easier
643 // reading [(0,0) is in the top-
644 // left corner]
645 int mod; // 1% length of slice for percent
646 // complete
647
648 // these bounds "frame" the interior of the slice which may be filtered
649 // (&adjusted);
650 // image outside the frame may not
651 int upperBound, lowerBound, // bounds on the row
652 leftBound, rightBound; // bounds on the column
653
654 if (isColorImage) {
655 upperBound = halfK;
656 leftBound = halfK*4;
657 lowerBound = sliceHeight - halfK - 1;
658 rightBound = sliceWidth - halfK*4 - 1;
659
660 // data element at the buffer (a = i bufferStartingPoint) must start on an
661 // alpha value
662 buffStart = bufferStartingPoint - bufferStartingPoint%4; // & no effect if
663 // bufferStartingPoint%4 == 0 !!!
664
Â
Â
|- |
665 // copy all alpha values in this slice
666 setCopyColorText("alpha");
667 for (a = buffStart, i = 0; i < imageSliceLength; a =4, i =4) {
668 destBuffer[a] = srcBuffer[a]; // copy alpha;
669 }
670
671 }
672 else { // monochrome image
673 upperBound = leftBound = halfK;
674 rightBound = sliceWidth - halfK - 1;
675 lowerBound = sliceHeight - halfK -1;
676 }
677 mod = (imageSliceLength*numberOfSlices)/100; // mod is 1 percent of length of
678 // slice the number of slices.
679
680 BitSet mask = srcImage.generateVOIMask();
681
682 for (pass = 0; pass < iterations && !threadStopped; pass ) {
683 a = buffStart; // set/reset a to address pixels
684 // from the beginning of this
685 // buffer.
686 if (isColorImage) { // color image dealt with in
687 // special way
688 // choose i so proper colors go
689 // copy only needed RGB values
690 initialIndex = 0; // start with alpha on each pass
691 // (routine moved so we don't do
692 // it for each pass)
693 while (initialIndex < 3 && !threadStopped) { // alpha:0, R:1, G:2,
694 // B:3. But alpha must
695 // be copied
696 initialIndex; // next initial index
697 a = initialIndex; // keep the pixel location up with
698 // color indexed to
699
700 if (numberOfSlices > 1 && pBarVisible == true) { // 3D image update
701 // progressBar
702 // do a progress bar update
703 progressBar.setValue(Math.round
704 (( ( (float)(3*currentSlice*iterations 3*pass
705 (initialIndex - 1))/(3*iterations*numberOfSlices))*
706 100)));
707 }
708
709 if (!rChannel && initialIndex==1) {
710 // when looking at the image reds but we're not filtering the red channel
711 // copy all red values
712 setCopyColorText("red");
713 for (i = initialIndex; i < imageSliceLength; a = 4, i =4) {
714 destBuffer[a] = srcBuffer[a];
715 }
716 }
717 else if (!gChannel && initialIndex==2) {
718 // when looking at the image greens but we're not filtering the
719 // greens channel
720
|- |
721 // copy all greens values
722 setCopyColorText("green");
723 for (i = initialIndex; i < imageSliceLength; a =4, i =4) {
724 destBuffer[a] = srcBuffer[a];
725 }
726 }
727 else if (!bChannel && initialIndex==3) {
728 // when looking at the image blues but we're not filtering the
729 // blues channel
730 // copy all blue values
731 setCopyColorText("blue");
732 for (i = initialIndex; i < imageSliceLength; a =4, i =4) {
733 destBuffer[a] = srcBuffer[a];
734 }
735 }
736 else {
737 if (pBarVisible == true) {
738 progressBar.setMessage("Filtering " msgString " (pass "
739 String.valueOf(pass 1) " of " iterations ") ...");
740 }
741 // if we needed to filter the image, we dropped through the
742 // selection to filter the
743 // color given by ints initialIndex
744 for (i = initialIndex; i < imageSliceLength && !threadStopped;
745 a =4, i =4){
746 if (numberOfSlices == 1) { // 2D image update progressBar
747 if (i%mod == 0 && pBarVisible == true) {
748 progressBar.setValue(Math.round
749 ( (float)(3*(pass*sliceLength) (initialIndex-
750 1)*sliceLength i/4)/
751 (3*iterations*(sliceLength-1))*100) );
752 }
753 }
754 if (entireImage == true || mask.get(a/4) ) {// may have problems
755 // in masking ...
756 row = i/sliceWidth;
757 col = i%sliceWidth;
758 if ( (row < upperBound) || (row > lowerBound) ) {
759 destBuffer[a] = srcBuffer[a]; // row too far up or
760 // down--out of bounds
761 }
762 else if ((col < leftBound) || (col > rightBound)) {
763 destBuffer[a] = srcBuffer[a]; // column too far left
764 // or right--out of bounds
765 }
766 else { // in bounds
767 maskedList = getNeighborList(a, srcBuffer, true);
768 // verify that this element is an outlier
769 if (stdDevLimit == 0.0) { // anything is an outlier
770 shellSort(maskedList);
771 destBuffer[a] = median(maskedList);
772 }
773 else { // look for outlierness
774 average = mean(maskedList);
775 sigma = standardDeviation(maskedList, average);
776 if ((maskedList[kCenter] > (average
777 stdDevLimit*sigma)) ||
778
|- |
779 (maskedList[kCenter] < (average -
780 stdDevLimit*sigma))) {
781 shellSort(maskedList);
782 destBuffer[a] = median(maskedList);
783 }
784 else { // if element was not an outlier, pixel is fine.
785 destBuffer[a] = srcBuffer[a];
786 }
787 }
788 }
789 }
790 else { // not part of the VOI so just copy this into the destination
791 // buffer.
792 destBuffer[a] = srcBuffer[a];
793 }
794 }
795 }
796 a = buffStart; // reset the index back to the beginning of
797 // the filterarea
798 }
799 }
800 else { // monochrome image
801 if (pBarVisible) {
802 progressBar.setMessage("Filtering " msgString " (pass "
803 String.valueOf(pass 1) " of " iterations ") ...");