首页 > 编程语言 >JavaCV实现旋转图像识别和旋转角度预测

JavaCV实现旋转图像识别和旋转角度预测

时间:2023-07-10 11:11:22浏览次数:53  
标签:图像识别 Mat new 旋转 opencv org JavaCV angle bytedeco

引言

本文将介绍如何使用JavaCV库来实现图像识别和旋转角度预测,并结合直方图统计和dhash算法来比较图片的相似度。JavaCV是一个基于OpenCV的Java库,提供了丰富的图像处理和计算机视觉功能。

环境搭建

在开始之前,需要安装JavaCV库和相关依赖。可以通过Maven或手动下载jar包的方式进行安装。安装完成后,配置JavaCV的开发环境,确保能够成功引入相关的类和方法。这里是使用maven的方式引入最小依赖。
JavaCV图片处理最小依赖如下:

<profiles>
        <profile>
            <id>dev</id>
            <properties>
                <system.platform>macosx-arm64</system.platform>
            </properties>
        </profile>
        <profile>
            <id>pro</id>
            <activation>
                <property>
                    <name>pro</name>
                </property>
            </activation>
            <properties>
                <system.platform>linux-x86_64</system.platform>
            </properties>
        </profile>
    </profiles>
<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <maven.compiler.source>1.8</maven.compiler.source>
  <maven.compiler.target>1.8</maven.compiler.target>
  <javacv.version>1.5.7</javacv.version>
  <opencv.version>4.5.5-${javacv.version}</opencv.version>
  <openblas.version>0.3.19-${javacv.version}</openblas.version>
</properties>
<dependencies>
  <!-- 全量依赖不建议使用 打包后有约1G大小-->
  <!--   <dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv-platform</artifactId>
    <version>1.5.9</version>
  </dependency> -->
    <!--    Maven 版本的最小依赖   -->
    <!--  javacv核心依赖 -->
    <dependency>
      <groupId>org.bytedeco</groupId>
      <artifactId>javacv</artifactId>
      <version>${javacv.version}</version>
     <!-- 排除不需要的依赖   -->
      <exclusions>
        <exclusion>
          <groupId>org.bytedeco</groupId>
          <artifactId>ffmpeg</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.bytedeco</groupId>
          <artifactId>videoinput</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.bytedeco</groupId>
          <artifactId>tesseract</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.bytedeco</groupId>
          <artifactId>flycapture</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.bytedeco</groupId>
          <artifactId>flycapture</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.bytedeco</groupId>
          <artifactId>artoolkitplus</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.bytedeco</groupId>
          <artifactId>leptonica</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.bytedeco</groupId>
          <artifactId>flandmark</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.bytedeco</groupId>
          <artifactId>librealsense</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.bytedeco</groupId>
          <artifactId>librealsense</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.bytedeco</groupId>
          <artifactId>libfreenect</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.bytedeco</groupId>
          <artifactId>librealsense2</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.bytedeco</groupId>
          <artifactId>libfreenect2</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.bytedeco</groupId>
          <artifactId>libdc1394</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.bytedeco</groupId>
      <artifactId>javacpp</artifactId>
      <version>${javacv.version}</version>
		<!--  classifier用于指定系统环境,具体有哪些可以先引入javacv-platform查看  -->
      <classifier>${system.platform}</classifier>
    </dependency>
    <!--  javacv核心依赖 -->
    <!-- opencv依赖 -->
    <dependency>
      <groupId>org.bytedeco</groupId>
      <artifactId>opencv</artifactId>
      <version>${opencv.version}</version>
      <classifier>${system.platform}</classifier>
    </dependency>
    <!-- 矩阵计算库 -->
    <dependency>
      <groupId>org.bytedeco</groupId>
      <artifactId>openblas</artifactId>
      <version>${openblas.version}</version>
      <classifier>${system.platform}</classifier>
    </dependency>
</dependencies>

GitHub - bytedeco/javacv: Java interface to OpenCV, FFmpeg, and more
GitHub - bytedeco/javacv-examples: Examples of using JavaCV / OpenCV library on Java Virtual Machine

图像旋转前后的识别匹配

在图像识别中,常用的方法之一是通过直方图统计来衡量图像之间的相似度。直方图统计可以将图像的颜色分布进行量化,然后通过比较直方图的差异来判断图像的相似程度。因为直方图统计的是图片的颜色分布,与图片像素的位置无关,所以对于旋转前后的图片用直方图的差异来判断图像的相似程度能达到比较好的效果。
JavaCV提供了直方图统计的功能,可以使用其提供的API来计算图像的直方图,并进行比较。

