boofcv.alg.segmentation.watershed.RemoveWatersheds Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of boofcv-feature Show documentation
Show all versions of boofcv-feature Show documentation
BoofCV is an open source Java library for real-time computer vision and robotics applications.
/*
* Copyright (c) 2011-2017, Peter Abeles. All Rights Reserved.
*
* This file is part of BoofCV (http://boofcv.org).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package boofcv.alg.segmentation.watershed;
import boofcv.struct.image.GrayS32;
import org.ddogleg.struct.GrowQueue_I32;
/**
* Examines a segmented image created by {@link WatershedVincentSoille1991} and merged watershed pixels
* into neighboring regions. Since there is no good rule for which region the pixel should be
* merged into, it is merged into the first valid one.
*
* @author Peter Abeles
*/
public class RemoveWatersheds {
// relative indexes of connected pixels
private int connect[] = new int[4];
// list of watershed pixels which have yet to be merged.
private GrowQueue_I32 open = new GrowQueue_I32();
private GrowQueue_I32 open2 = new GrowQueue_I32();
/**
* Removes watersheds from the segmented image. The input image must be the entire original
* segmented image and assumes the outside border is filled with values < 0. To access
* this image call {@link boofcv.alg.segmentation.watershed.WatershedVincentSoille1991#getOutputBorder()}.
* Each watershed is assigned the value of an arbitrary neighbor. 4-connect rule is used for neighbors.
* Doesn't matter if initial segmented was done using another connectivity rule. The value of each region i
* s reduced by one at the very end.
*
* @param segmented Entire segmented image (including border of -1 values) with watersheds
*/
public void remove( GrayS32 segmented ) {
// very quick sanity check
if( segmented.get(0,0) >= 0 )
throw new IllegalArgumentException("The segmented image must contain a border of -1 valued pixels. See" +
" JavaDoc for important details you didn't bother to read about.");
open.reset();
connect[0] = -1;
connect[1] = 1;
connect[2] = segmented.stride;
connect[3] = -segmented.stride;
// step through the inner pixels and find watershed pixels
for( int y = 1; y < segmented.height-1; y++ ) {
int index = y*segmented.stride + 1;
for( int x = 1; x < segmented.width-1; x++ , index++ ) {
if( segmented.data[index] == 0 ) {
open.add( index );
}
}
}
// assign region values to watersheds until they are all assigned
while( open.size != 0 ) {
open2.reset();
for( int i = 0; i < open.size; i++ ) {
int index = open.get(i);
// assign it to the first valid region it finds
for( int j = 0; j < 4; j++ ) {
// the outside border in the enlarged segmented image will have -1 and watersheds are 0
int r = segmented.data[index+connect[j]];
if( r > 0 ) {
segmented.data[index] = r;
break;
}
}
// see if it was not assigned a region
if( segmented.data[index] == 0 ) {
open2.add(index);
}
}
// swap open and open2
GrowQueue_I32 tmp = open;
open = open2;
open2 = tmp;
}
// watershed pixels have a value of 0 and have been removed. So change the region ID numbers by 1
for( int y = 1; y < segmented.height-1; y++ ) {
int index = y*segmented.stride + 1;
for( int x = 1; x < segmented.width-1; x++ , index++ ) {
segmented.data[index]--;
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy