src/main/java/sc/fiji/pQCT/utils/Tools.java
public static byte[] fillHoles(byte[] a, int width, int height, byte filVal){
		final int[][] fourconnectedNHood = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
		byte[] temp = new byte[a.length];
		//look for first non foreground pixel
		boolean keepGoing = true;
		int i= 0,j=0;
		while (true){
			if (a[i+j*width]==0){
				break;
			}else{
				++i;
				if (i>=width){
					++j;
					i=0;
					if (j>=height){
						return a;	//All filled input
					}
				}
			}
		}
		//Start filling form i,j
		ArrayList<Integer> iQueue = new ArrayList<Integer>();
		ArrayList<Integer> jQueue = new ArrayList<Integer>();
		iQueue.add(i);
		jQueue.add(j);
		//Fill from the initial point
		while (!iQueue.isEmpty()) {

			i = iQueue.remove(iQueue.size() - 1);
			j = jQueue.remove(jQueue.size() - 1);

			if (temp[i + j * width] == 0) {
				temp[i + j * width] = 1;
			}

			// Check 4-connected neighbours
			for (final int[] aFourconnectedNHood : fourconnectedNHood) {
				if (i+ aFourconnectedNHood[0]>=0 && j+aFourconnectedNHood[1]>= 0 
					&& i+ aFourconnectedNHood[0]<width && j+aFourconnectedNHood[1]<height){
					if(a[i + aFourconnectedNHood[0] + (j+aFourconnectedNHood[1]) * width] == 0 
						&&	temp[i + aFourconnectedNHood[0] + (j+aFourconnectedNHood[1]) * width] == 0){
						iQueue.add(i + aFourconnectedNHood[0]);
						jQueue.add(j + aFourconnectedNHood[1]);
					}
				}

			}

		}
		
		//Fill in the original sieve
		for (j = 0; j<height;++j){
			for (i = 0; i<width;++i){
				if (temp[i+j*width] == 0){
					a[i+j*width] = filVal;
				}
			}
		}
		return a;
	}
//Hole-filling algorithm. Only works, if objects do not touch the borders of the image.
Hole-filling algorithm. Only works, if objects do not touch the borders of the image.
Hole - filling algorithm . Only works if objects do not touch the borders of the image .
public static byte[] fillHoles(byte[] a, int width, int height, byte filVal){
		final int[][] fourconnectedNHood = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
		byte[] temp = new byte[a.length];
		boolean keepGoing = true;
		int i= 0,j=0;
		while (true){
			if (a[i+j*width]==0){
				break;
			}else{
				++i;
				if (i>=width){
					++j;
					i=0;
					if (j>=height){
						return a;	
					}
				}
			}
		}
		ArrayList<Integer> iQueue = new ArrayList<Integer>();
		ArrayList<Integer> jQueue = new ArrayList<Integer>();
		iQueue.add(i);
		jQueue.add(j);
		while (!iQueue.isEmpty()) {
			i = iQueue.remove(iQueue.size() - 1);
			j = jQueue.remove(jQueue.size() - 1);
			if (temp[i + j * width] == 0) {
				temp[i + j * width] = 1;
			}
			for (final int[] aFourconnectedNHood : fourconnectedNHood) {
				if (i+ aFourconnectedNHood[0]>=0 && j+aFourconnectedNHood[1]>= 0 
					&& i+ aFourconnectedNHood[0]<width && j+aFourconnectedNHood[1]<height){
					if(a[i + aFourconnectedNHood[0] + (j+aFourconnectedNHood[1]) * width] == 0 
						&&	temp[i + aFourconnectedNHood[0] + (j+aFourconnectedNHood[1]) * width] == 0){
						iQueue.add(i + aFourconnectedNHood[0]);
						jQueue.add(j + aFourconnectedNHood[1]);
					}
				}
			}
		}
		for (j = 0; j<height;++j){
			for (i = 0; i<width;++i){
				if (temp[i+j*width] == 0){
					a[i+j*width] = filVal;
				}
			}
		}
		return a;
	}
public static byte [ ] fillHoles ( byte [ ] a , int width , int height , byte filVal ) { final int [ ] [ ] fourconnectedNHood = { { - 1 , 0 } , { 1 , 0 } , { 0 , - 1 } , { 0 , 1 } } ; byte [ ] temp = new byte [ a . length ] ; boolean keepGoing = true ; int i = 0 , j = 0 ; while ( true ) { if ( a [ i + j * width ] == 0 ) { break ; } else { ++ i ; if ( i >= width ) { ++ j ; i = 0 ; if ( j >= height ) { return a ; } } } } ArrayList < Integer > iQueue = new ArrayList < Integer > ( ) ; ArrayList < Integer > jQueue = new ArrayList < Integer > ( ) ; iQueue . add ( i ) ; jQueue . add ( j ) ; while ( ! iQueue . isEmpty ( ) ) { i = iQueue . remove ( iQueue . size ( ) - 1 ) ; j = jQueue . remove ( jQueue . size ( ) - 1 ) ; if ( temp [ i + j * width ] == 0 ) { temp [ i + j * width ] = 1 ; } for ( final int [ ] aFourconnectedNHood : fourconnectedNHood ) { if ( i + aFourconnectedNHood [ 0 ] >= 0 && j + aFourconnectedNHood [ 1 ] >= 0 && i + aFourconnectedNHood [ 0 ] < width && j + aFourconnectedNHood [ 1 ] < height ) { if ( a [ i + aFourconnectedNHood [ 0 ] + ( j + aFourconnectedNHood [ 1 ] ) * width ] == 0 && temp [ i + aFourconnectedNHood [ 0 ] + ( j + aFourconnectedNHood [ 1 ] ) * width ] == 0 ) { iQueue . add ( i + aFourconnectedNHood [ 0 ] ) ; jQueue . add ( j + aFourconnectedNHood [ 1 ] ) ; } } } } for ( j = 0 ; j < height ; ++ j ) { for ( i = 0 ; i < width ; ++ i ) { if ( temp [ i + j * width ] == 0 ) { a [ i + j * width ] = filVal ; } } } return a ; }
Hole-filling algorithm.
Hole - filling algorithm .
//look for first non foreground pixel //All filled input //Start filling form i,j //Fill from the initial point // Check 4-connected neighbours //Fill in the original sieve