import org.bytedeco.javacpp.FloatPointer;
import org.bytedeco.javacpp.IntPointer;
import org.bytedeco.javacpp.PointerPointer;
import org.bytedeco.opencv.global.opencv_core;
import org.bytedeco.opencv.global.opencv_imgproc;
import org.bytedeco.opencv.opencv_core.*;

import static org.bytedeco.opencv.global.opencv_core.*;
import static org.bytedeco.opencv.global.opencv_imgproc.*;
import static org.bytedeco.opencv.global.opencv_imgcodecs.*;
import static org.bytedeco.opencv.global.opencv_imgproc.calcHist;

public void imageFeature() {
    // 加载图像
    Mat image1 = imread("image/a1.jpeg", IMREAD_COLOR);
    Mat hist1 = calcHist01(image1);
    for (int angle = 0; angle < 360; angle++) {
        Mat image2 = rotateImage(image1, angle);
        Mat hist2 = calcHist01(image2);
        // 比较直方图相似度(使用巴氏距离,距离越小越相似)
        double similarity = compareHist(hist1, hist2, opencv_imgproc.HISTCMP_BHATTACHARYYA);
        System.out.println(angle + ": " + similarity);
    }
}
public Mat calcHist01(Mat image) {
final int[] channels = new int[]{0,1,2};
final Mat mask = new Mat();
final Mat hist = new Mat();
final int[] histSize = new int[]{16,16,16};
final float[] histRange = new float[]{0f, 255f};
IntPointer intPtrChannels = new IntPointer(channels);
IntPointer intPtrHistSize = new IntPointer(histSize);
final PointerPointer<FloatPointer> ptrPtrHistRange = new PointerPointer<>(histRange, histRange, histRange);
calcHist(image, 1, intPtrChannels, mask, hist, 3, intPtrHistSize, ptrPtrHistRange, true, false);
return hist;
}

图片相似度比较

 除了直方图统计,还可以使用dhash算法来比较两个图片的相似度。dhash算法是一种基于哈希值的图像相似度计算方法,它通过计算图片的差异哈希值来评估图片的相似程度。dhash对于图像缩放、模糊的情况下有较高的识别率,但dhash由于是比较每行左右两个像素的差异,对像素的位置是敏感的,所以对于旋转前后的图片像素位置变化,使用dhash则达不到预想的效果。
由于JavaCV没有直接提供计算图片的dhash值的方法,这里需自己实现图片dhash的计算,然后再计算两个hash的汉明距离,汉明距离为0则最相似。
public static double calculateDHashSimilarity(Mat img1, Mat img2) {
    long hash1 = calculateDHash(img1);
    long hash2 = calculateDHash(img2);
    int hammingDistance = Long.bitCount(hash1 ^ hash2);
    double similarity = hammingDistance / 64.0;
    return similarity;
}
public static long calculateDHash(Mat image) {
        Mat resizedImage = new Mat();
        Size newSize = new Size(9, 8);
        opencv_imgproc.resize(image, resizedImage, newSize, 0, 0, INTER_AREA);
        long hash = 0;
        for (int row = 0; row < 8; row++) {
            for (int col = 0; col < 8; col++) {
                double leftPixel = resizedImage.ptr(row, col).getDouble();
                double rightPixel = resizedImage.ptr(row, col + 1).getDouble();
                hash = (hash << 1) | (leftPixel < rightPixel ? 1 : 0);
            }
        }
        return hash;
    }

旋转角度预测

