概述
最近项目中涉及到了图像算法识别,涉及到传递mat,于是就有了这样的一篇博客
由于对外接口要求对方提供的是base64编码的jpg图像数据,但是算法需要的是Mat类型的数据,这样就需要引入opencv_java来实现这样的转换。
实际上整个过程就需要几个步骤:
1.实现base64的解码;
2.将解码后的数据转换为BufferedImage;
3.将BufferedImage转换为Mat类型数据;
前两步都很好实现,难点在第三步上,我们就具体讲讲第三步的实现
1.首先,maven项目引入几个pom依赖:
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.4.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bytedeco/javacpp -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp</artifactId>
<version>1.4.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/opencv/opencv -->
<dependency>
<groupId>opencv</groupId>
<artifactId>opencv</artifactId>
<version>1.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bytedeco.javacpp-presets/opencv -->
<!-- <dependency> <groupId>org.bytedeco.javacpp-presets</groupId> <artifactId>opencv</artifactId>
<version>4.0.1-1.4.4</version> </dependency> -->
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>opencv</artifactId>
<version>2.4.11-0.11</version>
</dependency>
<!-- 需要自己安装配置opencv -->
<dependency>
<groupId>org</groupId>
<artifactId>opencv</artifactId>
<version>2413</version>
</dependency>
除最后一个pom依赖外,其余的应该都能够从maven仓库中下载得到。
那我们就来讲下如何获得最后一个maven依赖。
1.1)首先,我们来到opencv的官网:https://opencv.org/releases.html
选择自己需要下载的平台及版本,因为要和公司算法做兼容,所以我选用的是2.4.13版本,window下安装配置极其简单,将下载得到的.exe文件解压缩,然后将到opencvbuildjava下即可得到需要的jar包,再然后将jar包转换为maven库里的依赖就可以了。
具体命令我就不放在这了,拿一个通用的模板命令挂在这,按自己实际去转换吧。
mvn install:install-file -Dfile=XX.jar -DgroupId=org -DartifactId=opencv -Dversion=2413 -Dpackaging=jar
1.2)引入了pom依赖之后,windows下还需要opencvbuildjava
下需要的opencv的dll文件,将86(32位系统)或64(64位系统)下的
opencv_java2413.dll文件引入到系统的jdk的bin目录下
1.3)上边的是windows的例子,实际很多情况下代码是在GPU的linux服务器上运行的,那么就需要下载linux平台下的文件,在服务器上使用Cmake编译安装,安装之后得到的会是.so文件,将对应的.so文件移入到/usr/lib下即可。
如果不移动就需要将将.so文件的具体路径放入到/etc/profile配置文件中,然后使用source命令更新系统配置。
准备工作都做完了,剩下的就是代码了
首先,需要从系统的环境中加载需要的opencv文件
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
其次,就是代码的具体实现了,包含了BufferedImage与mat(4.0.1版本支持双方互转,2413不支持mat转BufferedImage或者是支持的类与4.0.1版本不一致,具体的各位自己去探索吧)数据的互转及转opencv的rect方法。
【注】代码是按照.jpg处理的,需要变更的东西还是各位按需求自定义吧。
import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Rect;
import sun.misc.BASE64Decoder;
public class Java2MatTools {
/**
* 加载文件 opencv_java401.dll(windows)/libopencv_java401.so文件
* (windows将文件放到jdk的bin目录下;linux为了简单起见可以放到/usr/lib下面)
*/
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
/**
* 路径图片转为base64
*
* @param imagePath
* @return
* @throws IOException
*/
public static Mat imagePath2Mat(String imagePath) throws IOException {
// 注释部分模拟传入base64数据
BufferedImage image = ImageIO.read(new FileInputStream(imagePath));
Mat matImage = Java2MatTools.BufImg2Mat(image, BufferedImage.TYPE_3BYTE_BGR, CvType.CV_8UC3);// CvType.CV_8UC3
// 小型图片可以输出 查看下
//
System.out.println(matImage.dump());
//
mat = matImage.dump();
return matImage;
}
/**
* base64转Mat
*
* @param base64
* @return
* @throws IOException
*/
public static Mat base642Mat(String base64) throws IOException {
// 对base64进行解码
BASE64Decoder decoder = new BASE64Decoder();
byte[] origin = decoder.decodeBuffer(base64);
InputStream in = new ByteArrayInputStream(origin); // 将b作为输入流;
BufferedImage image = ImageIO.read(in);
Mat matImage = Java2MatTools.BufImg2Mat(image, BufferedImage.TYPE_3BYTE_BGR, CvType.CV_8UC3);// CvType.CV_8UC3
return matImage;
}
/**
*
* @param base64
* @throws IOException
*/
public static Rect base642Rect(String base64) throws IOException {
BASE64Decoder decoder = new BASE64Decoder();
byte[] origin = decoder.decodeBuffer(base64);
InputStream in = new ByteArrayInputStream(origin); // 将b作为输入流;
BufferedImage image = ImageIO.read(in);
return new Rect(0,0,image.getWidth(),image.getHeight());
}
/**
*
* @param base64
* @throws IOException
*/
public static Rect BufferedImage2Rect(BufferedImage image) throws IOException {
return new Rect(0,0,image.getWidth(),image.getHeight());
}
/**
*
* @param base64
* @throws IOException
*/
public static BufferedImage base642BufferedImage(String base64) throws IOException {
BASE64Decoder decoder = new BASE64Decoder();
byte[] origin = decoder.decodeBuffer(base64);
InputStream in = new ByteArrayInputStream(origin); // 将b作为输入流;
return ImageIO.read(in);
}
/**
* BufferedImage转换成Mat
*
* @param original 要转换的BufferedImage
* @param imgType
bufferedImage的类型 如 BufferedImage.TYPE_3BYTE_BGR
* @param matType
转换成mat的type 如 CvType.CV_8UC3
*/
public static Mat BufImg2Mat(BufferedImage original, int imgType, int matType) {
if (original == null) {
throw new IllegalArgumentException("original == null");
}
// Don't convert if it already has correct type
if (original.getType() != imgType) {
// Create a buffered image
BufferedImage image = new BufferedImage(original.getWidth(), original.getHeight(), imgType);
// Draw the image onto the new buffer
Graphics2D g = image.createGraphics();
try {
g.setComposite(AlphaComposite.Src);
g.drawImage(original, 0, 0, null);
} finally {
g.dispose();
}
}
byte[] pixels = ((DataBufferByte) original.getRaster().getDataBuffer()).getData();
Mat mat = Mat.eye(original.getHeight(), original.getWidth(), matType);
mat.put(0, 0, pixels);
return mat;
}
/**
* Mat转换成BufferedImage
*
* @param matrix
要转换的Mat
* @param fileExtension 格式为 ".jpg", ".png", etc
* @return
*//*
public static BufferedImage Mat2BufImg(Mat matrix, String fileExtension) {
// convert the matrix into a matrix of bytes appropriate for
// this file extension
MatOfByte mob = new MatOfByte();
Imgcodecs.imencode(fileExtension, matrix, mob);
// convert the "matrix of bytes" into a byte array
byte[] byteArray = mob.toArray();
BufferedImage bufImage = null;
try {
InputStream in = new ByteArrayInputStream(byteArray);
bufImage = ImageIO.read(in);
} catch (Exception e) {
e.printStackTrace();
}
return bufImage;
}*/
/**
* Mat转换保存成Image
*
* @param matrix
要转换的Mat
* @param fileExtension 格式为 ".jpg", ".png", etc
*
* @return
*/
/* public static void Mat2Img(Mat matrix, String fileExtension, String pathAndName) {
// convert the matrix into a matrix of bytes appropriate for
// this file extension
MatOfByte mob = new MatOfByte();
Imgcodecs.imencode(fileExtension, matrix, mob);
// convert the "matrix of bytes" into a byte array
byte[] byteArray = mob.toArray();
BufferedImage bufImage = null;
try {
InputStream in = new ByteArrayInputStream(byteArray);
bufImage = ImageIO.read(in);
writeImageFile(bufImage, pathAndName);
} catch (Exception e) {
e.printStackTrace();
}
}*/
/**
* 将bufferdimage转换为图片
*
* @param bi
* @param pathAndName
* @throws IOException
*/
public static void writeImageFile(BufferedImage bi, String pathAndName) throws IOException {
File outputfile = new File(pathAndName);
ImageIO.write(bi, "jpg", outputfile);
}
}
ok,完事。
最后
以上就是有魅力冰淇淋为你收集整理的java实现base64及图片路径转换mat的方法的全部内容,希望文章能够帮你解决java实现base64及图片路径转换mat的方法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复