目录
一、环境部署
- Windows
- 在OpenCV官网下载安装包
- 安装完毕后,在opencv\build\java复制jar包,后续导入依赖时使用
- 在opencv\build\java\x64或opencv\build\java\x86复制dll文件,将dll文件复制到C:\Windows\System32文件夹
- Linux 以Centos为例
- 安装依赖
yum install gcc gcc-c++
yum install cmake*
yum install gtk2-devel
yum install ant
- 在官网下载OpenCV源码,上传至Linux服务器并解压
- 进入解压后的OpenCV源码目录,创建编译目录
cd /opencv4.4.0
mkdir build
cd build
- 生成makefile(/makefile目录更换为自定义的文件夹)
cmake -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=/makefile ..
.. 代表在父目录执行
- 编译、安装
make
make install
- 安装后产生的文件
opencv-4.4.0/build/lib/libopencv_java440.so
opencv-4.4.0/build/bin/opencv-440.jar
jar包和Windows下生成的一样;so包则是Linux所特有,对应于Windows的dll文件
7. 将libopencv_java440.so复制到 /usr/lib 文件夹
8. Linux下编译安装完成后会默认部署OpenJDK11环境在服务器上,影响服务器原Java环境,只需要手动卸载OpenJDK即可,原Java环境会重新生效
二、导入依赖
- 在SpringBoot项目的resources文件夹新建 /lib/opencv 文件夹,将 jar 包复制进去
- 项目不要集成spring-boot-devtools工具,会影响dll库文件导入
- 添加依赖
<!-- OpenCV -->
<dependency>
<groupId>org</groupId>
<artifactId>opencv</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}\src\main\resources\lib\opencv\opencv-440.jar</systemPath>
<version>4.4.0</version>
</dependency>
三、使用
- 新建MatUtil,将图片Base64(去掉Base64文件头)转为Mat对象
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.imgcodecs.Imgcodecs;
import sun.misc.BASE64Decoder;
import javax.imageio.ImageIO;
import javax.xml.bind.DatatypeConverter;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.ByteArrayInputStream;
import java.io.IOException;
/**
* @author Tang_J on 2022/4/20 下午 02:00
* @Description TODO
**/
public class MatUtil {
/**
* Base64 编码转换为 BufferedImage
*
* @param base64 图片Base64
* @return BufferedImage
*/
public static BufferedImage base64ToBufferedImage(String base64) {
BASE64Decoder decoder = new BASE64Decoder();
try {
byte[] buffer = decoder.decodeBuffer(base64);
ByteArrayInputStream inputStream = new ByteArrayInputStream(buffer);
return ImageIO.read(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* Mat 转换成 byte[]
*
* @param mat Mat对象
* @return byte[]
*/
public static byte[] toByteArray(Mat mat) {
MatOfByte mob = new MatOfByte();
Imgcodecs.imencode(".jpg", mat, mob);
return mob.toArray();
}
/**
* byte[] 转 图片Base64
*
* @param bytes byte[]
* @return Base64
*/
public static String byteArray2Base64(byte[] bytes) {
return DatatypeConverter.printBase64Binary(bytes);
}
/**
* Mat 转 图片Base64
*
* @param mat Mat
* @return 图片Base64
*/
public static String mat2Base64(Mat mat) {
return byteArray2Base64(toByteArray(mat));
}
/**
* Mat 转换成 BufferedImage
*
* @param mat Mat
* @return BufferedImage
*/
public static BufferedImage toBufferedImage(Mat mat) throws IOException {
byte[] buffer = toByteArray(mat);
ByteArrayInputStream inputStream = new ByteArrayInputStream(buffer);
return ImageIO.read(inputStream);
}
/**
* Base64 转换成 Mat
*
* @param base64 图片Base64
* @return Mat
*/
public static Mat base642Mat(String base64) {
return bufImg2Mat(base64ToBufferedImage(base64), BufferedImage.TYPE_3BYTE_BGR, CvType.CV_8UC3);
}
/**
* BufferedImage 转换成 Mat
*
* @param original 要转换的BufferedImage
* @param imgType bufferedImage的类型 如 BufferedImage.TYPE_3BYTE_BGR
* @param matType 转换成mat的type 如 CvType.CV_8UC3
* https://wenku.baidu.com/view/3cd5e54b5bfafab069dc5022aaea998fcc2240a1.html
*/
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);
original = image;
} catch (Exception e) {
e.printStackTrace();
} 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;
}
}
- OpenCVUtil,图片处理工具类,在此工具类中编写更多图片处理方法;@Component注册为组件使用,只需在项目启动时加载一次OpenCV库
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import static org.opencv.imgproc.Imgproc.*;
@Component
@Scope(value = "singleton")
public class OpenCVUtil {
/**
* 日志组件可根据自己项目更换
*/
private static final Logger logger = LoggerFactory.getLogger(OpenCVUtil.class);
/**
* 1.什么是java.awt.headless模式
* java.awt.headless是J2SE的一种模式,用于在缺失显示屏、鼠标或者键盘时的系统配置。对于后端服务来讲,很多都是需要将这个属性设置为true的。
* 2.什么时候使用java.awt.headless模式
* 对于开发者来讲常常需要在该模式下工作。因为服务器(如提供Web服务的)往往可能缺少前述设备,但又需要使用他们提供的功能,生成相应的数据,以提供给客户端(如浏览器所在的配有相关的、键盘和的主机)。
*/
static {
try {
// 解决awt报错问题
logger.info("启动headless mode...");
System.setProperty("java.awt.headless", "true");
logger.info("动态库路径:{}", System.getProperty("java.library.path"));
logger.info("开始加载OpenCV库...");
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
logger.info("load success");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 图片清晰度增强
* 使用高斯滤波器,高斯滤镜可减少图像中的噪声并使它看起来更好(或更高分辨率)
* http://www.srcmini.com/70014.html
*
* @param base64 图片Base64
*/
public String imageDefinitionEnhance(String base64) {
logger.info("图片清晰度增强");
Mat source = MatUtil.base642Mat(base64);
Mat destination = new Mat(source.rows(), source.cols(), source.type());
GaussianBlur(source, destination, new Size(0, 0), 10);
Core.addWeighted(source, 1.5, destination, -0.5, 0, destination);
return MatUtil.mat2Base64(destination);
}
/**
* 图片对比度增强
* 使用直方图均衡
* http://www.srcmini.com/70010.html
*
* @param base64 图片Base64
*/
public String imageContrastEnhance(String base64) {
logger.info("图片对比度增强");
Mat source = MatUtil.base642Mat(base64);
cvtColor(source, source, COLOR_BGR2GRAY);
Mat destination = new Mat(source.rows(), source.cols(), source.type());
equalizeHist(source, destination);
return MatUtil.mat2Base64(destination);
}
/**
* 图片无损放大
* 使用高斯金字塔
* https://blog.csdn.net/datouniao1/article/details/108535563
*
* @param base64 图片Base64(去文件头)
*/
public String imageQualityEnhance(String base64) {
logger.info("图片无损放大");
Mat source = MatUtil.base642Mat(base64);
Mat destination = new Mat();
pyrUp(source, destination);
return MatUtil.mat2Base64(destination);
}
}
四、注意事项
- 项目不要集成spring-boot-devtools
- 使用System.loadLibrary(Core.NATIVE_LIBRARY_NAME) 加载库,才能在部署到服务器后依旧可以动态加载库;网上的文章都是直接加载dll文件的方法
- Java使用OpenCV处理图片教程
如有建议或疑问欢迎指出!
本文转自 https://blog.csdn.net/qq_41155209/article/details/124297661,如有侵权,请联系删除。
文章评论