OpenCV 4.12.0
開源計算機視覺
載入中...
搜尋中...
無匹配項
Java 開發簡介

上一個教程: Image Watch:在 Visual Studio 偵錯程式中檢視記憶體中的影像
下一個教程: 在 Eclipse 中使用 OpenCV Java

原始作者Eric Christiansen 和 Andrey Pavlenko
相容性OpenCV >= 3.0
警告
本教程可能包含過時的資訊。

從 OpenCV 2.4.4 版本開始,OpenCV 支援桌面 Java 開發,其介面與 Android 開發的介面幾乎相同。本指南將幫助您使用 OpenCV 建立您的第一個 Java(或 Scala)應用程式。我們將使用 Apache AntSimple Build Tool (SBT) 來構建應用程式。

如果您想使用 Eclipse,請參閱在 Eclipse 中使用 OpenCV Java。閱讀本指南後,如需進一步閱讀,請參閱Android 開發入門教程。

本指南內容概覽

在本指南中,我們將

  • 獲取支援桌面 Java 的 OpenCV
  • 建立一個 Ant 或 SBT 專案
  • 用 Java 或 Scala 編寫一個簡單的 OpenCV 應用程式

OpenCV 倉庫的 samples/java 資料夾中的示例也是使用相同過程建立的,因此如果您遇到困難,可以查閱這些檔案。

獲取合適的 OpenCV

從 2.4.4 版本開始,OpenCV 包含了桌面 Java 繫結。

下載

最簡單的方法是從 OpenCV SourceForge 倉庫下載2.4.4 或更高版本的相應軟體包。

注意
Windows 使用者可以在軟體包內的 opencv/build/java/ 資料夾中找到 Java 開發所需的預構建檔案。對於其他作業系統,需要從原始碼構建 OpenCV。

獲取 OpenCV 原始碼的另一種選擇是克隆 OpenCV Git 倉庫。為了構建帶有 Java 繫結的 OpenCV,您需要安裝 JDK (Java Development Kit)(我們推薦 Oracle/Sun JDK 6 或 7)、Apache Ant 和 Python v2.6 或更高版本。

構建

讓我們構建 OpenCV

git clone git://github.com/opencv/opencv.git
cd opencv
git checkout 2.4
mkdir build
cd build

生成 Makefile 或 MS Visual Studio* 解決方案,或您系統中用於構建可執行檔案的任何內容

cmake -DBUILD_SHARED_LIBS=OFF ..

或者

cmake -DBUILD_SHARED_LIBS=OFF -G "Visual Studio 10" ..
注意
當 OpenCV 作為一組靜態庫構建時(-DBUILD_SHARED_LIBS=OFF 選項),Java 繫結動態庫是完全自給自足的,即它不依賴於其他 OpenCV 庫,但內部包含了所有 OpenCV 程式碼。

檢查 CMake 的輸出,確保 java 是“待構建”模組之一。如果不是,您很可能缺少一個依賴項。您應該透過檢視 CMake 輸出中任何未找到的 Java 相關工具並安裝它們來解決問題。

注意
如果 CMake 無法在您的系統中找到 Java,請在執行它之前設定 JAVA_HOME 環境變數,使其指向已安裝的 JDK 路徑。例如:
export JAVA_HOME=/usr/lib/jvm/java-6-oracle
cmake -DBUILD_SHARED_LIBS=OFF ..

現在開始構建

make -j8

或者

msbuild /m OpenCV.sln /t:Build /p:Configuration=Release /v:m

此外,所有這些操作還將建立一個包含 Java 介面的 jar 檔案(bin/opencv-244.jar)以及一個包含 Java 繫結和所有 OpenCV 內容的本地動態庫(分別是 lib/libopencv_java244.sobin/Release/opencv_java244.dll)。我們稍後將使用這些檔案。

使用 Ant 的 Java 示例

