Java 如何确定两个小缓冲区映像是否重复?

Java 如何确定两个小缓冲区映像是否重复?,java,image-processing,ocr,bufferedimage,Java,Image Processing,Ocr,Bufferedimage,我有一系列小的20x20的BuffereImage,每个都有白色背景和黑色文本,每个BuffereImage包含一个从0到9的数字 我想做的是,简单地相互比较图像,并确定它们是否重复(相等)。例如,如果我比较两个都是“2”的图像,那么我希望它被标记为一个副本。如果其中一个显示为5,那么我希望将其标记为非重复 我想简单地遍历图像的所有像素,获取它们的RBG值并将它们存储在一个字符串中,然后比较每个图像的RBG字符串以确定它们是否重复。这是最好的方法,还是有更好/更快的方法 图像存储在内存中,而不是

我有一系列小的20x20的BuffereImage,每个都有白色背景和黑色文本,每个BuffereImage包含一个从0到9的数字

我想做的是,简单地相互比较图像,并确定它们是否重复(相等)。例如,如果我比较两个都是“2”的图像,那么我希望它被标记为一个副本。如果其中一个显示为5,那么我希望将其标记为非重复

我想简单地遍历图像的所有像素,获取它们的RBG值并将它们存储在一个字符串中,然后比较每个图像的RBG字符串以确定它们是否重复。这是最好的方法,还是有更好/更快的方法


图像存储在内存中,而不是文件系统中,因此我无法真正对其进行md5处理,但是如果md5处理结果准确且速度快,那么我可以将其存储。

您最好为每个数字创建一个缓冲区图像(或ImageIcon,如果需要的话),然后比较是否相等,
==
。否则,您可能需要进行OCR以尝试找到足够接近的匹配项。

您最好为每个数字创建一个缓冲区图像(或图像图标,如果需要的话),然后比较是否相等,
=
。否则,您可能需要进行OCR以尝试找到足够接近的匹配项。

我从

Base64类下载自

我从

Base64类下载自

我想简单地遍历图像的所有像素,获取它们的RBG值并将它们存储在一个字符串中,然后比较每个图像的RBG字符串以确定它们是否重复。这是最好的方法,还是有更好/更快的方法

在字符串中编码和存储像素以及比较字符串是不必要的。如果可以逐像素比较图像,则将其作为像素值数组进行比较。如果成本可以摊销,校验和或散列将是一个很好的加速器。(您可以用Java计算MD5或等效摘要,其中包含可以表示为字节的任何内容!)

然而,真正的问题是简单的像素级比较是否有效。有各种各样的事情可以干扰这一点。你说:

这些图像来自屏幕不同部分的Robot.createScreenCapture()

这意味着:

  • 数字可以是不同的字体
  • 数字可以是相同的字体,但样式或字体大小不同
  • 数字图像可能在20x20图像内未对齐或旋转
  • 数字渲染可以使用抗锯齿,这可能会受到屏幕分辨率等的影响
  • 可能有一些无关的东西;e、 g.如果图像剪辑不正确
  • 可能有背景资料;e、 g.如果不是“纯”白色
如果其中任何一种情况发生,那么简单的逐像素比较将不起作用,您可能需要进行适当的OCR。。。它的所有成本和复杂性

关于JavaOCR软件的建议是离题的。谷歌是你的朋友

我想简单地遍历图像的所有像素,获取它们的RBG值并将它们存储在一个字符串中,然后比较每个图像的RBG字符串以确定它们是否重复。这是最好的方法,还是有更好/更快的方法

在字符串中编码和存储像素以及比较字符串是不必要的。如果可以逐像素比较图像,则将其作为像素值数组进行比较。如果成本可以摊销,校验和或散列将是一个很好的加速器。(您可以用Java计算MD5或等效摘要,其中包含可以表示为字节的任何内容!)

然而,真正的问题是简单的像素级比较是否有效。有各种各样的事情可以干扰这一点。你说:

这些图像来自屏幕不同部分的Robot.createScreenCapture()

这意味着:

  • 数字可以是不同的字体
  • 数字可以是相同的字体,但样式或字体大小不同
  • 数字图像可能在20x20图像内未对齐或旋转
  • 数字渲染可以使用抗锯齿,这可能会受到屏幕分辨率等的影响
  • 可能有一些无关的东西;e、 g.如果图像剪辑不正确
  • 可能有背景资料;e、 g.如果不是“纯”白色
如果其中任何一种情况发生,那么简单的逐像素比较将不起作用,您可能需要进行适当的OCR。。。它的所有成本和复杂性


关于JavaOCR软件的建议是离题的。谷歌是你的朋友。

对于基于OCR的解决方案,你可以使用(通过Java包装器)。该过程可以如下所示:

  • 将缓冲图像缩放到300 DPI
  • 设置为仅识别数字(SetVariable(“tessedit_char_whitelist”,“0123456789”))
  • 将页面分割模式(PSM)设置为10(对于单个字符)
  • 获取可识别的文本

  • 对于基于OCR的解决方案,您可以使用(通过Java包装器)。该过程可以如下所示:

  • 将缓冲图像缩放到300 DPI
  • 设置为仅识别数字(SetVariable(“tessedit_char_whitelist”,“0123456789”))
  • 将页面分割模式(PSM)设置为10(对于单个字符)
  • 获取可识别的文本

  • 仅仅实现对象相等是不可能的。图像来自屏幕的不同部分。请给我一些关于如何进行OCR的建议。@ClickUpvote:我还没有深入研究OCR领域,因此无法给你具体的建议。你知道是否有可能循环使用OCR的像素吗
    import java.awt.Rectangle;
    import java.awt.Robot;
    import java.awt.image.BufferedImage;
    
    import java.io.ByteArrayOutputStream;
    import java.io.OutputStream;
    import javax.imageio.ImageIO;
    
    protected boolean areEqual(BufferedImage img1, BufferedImage img2)
    {
        String str1 = imgToStr(img1);
        String str2 = imgToStr(img2);        
        return str1.equals(str2);
    }
    
    protected String imgToStr(BufferedImage img)
    {
        ByteArrayOutputStream os = new ByteArrayOutputStream();        
        try
        {
            OutputStream b64 = new Base64.OutputStream(os);
             ImageIO.write(img, "png", b64);
            String result = os.toString("UTF-8");   
            return result;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }        
        return "";
    
    }