前言
OpenCV是一個(gè)流行的透敌,開源的抗果,底層由C++寫的圖形圖像處理庫(kù)倡怎。眾所周知C++的學(xué)習(xí)成本是很高的迅耘,作者雖然也用C++實(shí)現(xiàn)了行駛證判斷工程,但希望通過我們所熟悉的Java來編寫上層监署,調(diào)用中間件JNI颤专,然后再使用底層C++庫(kù)。如圖架構(gòu)
好钠乏,廢話不多講栖秕,直接配置環(huán)境。
配置步驟
一.安裝IntelliJ
國(guó)內(nèi)有很多破解版本的鏈接可以使用晓避,目前最新破解版15.0.2
二.安裝MacPorts
作者M(jìn)ac下裝有HomeBrew簇捍,也確實(shí)用它安裝過C++版本的只壳。但是裝Java版本的遇到問題,
就是-with java命令提示不存在暑塑,未找到解決辦法吼句,
所以用了同類產(chǎn)品,但是它下載很慢事格,作者用了4個(gè)小時(shí)惕艳,
主要它要下載相關(guān)的所有依賴,而不是使用系統(tǒng)里已經(jīng)有的分蓖,
這一點(diǎn)也是優(yōu)點(diǎn)尔艇,因?yàn)椴灰蕾囅到y(tǒng),HomeBrew則不同么鹤,比如你無意刪掉其中一個(gè)依賴终娃,恐怕就影響使用了。
安裝MacPorts需要Xcode環(huán)境蒸甜,如何安裝請(qǐng)參考MacPorts官網(wǎng)棠耕,并配置環(huán)境變量。
如果不懂柠新,則可以鍵入到MacPorts的安裝目錄下使用下面命令窍荧。實(shí)在不會(huì)操作,再給作者留言恨憎。
鍵入命令
sudo port install opencv +java
它下載后的opencv放在了文件夾
/opt/local/share/OpenCV
并且你會(huì)看到一個(gè)java文件夾里面有2個(gè)文件分別是(以3.2.0版本為例)
libopencv_java320.dylib
opencv-320.jar
前者是動(dòng)態(tài)鏈接庫(kù)蕊退,JNI 在Windows上結(jié)尾就是.dll咯
后者是jar包
這兩個(gè)包對(duì)接下來配置是至關(guān)重要的,你只要記住路徑就可以了憔恳。路徑再打一遍
/opt/local/share/OpenCV/java/libopencv_java320.dylib
/opt/local/share/OpenCV/java/opencv-320.jar
接下來啟動(dòng)IntellJ進(jìn)行配置
1.添加 opencv-320.jar
2.添加依賴libopencv_java320.dylib
-Djava.library.path=/opt/local/share/OpenCV/java
分別為圖1和圖2展示瓤荔,然后本文結(jié)束
給出測(cè)試?yán)樱⒁庾约簞?chuàng)建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();
}
}
對(duì)了程梦,在Java中沒有方便的通過 imShow()來展示一張圖点把,所以封裝了一個(gè)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測(cè)試時(shí)調(diào)用該方法屿附,圖像會(huì)一閃而過郎逃,可通過sleep()等方式暫時(shí)顯示
*
* @param
*/
public ImageViewer(Mat image) {
this.image = image;
}
/**
* @param image 要顯示的mat
* @param windowName 窗口標(biāo)題
*/
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);// 用戶點(diǎn)擊窗口關(guān)閉
}
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); // 獲取所有的像素點(diǎn)
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;
}
全文完結(jié)