有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用图像进行java相似图像搜索

我正在做一个项目,在这个项目中,两张图片将被检查相似性,比如“谷歌图片搜索”

我在谷歌上搜索,也在包括stackoverflow在内的多个网站上搜索,了解了各种技术,如直方图、sift、傅立叶变换、像素抓取等。

作为这一领域的初学者,事情太复杂了,我无法理解

我的问题是:

  1. 我可以从哪里开始??是否有任何书籍或网站提供学习如何实际使用这些技术的教程

  2. 是否有新的技术可以用于此目的

我想开始通过颜色搜索图像,如果可能的话,以后再搜索其他属性

首选Java语言

在这个话题上也有类似的线索,但它是多年前写的


共 (3) 个答案

  1. # 1 楼答案

    这取决于你的用例。这些图片是通用的,还是在相似的照明条件和视角下拍摄的


    这些方法可以根据模型的复杂性进行分类。本质上,我们可以区分直接方法和基于特征的方法

    直接(或基于强度的)方法试图(迭代地)通过最小化基于重叠区域的强度差的误差函数来估计相似性。每个图像必须以相同的比例、视角等完全代表相同的场景,以便重叠。相似性度量可以通过计算和平方差(SSD)或ZSSD、相关系数(CC)、互信息(MI)和相关比(RC)来实现

    直接方法可能很有用,例如检查新的视频压缩算法的工作情况。请看下面的文章:

    http://docs.opencv.org/trunk/doc/tutorials/highgui/video-input-psnr-ssim/video-input-psnr-ssim.html


    另一方面,我们可以讨论基于特征的方法。他们试图在点、线或其他几何实体之间建立对应关系,以估计摄像机参数。当图像的结构单元(像素)不包含有关其内容的足够信息时,它们可能很有用。因此,基于特征的方法试图用数学特征(n维向量)来表示图像内容,然后使用分类器来比较这些特征,以获得关于它们相似性的度量

  2. # 2 楼答案

    我只是参考了@Alex代码,并添加了一些其他方法,从位置获取所有特定文件,并逐个处理图像

    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import javax.imageio.ImageIO;
    
    public class ImageSearch {
    
        static HashMap<String, BufferedImage> imgMap = new HashMap<>();
    
        public static void main(String imgToFind, String...img2)throws IOException{
            System.out.println("---------------------Images is processing--------------------- ");
            search("path/to/images");
            System.out.println("----------------------Images processing is completed--------------------- ");
            System.out.println("----------------------Searching Images---------------------");
            System.out.println("Wiiner is :"+findImage(imgMap,getThumbnil(imgToFind)));
        }
    
    
        public static void search(String path) throws IOException{
    
            File file = new File(path);
            File[] fArray = file.listFiles();
    
            for (File f : fArray) {
    
                if (!f.isDirectory()) {
                    if(f.getAbsolutePath().toUpperCase().endsWith(".JPG")){
                        BufferedImage bufImage = getThumbnil(f.getAbsolutePath());
                        imgMap.put(f.getAbsolutePath(), bufImage);
                    }
    
                }
    
                if (f.isDirectory()) {
                    search(f.getAbsolutePath());
                }
    
            }
    
        }
    
    
        public static BufferedImage getThumbnil(String imgSrc) throws IOException{
            BufferedImage img = ImageIO.read(new File(imgSrc));
            Image thumbnail = img.getScaledInstance(8, 8, Image.SCALE_AREA_AVERAGING);
            return toBufferedImage(thumbnail);
        }
    
    
        public static BufferedImage toBufferedImage(Image img)
        {
            if (img instanceof BufferedImage)
            {
                return (BufferedImage) img;
            }
    
            // Create a buffered image with transparency
            BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
    
            // Draw the image on to the buffered image
            Graphics2D bGr = bimage.createGraphics();
            bGr.drawImage(img, 0, 0, null);
            bGr.dispose();
    
            // Return the buffered image
            return bimage;
        }
    
        public static String findImage(HashMap<String, BufferedImage> imgMap, BufferedImage needle) {
    
            double lastDiff = Double.MAX_VALUE;
            BufferedImage winner = null;
            String winnerPath = "";
    
            for(Map.Entry<String, BufferedImage> candidate: imgMap.entrySet()) {
    
                String path = candidate.getKey();
                BufferedImage bufferedImage = candidate.getValue();
    
                double diff = compare(bufferedImage, needle);
                if(diff < lastDiff) {
                    lastDiff = diff;
                    winner = bufferedImage;
                    System.out.println("path :"+path);
                    winnerPath = path;
                }
            }
            return winnerPath;
        }
    
        public static double compare(BufferedImage img1, BufferedImage img2) {
            int width1 = img1.getWidth();
            int width2 = img2.getWidth();
            int height1 = img1.getHeight();
            int height2 = img2.getHeight();
            if ((width1 != width2) || (height1 != height2)) {
                throw new IllegalArgumentException("Error: Images dimensions mismatch");
            }
    
            int diff2 = 0;
    
            for (int i = 0; i < height1; i++) {
                for (int j = 0; j < width1; j++) {
                    int rgb1 = img1.getRGB(j, i);
                    int rgb2 = img2.getRGB(j, i);
                    int r1 = (rgb1 >> 16) & 0xff;
                    int g1 = (rgb1 >> 8) & 0xff;
                    int b1 = (rgb1) & 0xff;
                    int r2 = (rgb2 >> 16) & 0xff;
                    int g2 = (rgb2 >> 8) & 0xff;
                    int b2 = (rgb2) & 0xff;
    
                    diff2 += Math.pow(r1 - r2, 2) + Math.pow(g1 - g2, 2) + Math.pow(b1 - b2, 2); 
                }
            }
            return diff2 * 1.0 / (height1*width1);
        }
    
    }
    

    希望这能有所帮助

  3. # 3 楼答案

    为此,我制作了一个名为图像相似性搜索器tool,作为http://sourceforge.net/projects/imgndxr/上可用的自由软件

    它使用两个库:

    The LIRE (Lucene Image REtrieval) library provides a simple way to retrieve images and photos based on their color and texture characteristics. LIRE creates a Lucene index of image features for content based image retrieval (CBIR). Several different low level features are available, such as MPEG-7 ScalableColor, ColorLayout, and EdgeHistogram, Auto Color Correlogram, PHOG, CEDD, JCD, FCTH, and many more. Furthermore simple and extended methods for searching the index and result browsing are provided by LIRE. LIRE scales well up to millions of images with hash based approximate indexing. The LIRE library and the LIRE Demo application as well as all the source are available under the Gnu GPL license.

    Apache LuceneTM is a high-performance, full-featured text search engine library written entirely in Java. It is a technology suitable for nearly any application that requires full-text search, especially cross-platform.

    Apache Lucene is an open source project available for free download. Please use the links on the right to access Lucene.