java - Find perimeter of the image binary object -


i trying find perimeter of binary object.

consider following picture

[ 0 0 0 0 1 1 0 ] [ 0 0 1 0 0 0 0 ] [ 0 1 1 0 1 1 0 ] [ 0 1 1 0 0 1 0 ] [ 0 1 1 1 0 0 0 ] [ 0 1 0 0 1 1 0 ] [ 0 0 0 0 1 1 0 ] 

labeled image this

[ 0 0 0 0 1 1 0 ] [ 0 0 2 0 0 0 0 ] [ 0 2 2 0 3 3 0 ] [ 0 2 2 0 0 3 0 ] [ 0 2 2 0 0 0 0 ] [ 0 2 0 0 4 4 0 ] [ 0 0 0 0 4 4 0 ] 

also collected each object pixels in array list

so example 4 marked object list

{ (5,4), (5,5) , (6,4), (6,5) } 

area size of each object pixel array, how can find perimeter, should again iterate on whole image finding neighbors of cell check if corner pixel of object or there easier way basing on coordinates.

please suggest easier way find perimeter, code example highly appreciated

try doing a breadth-first search of image, (or alternatively iterate through list of points), , tag every pixel neighbors pixel isn't of same group.

it's not clear me if perimeter want every pixel on outside edge of requested object, or every pixel borders object. i'll assume former now.

set image:

here's how you'd go doing this. first, set image 2-d array, each pixel labeled group number:

[ 0 0 0 0 1 1 0 ] [ 0 0 2 0 0 0 0 ] [ 0 2 2 0 3 3 0 ] [ 0 2 2 0 0 3 0 ] [ 0 2 2 0 0 0 0 ] [ 0 2 0 0 4 4 0 ] [ 0 0 0 0 4 4 0 ] 

a way load use scanner object each point, 1 one:

list<point> points = new arraylist<>(); scanner scanner = new scanner( /* whatever input source */ ); string pointregex = "\\(\\d,\\d\\)"; //looks "(#,#)" while(!scanner.hasnext(pointregex)){     string pointtext = scanner.next(pointregex); //for example, "(5,4)"     point point = getpointfromtext(pointtext); //turns string point     points.add(point); } 

notice use of scanner.next(string pattern). method return next string looks pattern. (read on regular expressions if want learn more how works.)

now on populating grid:

boolean[][] binaryimage = new boolean[width][height]; for(point p : points){ //iterate through each point inside our list of point objects     binaryimage[p.getx()][p.gety()] = true; } 

this puts object, represented our collection of point objects "points", grid of booleans. need worry 1 object, don't need load of others. finding out points on perimeter.

recursive method:

boolean[][] visitedbefore = new boolean[width][height]; boolean[][] isonperimeter = new boolean[width][height]; int[] deltax = {-1,  0,  1, -1, 1, -1, 0, 1},       deltay = {-1, -1, -1,  0, 0,  1, 1, 1}; queue<point> searchnext = new linkedlist<>(); searchnext.add(points.get(0)); //just need 1 point going while(!searchnext.isempty()){     point p = searchnext.remove(); //take what's waiting @ front of queue     if(visitedbefore[p.getx()][p.gety()]){         continue; //already check spot!     }      //mark we've been here     visited[p.getx()][p.gety()] = true;      //look @ of point's neighbors     for(int = 0 ; < deltax.length ; i++){         int newx = p.getx() + deltax[i];         int newy = p.gety() + deltay[i];          //make sure isn't out of bounds         if(newx < 0 || newx >= width || newy<0 || newy>=height){             isonperimeter[p.getx()][p.gety()] = true; //if decide bordering edge of image counts being on perimeter             continue;         }          //check if new point we're considering isn't part of image         if( binaryimage[p.getx()][p.gety()] != binaryimage[newx][newy] ){             //if isn't, point p must on perimeter             isonperimeter[p.getx()][p.gety()] = true;         } else {             /* otherwise, new point we're considering part of              * same object, , part of perimeter. */             searchnext.add(new point(newx, newy));         }     } } 

now have grid each point on perimeter marked true. if need these list, picking out points easy:

list<point> perimeter = new arraylist<point>(); for(int x = 0 ; x < isonperimeter.length ; x++)     for(int y = 0 ; y < isonperimeter[x].length ; y++)         perimeter.add( new point(x,y) ); 

iterative method:

this pretty similar above, jumps straight putting perimeter points list.

int[] deltax = {-1,  0,  1, -1, 1, -1, 0, 1},       deltay = {-1, -1, -1,  0, 0,  1, 1, 1}; outer: for(point p : points){     inner: for(int = 0 ; < deltax.length ; i++){         int newx = p.getx() + deltax[i];         int newy = p.gety() + deltay[i];         //check if new point we're considering outside image         if(newx < 0 || newx >= width || newy<0 || newy>=height){             perimeter.add(p); //if decide bordering edge of image counts being on perimeter             continue outer;         }          //check if new point we're considering isn't part of image         if( binaryimage[p.getx()][p.gety()] != binaryimage[newx][newy] ){             //if isn't, point p must on perimeter             perimeter.add(p);             continue outer;         }     } } 

notice labels outer: , inner:. lets choose loop skip along when continue outer;.

there go! should perimeter of object either binary image or list.


Comments