如何平滑或处理代表闭合线的图像像素?

时间:2016-10-25 19:19:33

标签: java image bufferedimage graphics2d

让我解释一下我的问题。我有一项服务,可以进行一些数学计算(非常非常困难)。这是某种统计计算。此服务返回二维布尔数组(boolean [] [] 400x400)。在我创建对应于此数组的图像后:

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

代码非常简单。结果我创建了Pic1(参见附件)。例如,黄色边框以及黄色点(图像像素)。 此外,我想向您展示一些布尔数组的内容(它只是示例,我将打印为1,假为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    }

因此,正如我所说,Pic1。是的我知道这张照片看起来很奇怪。在实践中,它可以是任何形状,但它总是会被关闭。这个图像看起来非常难看,而我想把它绘制成一些宽度没有任何粗糙度的曲线。我试图在Pic2上展示它(是的.....它也很丑......我的画很糟糕)。

我在图像处理方面的技能和知识很差,我绝对需要帮助和澄清。可能根本无法使用Java实现我的目标。我不知道。可能有一些图书馆或其他可以帮助我的东西。

我会感谢任何回复和帮助,谢谢。

2 个答案:

答案 0 :(得分:0)

我认为你想要做同样的事情MSGPR(或see here),这是一种多尺度平滑匹配轮廓技术。

因此,作者基本上将模式轮廓视为parametric equation。然后,它们用高斯滤波器分别平滑曲线x [t]和y [t]。平滑越多,轮廓越简单。

答案 1 :(得分:0)

根据FiReTiTi的回答,我花了一些时间进行研究,最后找到了解决方案 所以我发现了两个类似的问题first postsecond post。它们都与opencv库有关 阅读了一些opencv文档后,我解决了我的问题,只需在上面的代码中添加下一行:

    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 );