package pl.wroc.pwr.imagechannel.segmentation; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Queue; import pl.wroc.pwr.IOperator; import pl.wroc.pwr.imagechannel.IImageChannel; import pl.wroc.pwr.imagechannel.basic.CloneChannel; import pl.wroc.pwr.roi.IROI; import pl.wroc.pwr.roi.model.ROIPixels; /** * @author Mariusz Paradowski */ public class SplitSeparate implements IOperator { private static final long serialVersionUID = -6991722997004764666L; private IImageChannel imageChannel; private float threshold; private IImageChannel workingChanel; private List imageSegments; private ROIPixels workingSegment; private Queue positionQueue; private IROI [ ] result; class Pixel { public int x; public int y; public Pixel( int x, int y ) { this.x = x; this.y = y; } @Override public boolean equals( Object obj ) { Pixel p = ( Pixel )obj; return ( ( p.x == this.x )&&( p.y == this.y ) ); } } public SplitSeparate( IImageChannel imageChannel, float threshold ) { this.imageChannel = imageChannel; this.threshold = threshold; //System.out.println("SplitSeparate on " + imageChannel + " with threshold " + threshold); //$NON-NLS-1$ //$NON-NLS-2$ } public SplitSeparate( IImageChannel imageChannel ) { this(imageChannel, 0); } private void checkNextPosition( int x, int y ) { if ( this.workingChanel.inRange( x, y ) ) { Pixel nextPosition = new Pixel( x, y ); double value = this.workingChanel.getValue( x, y ); if ( value > this.threshold ) { if ( !this.positionQueue.contains( nextPosition ) ) { this.positionQueue.add( nextPosition ); } } } } private void process( ) { while ( !this.positionQueue.isEmpty( ) ) { Pixel position = this.positionQueue.poll( ); this.workingChanel.setValue( position.x, position.y, 0 ); this.workingSegment.quickAdd( position.x, position.y ); int x = position.x; int y = position.y; this.checkNextPosition( x - 1, y + 0 ); this.checkNextPosition( x + 1, y + 0 ); this.checkNextPosition( x + 0, y - 1 ); this.checkNextPosition( x + 0, y + 1 ); this.checkNextPosition( x - 1, y - 1 ); this.checkNextPosition( x + 1, y - 1 ); this.checkNextPosition( x - 1, y + 1 ); this.checkNextPosition( x + 1, y + 1 ); } } private void processPixel(int x, int y) { double value = this.workingChanel.getValue( x, y ); if ( value > this.threshold ) { Pixel position = new Pixel( x, y ); this.workingSegment = new ROIPixels( this.imageChannel.getXSize( ), this.imageChannel.getYSize( ) ); this.positionQueue = new LinkedList< Pixel >( ); this.positionQueue.add( position ); this.process( ); this.imageSegments.add( this.workingSegment ); } } public IROI[] apply( ) { this.workingChanel = new CloneChannel(this.imageChannel).apply(); this.imageSegments = new ArrayList(); for (int y = 0; y < this.workingChanel.getYSize(); y++) { for (int x = 0; x < this.workingChanel.getXSize(); x++) { this.processPixel(x, y); } } this.result = new IROI[this.imageSegments.size()]; for (int i = 0; i < this.result.length; i++) { this.result[i] = this.imageSegments.get(i); } return this.result; } }