0

Let me explain my issue. I have a service that does some mathematic calculations ( very very difficult ). It is some sort of statistic calculations. This service returns two-dimensional array of booleans ( boolean [][] 400x400). After i am create an image corresponding to this array:

BufferedImage im = new BufferedImage( area.length, area.length, BufferedImage.TYPE_INT_RGB );
Graphics2D g2 = in.createGraphics();
g2.setColor( Color.BLACK);
for ( int i = 0; i < area.length; i++ ) {
   for ( int j = 0; j < area.length; j++ ) {
      if ( area[ i ][ j ] ) {
           g2.fillRect( j, i, 1, 1 );
      }            
   }
}
ImageIO.write( im, someformat, somefile );

enter image description here

The code is pretty simple. And as a result i am create Pic1 ( see attached file ). Yellow border is just for example as well as yellow points ( image pixels ). Also i want to show you some content of boolean array ( it is only example and i will print true as 1 and false as 0 ):

{ 0,.0,.............   .... ............0    }
 ....................   ...
{ 0,0,0,0,0,1,1,....   .... ............0    }
{ 0,0,0,1,1,0,1,....   .... ............0    }
{ 0,0,1,1,0,0,0,1,1,   .... ............0    }
{ 0,0,0,1,0,0,0,1,0,   .... ............0    }
 ..................................
{ 0,.0,.............   .... ............0    }

So as a result i have as i said Pic1. Yes i know this picture looks very strange. In practice it can be whatever shape but it always will be closed. This image looks very ugly and instead i want to draw it like some curve line with some width and without any roughness. I am tried to show it on Pic2 ( yeah..... it is also ugly.... my drawing is bad ).

My skills and knowledges in image processing is bad and i definetly need help and clarifications. May be it is not possible to achieve my goal using Java at all. I don't know. May be there is some library or something else that can help me.

I will apreciate for any response and help, thanks.

  • 1
    You can consider "1"s at [i,j] as points (x = j, y = i) and use series of Bezier curves or splines to interpolate it. – loginpassword Oct 25 '16 at 19:31
  • It's easy to press "-1" but can you little bit extend your answer with example ? And i give array example because around points that have value "1" there are also points that have value "1" and problem also is that i didn't know order. of these points. In this array i don't know point that followed by selected [ i,j ] point. I am trying to solve my issue but not increase my rating. – Alexander Khromov Oct 25 '16 at 20:56

2 Answers2

0

I think that you want to do the same thing that this technique MSGPR (or see here), which is a multi-scale smoothing matching contour technique.

So basically the authors consider the pattern contour as a parametric equation. Then they smooth separately the curves x[t] and y[t] with a gaussian filter. The more you smooth, the simpler the contour.

FiReTiTi
  • 5,597
  • 12
  • 30
  • 58
0

According to FiReTiTi answer i am spend some time for research and finally found solution.
So i found two similar questions first post and second post. Both of them relates to opencv library.
After reading some of opencv documentation i am resolve my issue just adding next lines to my above code:

    g2.dispose();
    BufferedImage result = new BufferedImage( im.getHeight(), im.getWidth(), TYPE_INT_RGB );
    g2.createGraphics();

    Mat src = new Mat( im.getHeight(), im.getWidth(), CvType.CV_8UC1 );
    src.put( 0, 0, ( ( DataBufferByte ) im.getRaster().getDataBuffer() ).getData() );
    List< MatOfPoint > contours = new ArrayList<>();
    Imgproc.findContours( src, contours, new Mat(), Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE, new Point( 0, 0 ) );

     for ( MatOfPoint point: contours ) {

          MatOfPoint2f source = new MatOfPoint2f();
          point.convertTo( source, CvType.CV_32F );
          MatOfPoint2f gb= new MatOfPoint2f();
          Imgproc.GaussianBlur( source, gb, new Size( 3, 3 ), 0, 0 );
          Polygon polygon = new Polygon();
          gb.toList().stream().forEach( p -> polygon.addPoint( ( int ) p.x, ( int ) p.y ) );
          g2.setColor( Color.WHITE);
          g2.drawPolygon( polygon );
     }

     ImageIO.write( result, format, file );
Community
  • 1
  • 1