zoukankan      html  css  js  c++  java
  • 搜索引擎对相似图片搜索识别的原理(一)

        晚上看了阮一峰先生的博客:搜索引擎对相似图片搜索识别的原理,感觉挺有趣,就按着算法写写。唉,本来打算写写spring mvc的,这下一晚上又废了。先记录一下:

    颜色分布法:

        具体原来可以去查看博客,这里不写了。

        包括两个类,第一个是颜色分布法的实现

    import java.awt.image.BufferedImage;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    
    import javax.imageio.ImageIO;
    
    /**
     * 
     * @author Andy
     * date:2013/8/18
     * 颜色分布法
     *将0~255分成四个区:
     *0~63为第0区,64~127为第1区,128~191为第2区,192~255为第3区。
     *这意味着红绿蓝分别有4个区,总共可以构成64种组合(4的3次方)。
     *所以一张图片组成了一个64维向量,这个向量可以视为图片的指纹
     *
     */
    
    public class ColorDistribution {
        private int N=64;
        public int[] vectorValue=new int[64];
        
        public ColorDistribution(){
            
        }
        public void vectorCompute(String imagePath){
            BufferedImage bufferedImage=null;
            try {
                //read the image
                bufferedImage = ImageIO.read(new FileInputStream( imagePath));
                int green, red, blue;
                int imageWidth = bufferedImage.getWidth();
                int imageHeight = bufferedImage.getHeight();
                //deal every pixel
                for (int i = bufferedImage.getMinX(); i < imageWidth; i++) {
                    for (int j = bufferedImage.getMinY(); j < imageHeight; j++) {
                        Object data = bufferedImage.getRaster().getDataElements(i,
                                j, null);
                        red = bufferedImage.getColorModel().getRed(data);
                        green = bufferedImage.getColorModel().getGreen(data);
                        blue = bufferedImage.getColorModel().getBlue(data);
                        vectorValue[zone(red) * 16 + zone(green) * 4 + zone(blue)]++;
                    }
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
     
        }
        //divide to four zones -0,1,2,3
        int zone(int colorValue){
            if(colorValue>=0 && colorValue<=63){
                return 0;
            }else if(colorValue>=64 && colorValue<=127){
                return 1;
            }else if(colorValue>=128 && colorValue<=191){
                return 2;
            }else{
                return 3;
            }
        }
        
        //test
        public static void main(String[] args){
            ColorDistribution cd=new ColorDistribution();
            cd.vectorCompute("C:\Users\red\Desktop\2.jpg");
            int[] a=cd.vectorValue;
            for(int i=0;i<a.length;++i){
                System.out.print(a[i]+" ");
            }
        }
    }

    第二个是皮尔逊积矩相关系数的实现

    /**
     * 皮尔逊积矩相关系数
     * @author Andy
     * date:2013/8/18
     */
    public class PPMCC{
        private double exVector1;//sample mean
        private double exVector2;//sample mean
        private double sxVector1;//sample standard deviation
        private double sxVector2;//sample standard deviation
        
        //mean
        public double mean(int[] v){
            double sum=0;
            for(int i=0;i<v.length;++i){
                sum+=v[i];
            }
            return sum/(v.length);
        }
        //standard deviation
        public double standardDeviation(int[] v,double ex){
            double sx=0;
            for(int i=0;i<v.length;++i){
                double temp=v[i]-ex;
                sx+=temp*temp;
            }
            return Math.sqrt(sx/(v.length-1));
        }
        public double execute(int[] v1,int[] v2){
            int n=0;
            double r=0;
            if(v1.length==v2.length){
                n=v1.length;
            }else{
                return r;
            }
            exVector1=mean(v1);
            exVector2=mean(v2);
            sxVector1=standardDeviation(v1, exVector1);
            sxVector2=standardDeviation(v2, exVector2);
            for(int i=0;i<v1.length;++i){
                r+=((v1[i]-exVector1)/sxVector1)*((v2[i]-exVector2)/sxVector2);
            }
            r/=n-1;
            return r;
        }
        
        
        //test
        public static void main(String[] args){
            ColorDistribution cd1=new ColorDistribution();
            ColorDistribution cd2=new ColorDistribution();
            cd1.vectorCompute("C:\Users\red\Desktop\2.jpg");
            cd2.vectorCompute("C:\Users\red\Desktop\1.jpg");
            PPMCC ppmcc=new PPMCC();
            double r=ppmcc.execute(cd1.vectorValue, cd2.vectorValue);
            System.out.println(r);
        }
    }

    最后说说结果:

       对于同样一张图片的结果,返回的皮尔逊系数是1.0000000000009,也没检查出那里出现了误差。还有就是在windows的画图上用同种颜色的笔画出的两张不同图片比较,结果很接近一,不知道这是算法的问题,还是写的程序代码,有问题,今天太晚了,先记到这。

  • 相关阅读:
    常用坐标系椭球参数整理
    ArcEngine编辑保存错误:Unable to create logfile system tables
    ArcEngine:The XY domain on the spatial reference is not set or invalid错误
    dockManager中DockPanel的刷新问题!
    ibatis实现Iterate的使用
    mongodb用子文档做为查询条件的两种方法
    Eclipse中的文件导航插件StartExplorer
    mongoVUE的增删改查操作使用说明
    什么是脏读,不可重复读,幻读
    转:Maven常用命令
  • 原文地址:https://www.cnblogs.com/redlight/p/3265593.html
Copyright © 2011-2022 走看看