注意
所述示例隨 OpenCV 庫提供,位於 opencv/samples/java/ant 資料夾中。
  • 建立一個資料夾,用於開發此示例應用程式。
  • 在該資料夾中,使用任何文字編輯器建立包含以下內容的 build.xml 檔案
    <project name="SimpleSample" basedir="." default="rebuild-run">
    <property name="src.dir" value="src"/>
    <property name="lib.dir" value="${ocvJarDir}"/>
    <path id="classpath">
    <fileset dir="${lib.dir}" includes="**/*.jar"/>
    </path>
    <property name="build.dir" value="build"/>
    <property name="classes.dir" value="${build.dir}/classes"/>
    <property name="jar.dir" value="${build.dir}/jar"/>
    <property name="main-class" value="${ant.project.name}"/>
    <target name="clean">
    <delete dir="${build.dir}"/>
    </target>
    <target name="compile">
    <mkdir dir="${classes.dir}"/>
    <javac includeantruntime="false" srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"/>
    </target>
    <target name="jar" depends="compile">
    <mkdir dir="${jar.dir}"/>
    <jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
    <manifest>
    <attribute name="Main-Class" value="${main-class}"/>
    </manifest>
    </jar>
    </target>
    <target name="run" depends="jar">
    <java fork="true" classname="${main-class}">
    <sysproperty key="java.library.path" path="${ocvLibDir}"/>
    <classpath>
    <path refid="classpath"/>
    <path location="${jar.dir}/${ant.project.name}.jar"/>
    </classpath>
    </java>
    </target>
    <target name="rebuild" depends="clean,jar"/>
    <target name="rebuild-run" depends="clean,run"/>
    </project>
    注意
    此 XML 檔案可用於構建其他 Java 應用程式。它描述了第 3 - 12 行中的通用資料夾結構以及用於編譯和執行應用程式的通用目標。重用此 XML 檔案時,請不要忘記修改第 1 行中的專案名稱,該名稱也是主類的名稱(第 14 行)。OpenCV jar 和 jni 庫的路徑預期為引數(第 5 行中的“${ocvJarDir}”和第 37 行中的“${ocvLibDir}”),但為了方便起見,您可以硬編碼這些路徑。有關其構建檔案格式的詳細說明,請參閱 Ant 文件
  • build.xml 檔案旁邊建立一個 src 資料夾,並在其中建立一個 SimpleSample.java 檔案。
  • 將以下 Java 程式碼放入 SimpleSample.java 檔案中
    import org.opencv.core.Core;
    import org.opencv.core.Mat;
    import org.opencv.core.CvType;
    import org.opencv.core.Scalar;
    class SimpleSample {
    static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }
    public static void main(String[] args) {
    System.out.println("Welcome to OpenCV " + Core.VERSION);
    Mat m = new Mat(5, 10, CvType.CV_8UC1, new Scalar(0));
    System.out.println("OpenCV Mat: " + m);
    Mat mr1 = m.row(1);
    mr1.setTo(new Scalar(1));
    Mat mc5 = m.col(5);
    mc5.setTo(new Scalar(5));
    System.out.println("OpenCV Mat data:\n" + m.dump());
    }
    }
    int main(int argc, char *argv[])
    定義 highgui_qt.cpp:3
  • 在包含 build.xml 的資料夾中,在控制檯中執行以下命令
    ant -DocvJarDir=path/to/dir/containing/opencv-244.jar -DocvLibDir=path/to/dir/containing/opencv_java244/native/library
    例如
    ant -DocvJarDir=X:\opencv-2.4.4\bin -DocvLibDir=X:\opencv-2.4.4\bin\Release
    該命令應啟動示例的 [重新]構建和執行。您應該在螢幕上看到類似以下內容:

用於 Java 和 Scala 的 SBT 專案

現在我們將使用 SBT 建立一個簡單的 Java 應用程式。這為不熟悉此構建工具的人提供了一個簡要的介紹。我們使用 SBT 是因為它特別簡單且功能強大。

首先,根據 SBT 網站上的說明下載並安裝 SBT

接下來,導航到一個新目錄,您希望應用程式原始碼位於該目錄中(在 opencv 目錄之外)。我們稱之為“JavaSample”併為其建立一個目錄

cd <somewhere outside opencv>
mkdir JavaSample

現在我們將建立必要的資料夾和一個 SBT 專案

cd JavaSample
mkdir -p src/main/java # 這是 SBT 期望找到 Java 原始碼的位置
mkdir project # 這是構建定義所在的位置

現在在您喜歡的編輯器中開啟 project/build.scala 並貼上以下內容。它定義了您的專案

