Java图片相似度,图像识别

该博客介绍了如何使用Java进行图片相似度比较,提供了具体的代码实现。通过将图片转换为二进制码并分析像素点的相似度来判断两张图片是否匹配。注意,这种方法要求图片的大小、分辨率和像素值完全一致。
摘要由CSDN通过智能技术生成

Java图片相似对比实例

package com.icss.main;

import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;

import sun.misc.BASE64Decoder;

/**

  • 比较两张图片的相似度,这里准确匹配方案

  • 原因是:两张图片必须大小一样,分辨率必须一样,像素大小一样,这就决定了如果存在模糊程度,分辨率问题,就不能匹配,

  • 百度那边做了这样的设定,设置不同模糊程度,再继续对比,完成更人性化的操作
    */
    public class SimilarityComparer {
    // 改变成二进制码, //这里表示的像素,每一像素取点,返回颜色的值
    private static String[][] getPX(BufferedImage image) {
    int[] rgb = new int[3];
    int width = image.getWidth();
    //这里表示的像素,每一像素取点,返回颜色的值

     int height = image.getHeight();
     int minx = image.getMinX();
    
     int miny = image.getMinY();
     String[][] list = new String[width][height];
     
     for (int i = minx; i < width; i++) {
         for (int j = miny; j < height; j++) {
         	//这里当流读取对象的时候,把一个点的三原色封装成一个整数,这里进行反向取值,光色分解成三原色,rgb,就是红绿蓝,三原色可以组成任何颜色
             int pixel = image.getRGB(i, j);
             //红色值反向解析
             rgb[0] = (pixel & 0xff0000) >> 16;
         	//绿色值反向解析
             rgb[1] = (pixel & 0xff00) >> 8;
             //蓝色值反向解析
             rgb[2] = (pixel & 0xff);
             list[i][j] = rgb[0] + "," + rgb[1] + "," + rgb[2];
            
         }
     }
    
     return list;
    

    }

    //匹配点阵像素相似度
    public static boolean compareImage(BufferedImage image1, BufferedImage image2) {
    boolean result = false;
    // 分析图片相似度 begin
    String[][] list1 = getPX(image1);
    String[][] list2 = getPX(image2);
    //这里double预防溢出,内存,记录比较次数
    double count=0;
    int xiangsi = 0;
    int busi = 0;
    int length=list1.length;
    int lengthin = list1[1].length;

     for (int i = 0; i < length; i++) {
     	//这里没有看明白要来干嘛,好像永远不成立
     	if ((i + 1) == list1.length) {
             continue;
         }
         for (int j = 0; j < lengthin; j++) {          	
             try {
                 String[] value1 = list1[i][j].toString().split(",");
                 String[] value2 = list2[i][j].toString().split(",");
                 
                 for (int n = 0; n < value2.length; n++) { 
                 	count++;
                 	//相似度设置,根据实际需求设定图片相似程度,这里设置为5相似度极高像素的±偏差允许范围
                     if (Math.abs(Integer.parseInt(value1[n]) - Integer.parseInt(value2[n])) < 5) {
                         xiangsi++;
                     } else {
                         busi++;
                     }
                 }
             } catch (RuntimeException e) {
                 continue;
             }
             
         }
         
     }
     //这里采用正反比较两次
     list1 = getPX(image2);
     list2 = getPX(image1);
     for (int i = 0; i < length; i++) {
     	//这里没有看明白要来干嘛,好像永远不成立
     	if ((i + 1) == list1.length) {
             continue;
         }
         for (int j = 0; j < lengthin; j++) {          	
             try {
                 String[] value1 = list1[i][j].toString().split(",");
                 String[] value2 = list2[i][j].toString().split(",");
                
                 for (int n = 0; n < value2.length; n++) {
                 	count++;
                 	//相似度设置,根据实际需求设定图片相似程度,这里设置为5相似度极高,像素的±偏差允许范围
                     if (Math.abs(Integer.parseInt(value1[n]) - Integer.parseInt(value2[n])) < 5) {
                         xiangsi++;
                     } else {
                         busi++;
                     }
                 }
             } catch (RuntimeException e) {
                 continue;
             }
             
         }
     }
     double redio=busi/count;
     double radio=xiangsi/count;
    System.out.println("不相似的次数"+busi+"=========不相似率"+redio*100+"%");
    System.out.println("相似的次数"+xiangsi+"=========相似率"+radio*100+"%");
     if (radio*100>=80) {
         result = true;
     }
     return result;
    

    }

    public static void main(String[] args) throws IOException, AWTException {

     BufferedImage img01 = ImageIO.read(new File("E:/img01.jpg"));
    
     
     //用64位读取图片,获取数据
     //byte[] decodeBuffer2 = base64Decoder.decodeBuffer(new FileInputStream("E:/img02.jpg"));
     //装配到字节数组流中
     //InputStream stream2 = new ByteArrayInputStream(decodeBuffer2);
     /**
      * 对比图片的时候,必须保证图片像素相同,否则无法匹配,20K以内,大概2miao
      * 当图片太大的时候,比较时间越长,5M图片比较,需要一分多钟
      */
     BufferedImage img02 = ImageIO.read(new File("E:/img02.jpg"));
     long time = new Date().getTime();
     System.out.println("开始匹配");
     System.out.println(SimilarityComparer.compareImage(img01, img02));
     
     System.out.println("匹配耗时"+(new Date().getTime()-time));
    
     /**
      * java截屏工具,并输出
      */
     /*Robot rb = null; // java.awt.image包中的类,可以用来抓取屏幕,即截屏。
     rb = new Robot();
     //这里截屏工具
     Toolkit tk = Toolkit.getDefaultToolkit(); // 获取缺省工具包
     Dimension di = tk.getScreenSize(); // 屏幕尺寸规格
     System.out.println(di.width);
     System.out.println(di.height);
     Rectangle rec = new Rectangle(0, 0, di.width, di.height);
     BufferedImage bi = rb.createScreenCapture(rec);
     //输出截屏
     OutputStream os = new FileOutputStream("E:/test.jpg");
     ImageIO.write(bi, "jpg", os);*/
    

    }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值