对于图片旋转角度的预测可以使用机器学习的方式达到预测效果。RotNet就是一种自监督模型。这里推荐一个Python的实现,感兴趣的可以了解一下(https://github.com/d4nst/RotNet/)。由于RotNet,达不到我预期的效果,这里使用前面提到的直方图统计比较旋转前后的图片找到原图,然后用暴力破解的方式将旋转后的图片每次旋转两度与原图匹配计算显示度,然后取最小相似度的旋转角度作为预测角度。

// 部分代码
int minAngel = 0;
double minRotateSimilarity = 999999999;
for (int angle = 1; angle < 360; angle += 2) {
    // 旋转
    Mat matRotate = rotateImage(imgMatRandom, -angle);
    double similarity = calculateDHashSimilarity(matRotate, matchMat);
    if (similarity < minRotateSimilarity) {
        minRotateSimilarity = similarity;
        minAngel = angle;
    }
}

private static Mat rotateImage(Mat image, double angle) {
        Point2f center = new Point2f(image.cols() / 2, image.rows() / 2);
        Mat rotationMatrix = getRotationMatrix2D(center, angle, 1.0);
        Mat rotatedImage = new Mat();
        warpAffine(image, rotatedImage, rotationMatrix, image.size());
        return rotatedImage;
}

标签:图像识别,Mat,new,旋转,opencv,org,JavaCV,angle,bytedeco
From: https://www.cnblogs.com/jiansu/p/17540440.html

相关文章

  • labview 调用,联合halcon 编程最近在做项目,主界面使用labview,图像识别部分使用halcon,然
    labview调用,联合halcon编程最近在做项目,主界面使用labview,图像识别部分使用halcon,然后返回结果到labview再进一步判断显示。具体流程1.使用labview采集图像2,图像传递给halcon处理3.labview读取halcon的处理结果这里共享的知识点有以下几个1.labview的里面的图像,也就是image类型......
  • 数据增强之裁剪、翻转与旋转
    文章和代码已经归档至【Github仓库:<https://github.com/timerring/dive-into-AI>】或者公众号【AIShareLab】回复pytorch教程也可获取。数据增强DataAugmentation数据增强又称为数据增广,数据扩增,它是对训练集进行变换,使训练集更丰富,从而让模型更具泛化能力。技巧:debugconsole......
  • 【验证码逆向专栏】某度滑块、点选、旋转验证码 v1、v2 逆向分析
    声明本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作......
  • 旋转Treap树
    #include<bits/stdc++.h>usingnamespacestd;constintM=1e6+10;intcnt=0;//cnt记录当前节点个数,最新一个节点即t[cnt]introot=0;//root是整棵树的树根,初始为空树所以root初始化=0intn;//n表示操作次数structNode{ intls,rs;//左右儿子 intval,pr......
  • 坚固型3DMAG™A31315LOLATR-XZ-S-AR-10、A31315LOLATR-XY-S-SE-10霍尔效应 线性,旋转位
    A313153D磁性位置传感器IC是完全集成的坚固型3DMAG™霍尔效应磁性位置传感器IC,主要用于支持汽车、工业和消费类应用中的各种非接触式旋转和线性位置测量。此传感器IC符合AEC-Q1000级的要求,并根据ISO26262进行开发。这些标准使A31315成为了要求严格的汽车安全系统的理想选择,适......
  • 图像识别,如何提取文字?在线提取图片文字内容(批量)
    功能地址在线文字识别,OCR识别,提取图片文字内容,图像转文字教程,批量免费|TOFORU在线工具软件定制地址:https://tool.toforu.com/f/img_text.html功能说明在线文字识别,提取图片文字内容,图像转文字。功能使用原图上传识别提取文字结果下载结果txt文件,可看到提取到......
  • 怎么旋转图片?在线旋转图片(批量)
    功能地址在线图片旋转,翻转照片,设置照片旋转角度,批量免费|TOFORU在线工具软件定制地址:https://tool.toforu.com/f/img_roate.html功能说明在线图片旋转,翻转照片,设置照片旋转角度,批量免费。支持参数:旋转角度功能使用相关知识图片旋转是一种常见的图像处理操作,它可......
  • JavaCV的摄像头实战之十三:年龄检测
    欢迎访问我的GitHub这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos本篇概览本文是《JavaCV的摄像头实战》系列的第十三篇,前文《JavaCV的摄像头实战之十二:性别检测》中,借助训练好的卷积神经网络模型开发出了识别性别的应用,今天在前文基础......
  • Java使用joml计算机图形学库,将3D坐标旋转正交投影转为2D坐标
    最近遇到了一个困扰我许久的难题,现将解决方案分享出来由于我们的项目侧重点在前端绘图,导致了前后端工作量不协调,我后端接口很快就能写完,而前端一个图要画好久,领导见状将前端的任务分到后端一部分用Java代码来实现,然后给前端提供接口而我接到的任务就是将Echarts中绘制三维图形的......
  • C#图片旋转
    这里以Bitmap为例说明问题。可以看到,旋转方法需要传入一个参数,而这个参数是一个枚举类型,RotateFlipType。系统提供了两大类型的旋转,1.旋转后不翻转。2.旋转后接着翻转。翻转的轴可以为X和Y,对应为水平和垂直。经测试,它们的这样分的,如图所示,3代表水平的轴,2代表垂直的轴。 ......