import sbt._
import Keys._
object JavaSampleBuild extends Build {
def scalaSettings = Seq(
scalaVersion := "2.10.0",
scalacOptions ++= Seq(
"-optimize",
"-unchecked",
"-deprecation"
)
)
def buildSettings =
Project.defaultSettings ++
scalaSettings
lazy val root = {
val settings = buildSettings ++ Seq(name := "JavaSample")
Project(id = "JavaSample", base = file("."), settings = settings)
}
}

現在編輯 project/plugins.sbt 並貼上以下內容。這將啟用 Eclipse 專案的自動生成

addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0")

現在從 JavaSample 根目錄執行 sbt,並在 SBT 內部執行 eclipse 以生成 Eclipse 專案

sbt # 啟動 sbt 控制檯
eclipse # 從 sbt 控制檯內部執行“eclipse”

您應該看到類似以下內容:

您現在可以使用“匯入... -> 將現有專案匯入工作區”將 SBT 專案匯入 Eclipse。您是否實際執行此操作對於本指南來說是可選的;我們將使用 SBT 構建專案,因此如果您選擇使用 Eclipse,它將僅充當文字編輯器。

為了測試一切是否正常工作,建立一個簡單的“Hello OpenCV”應用程式。透過建立檔案 src/main/java/HelloOpenCV.java 幷包含以下內容來完成此操作

public class HelloOpenCV {
public static void main(String[] args) {
System.out.println("Hello, OpenCV");
}

}

現在從 sbt 控制檯執行 run,或者更簡潔地,從命令列執行 sbt run

sbt run

您應該看到類似以下內容:

執行 SBT 示例

現在我們將使用 OpenCV 建立一個簡單的面部識別應用程式。

首先,建立一個 lib/ 資料夾並將 OpenCV jar 複製到其中。預設情況下,SBT 將 lib 資料夾中的 jar 新增到 Java 庫搜尋路徑中。您可以選擇重新執行 sbt eclipse 來更新您的 Eclipse 專案。

mkdir lib
cp <opencv_dir>/build/bin/opencv_<version>.jar lib/
sbt eclipse

接下來,建立目錄 src/main/resources 並將此 Lena 影像下載到其中

確保它名為 "lena.png"。資源目錄中的專案在執行時可供 Java 應用程式使用。

接下來,將 lbpcascade_frontalface.xmlopencv/data/lbpcascades/ 複製到 resources 目錄中

cp <opencv_dir>/data/lbpcascades/lbpcascade_frontalface.xml src/main/resources/

現在修改 src/main/java/HelloOpenCV.java,使其包含以下 Java 程式碼

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.objdetect.CascadeClassifier;
//
// 在影像中檢測人臉,在人臉周圍繪製框,並將結果寫入
// "faceDetection.png"。
//
class DetectFaceDemo {
public void run() {
System.out.println("\nRunning DetectFaceDemo");
// 從資源目錄中的級聯檔案建立人臉檢測器。
// directory.
CascadeClassifier faceDetector = new CascadeClassifier(getClass().getResource("/lbpcascade_frontalface.xml").getPath());
Mat image = Imgcodecs.imread(getClass().getResource("/lena.png").getPath());
// 在影像中檢測人臉。
// MatOfRect 是 Rect 的特殊容器類。
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(image, faceDetections);
System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));
// 在每個人臉周圍繪製一個邊界框。
for (Rect rect : faceDetections.toArray()) {
Imgproc.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0));
}
// 儲存視覺化檢測結果。
String filename = "faceDetection.png";
System.out.println(String.format("Writing %s", filename));
Imgcodecs.imwrite(filename, image);
}
}
public class HelloOpenCV {
public static void main(String[] args) {
System.out.println("Hello, OpenCV");
// 載入本地庫。
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
new DetectFaceDemo().run();
}
}

請注意對 System.loadLibrary(Core.NATIVE_LIBRARY_NAME) 的呼叫。在使用任何本地 OpenCV 方法之前,此命令必須在每個 Java 程序中精確執行一次。如果您不呼叫它,將會遇到 UnsatisfiedLink 錯誤。如果您嘗試載入已載入的 OpenCV,也會出現錯誤。

現在使用 `sbt run` 執行人臉識別應用程式

sbt run

您應該看到類似以下內容:

它還應該將以下影像寫入 faceDetection.png

您已完成!現在您有了一個使用 OpenCV 的 Java 示例應用程式,因此您可以開始自己的工作了。祝您好運,生活愉快!