我正在尝试从在线资源中分析基于图像的3位数字验证码。这些数字根本没有动。我使用BufferedImage
的{{1}}方法从验证码中提取每个数字。我已经为每个数十个和数百个位置保存(0-9)。 (所以总共有30个数字)
我将在线图像的getSubimage(...)
读入bytes
,然后创建一个byte[]
对象,如下所示:
BufferedImage
然后,我将该图像与驱动器上的图像列表进行比较:
BufferedImage captcha = ImageIO.read(new ByteArrayInputStream(captchaBytes));
这就是我比较两张图片的方式:
BufferedImage[] nums = new BufferedImage[10];
//Load images into the array here... The code is removed.
for(int i = 0; i < nums.length; i++) {
double x;
System.out.println(x = bufferedImagesEqualConfidence(nums[i], firstNumberImage));
if(x > 0.98) {
System.out.println("equal to image " + i + ".jpeg");
isNewEntry = false;
break;
}
}
完全从包裹在我自己的static double bufferedImagesEqualConfidence(BufferedImage img1, BufferedImage img2) {
double difference = 0;
int pixels = img1.getWidth() * img1.getHeight();
if (img1.getWidth() == img2.getWidth() && img1.getHeight() == img2.getHeight()) {
for (int x = 0; x < img1.getWidth(); x++) {
for (int y = 0; y < img1.getHeight(); y++) {
int rgbA = img1.getRGB(x, y);
int rgbB = img2.getRGB(x, y);
int redA = (rgbA >> 16) & 0xff;
int greenA = (rgbA >> 8) & 0xff;
int blueA = (rgbA) & 0xff;
int redB = (rgbB >> 16) & 0xff;
int greenB = (rgbB >> 8) & 0xff;
int blueB = (rgbB) & 0xff;
difference += Math.abs(redA - redB);
difference += Math.abs(greenA - greenB);
difference += Math.abs(blueA - blueB);
}
}
} else {
return 0.0;
}
return 1-((difference/(double)pixels) / 255.0);
}
对象中的HttpURLConnection
对象加载图像。因此,我这样做:HttpGet
之所以有用,是因为保存byte[] captchaBytes = hg.readAndGetBytes();
时,它将保存为驱动器上的有效映像。
但是,即使2张图像实际上是相同的,结果也显示它们根本不相似。但是,当我保存从网上资源下载的图像时,请重新阅读并进行比较,表明它们是相等的。当我说要保存并重新阅读时,这就是我正在做的事情:
BufferedImage captcha = ImageIO.read(new ByteArrayInputStream(captchaBytes));
图片格式:File temp = new File("temp.jpeg");
ImageIO.write(secondNumberImage, "jpeg", temp);
secondNumberImage = ImageIO.read(temp);
我知道这可能与JPEG
中的压缩有关,但是如何制作它,这样我就不必保存图像了?
答案 0 :(得分:0)
问题出在我的bufferedImagesEqualConfidence
方法内。仅仅比较RGB是不够的。我不得不比较各个R / G / B值。
我最初的bufferedImagesEqualConfidence
无效:
static double bufferedImagesEqualConfidence(BufferedImage img1, BufferedImage img2) {
int similarity = 0;
int pixels = img1.getWidth() * img1.getHeight();
if (img1.getWidth() == img2.getWidth() && img1.getHeight() == img2.getHeight()) {
for (int x = 0; x < img1.getWidth(); x++) {
for (int y = 0; y < img1.getHeight(); y++) {
if (img1.getRGB(x, y) == img2.getRGB(x, y)) {
similarity++;
}
}
}
} else {
return 0.0;
}
return similarity / (double)pixels;
}
(来源:Java Compare one BufferedImage to Another)
起作用的bufferedImagesEqualConfidence
是:
static double bufferedImagesEqualConfidence(BufferedImage img1, BufferedImage img2) {
double difference = 0;
int pixels = img1.getWidth() * img1.getHeight();
if (img1.getWidth() == img2.getWidth() && img1.getHeight() == img2.getHeight()) {
for (int x = 0; x < img1.getWidth(); x++) {
for (int y = 0; y < img1.getHeight(); y++) {
int rgbA = img1.getRGB(x, y);
int rgbB = img2.getRGB(x, y);
int redA = (rgbA >> 16) & 0xff;
int greenA = (rgbA >> 8) & 0xff;
int blueA = (rgbA) & 0xff;
int redB = (rgbB >> 16) & 0xff;
int greenB = (rgbB >> 8) & 0xff;
int blueB = (rgbB) & 0xff;
difference += Math.abs(redA - redB);
difference += Math.abs(greenA - greenB);
difference += Math.abs(blueA - blueB);
}
}
} else {
return 0.0;
}
return 1-((difference/(double)pixels) / 255.0);
}
我猜想要找到两幅图像之间的相似性,您必须比较每个像素的单个R / G / B值,而不仅仅是整个RGB值。