Kir*_*ril 5 java graphics image-manipulation image-processing
我想知道是否存在基于某些特征分割图像的"智能"方式.
图像是300x57,黑色和白色(实际上是灰度,但大多数颜色是黑色或白色),它由两个主要特征(让我们称之为斑点)组成,由黑色空间分隔,每个斑点的宽度和高度略有不同,斑点的位置也各不相同,斑点永远不会重叠!
这是图像"看起来"的样子:
-------------------------
----WWW---------WWWWW----
---WWWWWWW----WWWWWW-----
-----WWWW-------WWW------
-------------------------
Run Code Online (Sandbox Code Playgroud)
由此产生的分裂将是这样的:
------------ -------------
----WWW----- ----WWWWW----
---WWWWWWW-- --WWWWWW-----
-----WWWW--- ----WWW------
------------ -------------
Run Code Online (Sandbox Code Playgroud)
我计划采取的步骤,以分割图像:
如果我规范化图像宽度会很好,所以我的所有图像在保存时都具有统一的宽度.
我没有图像处理的经验,所以我不知道这是一种有效的方法.我目前正在使用BufferedImage,获取宽度/高度,迭代每个像素等等.我的问题没有错误的解决方案,但我正在寻找更高效的解决方案(更少代码+更快).我也一直在研究java.awt.Graphics ......
如果我能找到更有效的方法来完成这项任务,我将不胜感激.我想坚持使用Java的内置库,在这种情况下,BufferedImage或Graphics2D是最有效的吗?
编辑:这是阅读建议后的代码:
public void splitAndSaveImage( BufferedImage image ) throws IOException
{
// Process image ------------------------------------------
int height = image.getHeight();
int width = image.getWidth();
boolean edgeDetected = false;
double averageColor = 0;
int threshold = -10;
int rightEdge = 0;
int leftEdge = 0;
int middle = 0;
// Scan the image and determine the edges of the blobs.
for(int w = 0; w < width; ++w)
{
for(int h = 0; h < height; ++h)
{
averageColor += image.getRGB(w, h);
}
averageColor = Math.round(averageColor/(double)height);
if( averageColor /*!=-1*/< threshold && !edgeDetected )
{
// Detected the beginning of the right blob
edgeDetected = true;
rightEdge = w;
}else if( averageColor >= threshold && edgeDetected )
{
// Detected the end of the left blob
edgeDetected = false;
leftEdge = leftEdge==0? w:leftEdge;
}
averageColor = 0;
}
// Split the image at the middle of the inside distance.
middle = (leftEdge + rightEdge)/2;
// Crop the image
BufferedImage leftImage = image.getSubimage(0, 0, middle, height);
BufferedImage rightImage = image.getSubimage(middle, 0, (width-middle), height);
// Save the image
// Save to file -------------------------------------------
ImageIO.write(leftImage, "jpeg", new File("leftImage.jpeg"));
ImageIO.write(rightImage, "jpeg", new File("rightImage.jpeg"));
}
Run Code Online (Sandbox Code Playgroud)
一种简单的方法是将每列中的像素值相加(向下)以创建平均值的单个数组(与输入图像的宽度相同).从数组中间开始,搜索最小值.这将是您可以拆分图像的列.
此列可能不会是blob之间差距的中心.您可以从此列进行另一次向外搜索,向左移动以查找所有类似的列,然后向右移动.
-------------------------
----WWW---------WWWWW----
---WWWWWWW----WWWWWW-----
-----WWWW-------WWW------
-------------------------
Run Code Online (Sandbox Code Playgroud)
col avg:
---wwWWwww-----wWWWWww---
Run Code Online (Sandbox Code Playgroud)
根据两个blob之间空白的空白(像素值),您可以将阈值设置得相当低.如果有一些噪音,它必须要高一点.
找到正确的阈值可能是一件苦差事,除非您可以通过算法确定它.
| 归档时间: |
|
| 查看次数: |
4026 次 |
| 最近记录: |