前言
OpenCV是一个流行的,开源的,底层由C++写的图形图像处理库。众所周知C++的学习成本是很高的,作者虽然也用C++实现了行驶证判断工程,但希望通过我们所熟悉的Java来编写上层,调用中间件JNI,然后再使用底层C++库。如图架构
好,废话不多讲,直接配置环境。
配置步骤
一.安装IntelliJ
国内有很多破解版本的链接可以使用,目前最新破解版15.0.2
二.安装MacPorts
作者Mac下装有HomeBrew,也确实用它安装过C++版本的。但是装Java版本的遇到问题,
就是-with java命令提示不存在,未找到解决办法,
所以用了同类产品,但是它下载很慢,作者用了4个小时,
主要它要下载相关的所有依赖,而不是使用系统里已经有的,
这一点也是优点,因为不依赖系统,HomeBrew则不同,比如你无意删掉其中一个依赖,恐怕就影响使用了。
安装MacPorts需要Xcode环境,如何安装请参考MacPorts官网,并配置环境变量。
如果不懂,则可以键入到MacPorts的安装目录下使用下面命令。实在不会操作,再给作者留言。
键入命令
sudo port install opencv +java
它下载后的opencv放在了文件夹
/opt/local/share/OpenCV
并且你会看到一个java文件夹里面有2个文件分别是(以3.2.0版本为例)
libopencv_java320.dylib
opencv-320.jar
前者是动态链接库,JNI 在Windows上结尾就是.dll咯
后者是jar包
这两个包对接下来配置是至关重要的,你只要记住路径就可以了。路径再打一遍
/opt/local/share/OpenCV/java/libopencv_java320.dylib
/opt/local/share/OpenCV/java/opencv-320.jar
接下来启动IntellJ进行配置
1.添加 opencv-320.jar
2.添加依赖libopencv_java320.dylib
-Djava.library.path=/opt/local/share/OpenCV/java
分别为图1和图2展示,然后本文结束
给出测试例子,注意自己创建resources目录,放一张图片。该例子是加载并展示一张图,源码为:
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
public class Main {
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);//很重要
}
public static void main(String[] args) {
Mat mat = Imgcodecs.imread("./resources/test.jpg");
ImageViewer viewer = new ImageViewer(mat);
viewer.imshow();
}
}
对了,在Java中没有方便的通过 imShow()来展示一张图,所以封装了一个ImageViewer类,源码如下:
import org.opencv.core.Mat;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
public class ImageViewer {
private JLabel imageView;
private Mat image;
private String windowName;
/**
* 如果使用junit测试时调用该方法,图像会一闪而过,可通过sleep()等方式暂时显示
*
* @param
*/
public ImageViewer(Mat image) {
this.image = image;
}
/**
* @param image 要显示的mat
* @param windowName 窗口标题
*/
public ImageViewer(Mat image, String windowName) {
this.image = image;
this.windowName = windowName;
}
/**
* 图片显示
*/
public void imshow() {
setSystemLookAndFeel();
Image loadedImage = toBufferedImage(image);
JFrame frame = createJFrame(windowName, image.width(), image.height());
imageView.setIcon(new ImageIcon(loadedImage));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 用户点击窗口关闭
}
private void setSystemLookAndFeel() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
private JFrame createJFrame(String windowName, int width, int height) {
JFrame frame = new JFrame(windowName);
imageView = new JLabel();
final JScrollPane imageScrollPane = new JScrollPane(imageView);
imageScrollPane.setPreferredSize(new Dimension(width, height));
frame.add(imageScrollPane, BorderLayout.CENTER);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
return frame;
}
private Image toBufferedImage(Mat matrix) {
int type = BufferedImage.TYPE_BYTE_GRAY;
if (matrix.channels() > 1) {
type = BufferedImage.TYPE_3BYTE_BGR;
}
int bufferSize = matrix.channels() * matrix.cols() * matrix.rows();
byte[] buffer = new byte[bufferSize];
matrix.get(0, 0, buffer); // 获取所有的像素点
BufferedImage image = new BufferedImage(matrix.cols(), matrix.rows(), type);
final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.arraycopy(buffer, 0, targetPixels, 0, buffer.length);
return image;
}
全文完结