图像处理-Java-以图搜图

背景

  《图像处理-Java-以图搜图》,之前在编写过关于图像边缘检测-去黑边图像边缘检测-自动纠偏图像处理-锐化图像处理-去噪/高斯模糊/套红图像处理-背景色平滑/反色图像处理-指定大小压缩图像处理-Java-字深字浅等一系列文章,接下来主要介绍基于opencv+lucene的以图搜图功能。

概述

  使用JAVA语言实现,实现思路是使用opencv获得图像的特征,之后将图像特征存入lucene后使用KnnVectorQuery进行搜索,从而达到以图搜图的效果。

实现步骤

  1. 引入OpenCV后获得图像特征;
  2. 处理图像特征,包括归一化等操作;
  3. 归一化后的图像特征存入lucene中;
  4. 使用 KnnVectorQuery 进行相关搜索

代码实现

        <dependency>
            <groupId>org.opencv</groupId>
            <artifactId>opencv-401</artifactId>
            <version>401</version>
            <scope>system</scope>
            <systemPath>${pom.basedir}/libs/opencv-401.jar</systemPath>
        </dependency>

        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-core</artifactId>
            <version>9.10.0</version>
        </dependency>
    /**
     * 图像特征
     *
     * @param imagePath
     * @return
     */
    public static byte[] matOfKeyPointImage(String imagePath) {
        Mat image = Imgcodecs.imread(imagePath);

        // Convert image to grayscale
        Mat grayImage = new Mat();
        Imgproc.cvtColor(image, grayImage, Imgproc.COLOR_BGR2GRAY);

        // Initialize ORB detector
        ORB detector = ORB.create();

        // Detect keypoints
        MatOfKeyPoint keypoints = new MatOfKeyPoint();
        detector.detect(grayImage, keypoints);

        // Compute descriptors
        Mat descriptors = new Mat();
        detector.compute(grayImage, keypoints, descriptors);

        // Convert descriptors to byte array
        MatOfByte matOfByte = new MatOfByte();
        descriptors.convertTo(matOfByte, CvType.CV_8U);

        // Convert MatOfByte to byte array
        byte[] descriptorsData = new byte[(int) (matOfByte.total() * matOfByte.channels())];
        matOfByte.get(0, 0, descriptorsData);

        return descriptorsData;
    }

    @Test
    public void testQuery() throws IOException {
        // 第一个存储的向量,用来后续的搜索
        float[] firstVector = null;

        try (MMapDirectory dir = new MMapDirectory(indexPath)) {
            try (IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig())) {
                List<String> imageAbsPathList = new ArrayList<>();
                imageAbsPathList.add("pap-1.jpg");
                imageAbsPathList.add("pap-2.jpg");
                imageAbsPathList.add("pap-3.jpg");
                for(String imageAbsPath : imageAbsPathList) {
                    byte[] bytes = OpenCVUtils.matOfKeyPointImage(imageAbsPath);
                    // TODO 这里不合适,后续需要再次调整,由于lucene的限制,这里限制了特征向量的长度。 这里主要是把 byte[] -> float[], 并且只取前面1024个特征。
                    float[] floats = OpenCVUtils.normalize(OpenCVUtils.convertArray(OpenCVUtils.byteArrayToFloatList(bytes), 1024));
                    if(firstVector == null) {
                        firstVector = floats;
                    }
                    Document doc = new Document();
                    doc.add(new StoredField("id", imageAbsPath));
                    doc.add(new KnnVectorField("field", floats));
                    writer.addDocument(doc);
                }
            }
            System.out.println();
            try (IndexReader reader = DirectoryReader.open(dir)) {
                IndexSearcher searcher = new IndexSearcher(reader);

                TopDocs results = searcher.search(new KnnVectorQuery("field", firstVector, 3), 10);
                System.out.println("Hits: " + results.totalHits);
                for (ScoreDoc sdoc : results.scoreDocs) {
                    Document doc = reader.document(sdoc.doc);
                    StoredField idField = (StoredField) doc.getField("id");
                    System.out.println("Found: " + idField.toString() + " = " + String.format("%.1f", sdoc.score));
                }
            }
        }

    }

参考

  1. http://pap-docs.pap.net.cn/
  2. https://gitee.com/alexgaoyh/pap4j-boot3
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值