Java OpenCV Lv2 〜JavaFXでの画像表示〜

イントロダクション

前回は、写真などを表示しようと試みましたがImShowメソッドが使用できないということで、JavaFXを使用してやる方向にしました。

参考サイト;Java版OpenCVチュートリアル(英語です)

<工程>

  1. Eclipseのインストール
  2. OpenCVインストール
  3. JavaでOpenCVのライブラリを起動する(工程2の記事でやりました)
  4. JavaFXで写真を表示してみる(今回実行します)

画像(イメージ)表示の準備

こちらのサイトを参考にしてやります。

大雑把に上記の<工程>にあるようなことが書いてありました。今までに<工程>の1、2をやったので3からいきます。

<前提>

JavaFXでの画面作成のためにSceneBuiderをセットアップします。

  1. Eclipse SceneBuilderを追加する
  2. JavaFX SceneBuilder 〜EclipseとSceneBuilder連携~


JavaFXの実装

ソースコードはGITにあるものを参照(参考サイトより)

<今回の作成するアプリ構成>

ソースはGitにアップロードしてあります。

<Main.java>

import org.opencv.core.Core;

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.fxml.FXMLLoader;

/**
 * OpenCVnogaの学習用のGUIを作成する。
 * JavaFXで画面を作成している
 * 1.SceneBuilderでFXMLを出力
 * 2.FXMLで取得したコンポーネントを表示する
 * 
 * @author takunoji
 * 2018/11/18
 */
public class Main extends Application {
	/**
	 * このアプリケーション(Mainメソッド)が起動する前に
	 * 起動(OpenCVのロード)する
	 */
	static {
		System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
	}
	/**
	 * スーパクラスApplication)のstartメソッドを起動する
	 * オーバーライドしているので、本当は親クラスのメソッドが起動するが
	 * 子クラスで上書きするので、このクラスを起動した時にはこちらのメソッドが起動する。
	 */
	@Override
	public void start(Stage primaryStage) {
		try {
			// FXMLをロード
			BorderPane root = (BorderPane)FXMLLoader.load(getClass().getResource("OpenCvTest.fxml"));
			// 表示領域を作成する
			Scene scene = new Scene(root,400,400);
			// JavaFX用のCSSを適用する
			scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
			// Sceneをステージに設定する
			primaryStage.setScene(scene);
			// 表示処理
			primaryStage.show();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * メインメソッド。
	 * JavaFXの規定部品
	 * Application{@link #start(Stage)}を起動する
	 * 
	 * @param args プログラム引数
	 */
	public static void main(String[] args) {
		// スーパークラス(親)のメソッドを起動する
		launch(args);
	}
}

<OpenCvController.java>

/**
 * FXMLで定義したコントローラクラス。
 * 参考サイトを写経しようとしたが、ソースを少しいじる
 * 基本的には写経している。
 * @see 
 * @author takunoji
 * 2018/11/17
 */
public class OpenCvController {
	 /** FXML定義のボタン */
	@FXML
	private Button button;
	/** FXML定義のImageViewer */
	@FXML
	private ImageView currentFrame;
	
	/** ビデオキャプチャ */
	private VideoCapture capture = new VideoCapture();
	
	private ScheduledExecutorService timer;
	// a flag to change the button behavior
	private boolean cameraActive = false;
	// the id of the camera to be used
	private static int cameraId = 0;
	
	/**
	 * ボタン押下時のアクション処理。
	 * "@FXML"アノテーションでFXMLとの同期を取っている
	 * @param event ボタン押下のイベント
	 */
	@FXML
	protected void startCamera(ActionEvent event) {
		// カメラがアクティブ状態の時は停止する
		if (this.cameraActive) {
			this.cameraActive = false;
			this.button.setText("Start Camera");
			this.stopAcquisition();
			// 処理終了
			return;
		}
		// カメラ
		this.capture.open(this.cameraId);
		// カメラが開いていない時
		if (this.capture.isOpened() == false) {
			// エラーログを出力して処理を終了する
			System.err.println("Impossible to open the camera connection...");
			return;
		}
		// カメラが正常に開いている時
		this.cameraActive = true;
		// 匿名クラス
		Runnable frameGrabber = new Runnable() {
			@Override
			public void run() {
				Mat frame = grabFrame();
				Image imageToShow = Utils.mat2Image(frame);
				updateImageView(currentFrame, imageToShow);
			}
		};
		this.timer = Executors.newSingleThreadScheduledExecutor();
		this.timer.scheduleAtFixedRate(frameGrabber, 0, 33, TimeUnit.MILLISECONDS);
		this.button.setText("Stop Camera");
	}

	/**
	 * 開いているビデオストリームからフレームを取得する
	 * @return {@link Mat}
	 */
	private Mat grabFrame() {
		Mat frame = new Mat();
		if (this.capture.isOpened()) {
			try {
				this.capture.read(frame);
				if (frame.empty() == false) {
					Imgproc.cvtColor(frame, frame, Imgproc.COLOR_BGR2GRAY);
				}
				
			} catch(Exception e) {
				System.err.println("Exception during the image elaboration: " + e);
			}
		}
		return frame;
	}

	private void stopAcquisition() {
		if (this.timer != null && this.timer.isShutdown() == false) {
			try {
				this.timer.shutdown();
				this.timer.awaitTermination(33, TimeUnit.MICROSECONDS);
			} catch(Exception e) {
				// log any exception
				System.err.println("Exception in stopping the frame capture, trying to release the camera now... " + e);
			}
		}
		// @FIXME-[カメラを解放するだけで良い?]
		if (this.capture.isOpened()) {
			this.capture.release();
		}
	}
		/**
		 * Update the {@link ImageView} in the JavaFX main thread
		 * 
		 * @param view
		 *            the {@link ImageView} to update
		 * @param image
		 *            the {@link Image} to show
		 */
		private void updateImageView(ImageView view, Image image) {
			Utils.onFXThread(view.imageProperty(), image);
		}
		
		/**
		 * On application close, stop the acquisition from the camera
		 */
		protected void setClosed() {
			this.stopAcquisition();
		}
}

ボタンを押下したらエラーが出た!

下のキャプチャのようにbottunの変数名とIDが違っていると次のようなエラーが出ます。

 

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException

<BorderPane xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="zenryokuservice.opencv.fx.OpenCvController">
   <center>
      <BorderPane prefHeight="522.0" prefWidth="410.0" BorderPane.alignment="CENTER">
         <bottom>
            <Button fx:id="start_btn" mnemonicParsing="false" onAction="#startCamera" text="StartCamera" BorderPane.alignment="CENTER" />
         </bottom>
         <center>
            <ImageView fx:id="currentFrame" fitHeight="248.0" fitWidth="234.0" pickOnBounds="true" preserveRatio="true" BorderPane.alignment="CENTER" />
         </center>
      </BorderPane>
   </center>
</BorderPane>

上のコード赤字の部分を変数名に合わせます。「button」に修正。

[rakuten ids="0909fd:10003689"]

<問題>

このVideoCaptureを起動し、閉じるときにメモリの使用量の部分(そのほかにもあるかも?)で問題があります。

ソースの方では、カメラを停止したときに「System.gc()」でメモリを解放するようにしたのですが、操作を早くするとクラッシュします。

この部分は、根深い問題なのでとりあえずは、飛ばしてOpenCVを学んでいくようにします。。。

エラーログ

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007fffcfe13017, pid=1748, tid=0x000000000001560f
#
# JRE version: Java(TM) SE Runtime Environment (8.0_144-b01) (build 1.8.0_144-b01)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.144-b01 mixed mode bsd-amd64 compressed oops)
# Problematic frame:
# C  [libobjc.A.dylib+0x7017]  objc_msgSend+0x17
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /XXX/git/OpenCvFX/OpeCvFX/hs_err_pid1748.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

 

関連ページ一覧

<JavaFXの準備>

  1. EclipseにSceneBuilderを追加する
  2. JavaFX SceneBuilder 〜EclipseとSceneBuilder連携~
  3. Java OpenCv Lv1 〜入門: 写真の表示〜
  4. Java OpenCV Lv2 〜JavaFXでの画像表示〜
    1. バグを回収しました。

Java OpenCv Lv1 〜入門: 写真の表示〜

イントロダクション

前々回に、家計簿アプリのグラフ部分を作成が一区切りついたので今度は入力部分を作成しようとOpenCvに着手しました。

今までにやってきたこと

そして、入力部分は手入力を行いたくないのでアプリケーションに入力させようと思うのです。つまり、アプリのユーザーはレシートの写真をとるだけ(カテゴリの追加などは別です)という仕様にしようと思い現在に至る次第です。

まずは、OpenCv in Javaと、JUnitのセットアップを行いました。

OpenCvを学ぶ

画像から文字を取得することが最優先なのですが、なんだかんだと初めから学ぶことになりそうなので初っ端から学び始めてしまおうと思います。※OpenGLをやった時に途中から学んだけど初めからやり直しました。。。

参考にするサイトはこちらです。
OpenCVのチュートリアルを掲載しているサイトです。

OpenCVチュートリアル

このサイトでは、JavaFXを使用して以下のことを行っています。

  1. OpenCV(Javaバインド)のインストール
  2. OpenCV を使用した初めての Java アプリケーション
  3. OpenCV の基礎
  4. フーリエ変換
  5. 顔の検出と追跡
  6. 画像セグメンテーション
  7. 物体検出
  8. カメラのキャリブレーション

ここで使用するツール

SceneBuilderを使用します。

使用したときの動画です。GUIで画面の作成ができます。HTMLをGUIでつくるのに似ています。




画像を表示する

上のツイート画像にある様にその本に書いてあることを実行します。よくわからなかったら、とりあえず進んで見れば良いのです。

※危険な事は神経質になった方が良い、痛い目にあいます。。。

そんなわけで、上記の18ぺーじにC/C++で書かれたソースがあります。そいつをJavaに書き換えて実行します。

駄菓子菓子、OpenCV3.XからはImShowメソッドが、HightGUIが使用できない(しない)仕様になったということで。。。

JavaFXで実装します。続きは以下参照でお願いします。

Eclipse SceneBuilderを追加する – PGボックス

JavaFX SceneBuilder 〜EclipseとSceneBuilder連携~ – PGボックス

関連ページ一覧

  1. Java OpenCV 環境セットアップ(on Mac)
  2. Java OpenCv Lv1 〜入門: 写真の表示〜
  3. Java OpenCV Lv2 〜画像を表示する〜
  4. Java OpenCV Lv3 〜画像の平滑化(smooth())〜
  5. Java OpenCV Lv3 〜画像にガウシアンフィルタ(GaussianBlur())〜
  6. Java OpenCV Lv3 〜画像に中央値フィルタ(medianBlur())〜
  7. Java OpenCV Lv4 〜画像の中身をみてみる〜
  8. Java OpenCV Lv5 〜Matクラスで描画処理〜
  9. Java OpenCV Lv6 〜Matクラスで背景から作成してみる〜
  10. Java OpenCV Lv7 〜MatクラスでEllipseしてみる〜
  11. Java OpenCV Lv9 〜画像編集「足し算」(cvAdd)〜
  12. Java OpenCV Lv9 〜画像編集「引き算」(cvSubtract)〜
  13. Java OpenCV Lv9 〜画像の掛け算〜
  14. Java OpenCV Lv10 〜行列演算Mat#submat()〜
  15. Java OpenCv Lv10〜画像の平均値をだす〜

IntelliJ Eclipse SceneBuilderを追加する

イントロダクション

OpenCVの学習を始めるのは良いが、JavaFXを使用する様で。。。(画面の確認などのため)
ここでは、IntelliJとEclipseでの環境構築について記載します。

SceneBuilderはこんな感じ1

SceneBuilderはこんな感じ2

IntelliJのセットアップ

単純に次の手順でOKです。

  1. SceneBuilderをダウンロードしてインストール※GLUONのサイトからダウンロード
  2. File→Settings→Language & Frameworks→JavaFXからSceneBuilderのパスを登録

ショート動画で手順を見る

共通手順

参照したページはOpenCVのチュートリアルです。
仕方ないのでプラグインを追加することにしました。

上記のチュートリアルでは、OpenCVを使用してプログラムを組むときのやり方をJavaFXで画面表示してやるものでした。

下の動画には雑音が入っています。

e(fx)clipseプラグインの追加

こちらのページを参考に、マーケットプレイスからインストールできます。

SceneBuilderのインストール

オラクルのサイトからダウンロードする様です。

スクリーンショット 2018-11-17 15.20.53.png

自分は、Macを使用しているので「dmg」ファイルを選択します。

スクリーンショット 2018-11-17 15.22.31.png

こんな感じでインストールします。

Windows版SceneBuilderのインストール

こちらのサイトからダウンロードします。
インストーラーがダウンロードできるので、それでインストールします。
しかし、そのままインストールすると文字化けました。

どうやらバージョンを間違ったようです。自分のPCにインストールしているJavaのバージョンを確認してください。コマンドプロンプトを起動して以下のコマンドを叩きます。

java -version

確認ができたらダウンロードしたscenebuilder-8.5.0-all.jarを起動するためのBATファイルを作成します。

java -jar SceneBuilderをインストールしたディレクトリまでのパス\scenebuilder-8.5.0-all.jar

自分の場合は下のようなコマンドになりました。

java -jar Apps\SceneBuilder\scenebuilder-8.5.0-all.jar

このコマンドをテキストファイルに「FX.BAT]という名前で保存します。そして実行

まだ、文字化けしています。。。

これは、Githubからプロパティファイルをダウンロードして、ファイルを置き換える

  1. 「scenebuilder-8.5.0-all.jar」ファイルの拡張子を「.zip」に変更する
  2. エクスプローラで「scenebuilder-8.5.0-all.zip」ファイルの中身を表示する
  3. コピー&ペーストなどで「SceneBuilderApp_ja.properties」ファイルを上書きする
  4. 「scenebuilder-8.5.0-all.zip」ファイルの拡張子を「.jar」に戻す

しかし、更新するファイルのパスが見当たらないため、別のインストーラーをダウンロードしてやると「英語」だったけど文字化けしない。。。
のでまぁ良しとします。
ちなみにダウンロードしたのは、「javafx_scenebuilder-2_0-windows.msi」です。

Eclipseでの起動

Eclipseで設定を開き、JavaFXを選択します。すると右のほうにボタンがあるのでそいつをクリックすると。。。

スクリーンショット 2018-11-17 15.25.42.png

ファイルを選択する様に言われますので、先ほどインストールしたApplicationを参照するとSceneBuilderが見つかります。これを選択して設定します。

スクリーンショット 2018-11-17 15.24.35.png

そしてFXMLファイルを右クリックして起動します。

https://www.youtube.com/watch?v=w9BubZIEGdg&feature=youtu.be

 

JavaFX関連ページ

  1. Eclipse SceneBuilderを追加する
  2. JavaFX SceneBuilder 〜EclipseとSceneBuilder連携~
  3. JavaFX SceneBuilder〜ボタンにメソッドを割り当てるワンポイント〜
  4. Java プロコンゲーム 〜見た目の作成(SceneBuilderの使用)〜

関連ページ一覧

Eclipse セットアップ

  1. Java Install Eclipse〜開発ツールのインストール〜
  2. TensorFlow C++環境〜EclipseCDTをインストール〜
  3. Setup OpenGL with JavaJOGLを使う準備 for Eclipse
  4. Eclipse Meven 開発手順〜プロジェクトの作成〜
  5. Java OpenCV 環境セットアップ(on Mac)
  6. Eclipse SceneBuilderを追加する
  7. JavaFX SceneBuilder EclipseSceneBuilder連携~

Java Basic一覧

  1. Java Basic Level 1 〜Hello Java〜
  2. Java Basic Level2 〜Arithmetic Calculate〜
  3. Java Basic Level3 〜About String class〜
  4. Java Basic Level 4〜Boolean〜
  5. Java Basic Level 5〜If Statement〜
  6. Java Basic Summary from Level1 to 5
  7. Java Basic Level 6 〜Traning of If statement〜
  8. Java Basic Level8 〜How to use for statement〜
  9. Java Basic Level 8.5 〜Array〜
  10. Java Basic Level 9〜Training of for statement〜
  11. Java Basic Level 10 〜While statement 〜
  12. Java Basic Swing〜オブジェクト指向〜
  13. Java Basic Swing Level 2〜オブジェクト指向2〜
  14. サンプル実装〜コンソールゲーム〜
  15. Java Basic インターフェース・抽象クラスの作り方
  16. Java Basic クラスとは〜Step2_1〜
  17. Java Basic JUnit 〜テストスイートの作り方〜

Git関連

  1. Java Git clone in Eclipse 〜サンプルの取得〜
  2. Eclipse Gitリポジトリの取得 GitからソースをPullしよう〜
  3. IntelliJ IDEA GitGitリポジトリからクローン〜

Java OpenCv Hello in Java〜OpenCv事始め〜

イントロダクション

ついに最近流行りの技術「人工知能」への入り口画像解析を始めたいと思います。以前、中途半端にPythonでOpenCvを使ったのですが、すごく簡単に扱えて「あ〜したらこ〜なる」なんてことを考えさせられる。。。そんなフレームワークだと思います。

参考サイト:OpenCV-ReadingImages

 

OpenCVは、どんなものなのか?

事始めということで

年の瀬も近いのに「事始め」とはおかしな話ですが。。。思い立ったが吉日やらないわけには行きません。
そんなわけで早速サンプルコードを見てみます。とりあえずはどんな動きをするのか見てみようということです。

import org.opencv.core.Core; 
import org.opencv.core.Mat;  
import org.opencv.imgcodecs.Imgcodecs;

public class ReadingImages {
   public static void main(String args[]) { 
      //Loading the OpenCV core library  
      System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); 

      //Instantiating the Imagecodecs class 
      Imgcodecs imageCodecs = new Imgcodecs(); 

      //Reading the Image from the file  
      String file ="C:/EXAMPLES/OpenCV/sample.jpg"; 
      imageCodecs.imread(file);

      System.out.println("Image Loaded");     
   } 
}

赤字で書いている部分が気になったのでJavaDocAPIを参照してみます。

参考サイトからコードをパクった感じにして以下の様にコードを組みました。

<読み込んだ画像>



<実行結果>

import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;

/**
 * OpenCVの機能を実装するクラス。
 * 
 * @author takunoji
 *
 * 2018/11/11
 */
public class ReceiptCv {
    Imgcodecs imgCodecs;
    static {
        System.loadLibrary("opencv_java343");
    }

    public static void main(String[] args) {
        ReceiptCv rece = new ReceiptCv();
        rece.loadImg("download-1.jpg");
    }

    /**
     * コンストラクタ
     */
    public ReceiptCv() {
        imgCodecs = new Imgcodecs();

    }

    private void loadImg(String fileName) {
        Mat matrix = Imgcodecs.imread(getClass().getResource("/sampleImages/" + fileName).getPath());
        System.out.println("type: " + matrix.type());
        System.out.println("dims: " + matrix.dims());
        System.out.println("height: " + matrix.height());
        System.out.println("width: " + matrix.width());
        System.out.println("rows: " + matrix.rows());
        System.out.println("cols: " + matrix.cols());
    }

    public void helloCv() {
        Mat m = Mat.eye(3, 3, CvType.CV_8UC1);
        System.out.println("m = " + m.dump());
    }
}

OpenCV事はじめ

処理の概要

  1. メインメソッドでこのクラスをインスタンス化、loadImg()に「”download-1.jpg"」を私て実行します
  2. "resources/sampleImages/download-1.jpg"を読み込んでMatを返します、
  3. Matの中身をコンソールに表示 

読み込んだ画像は「レシート」です。家計簿を書く時に使うでしょ?(笑)

OpenCVは画像を読み込んで何かしらの画像編集処理を行うフレームワーク(ライブラリ)ということで、画像ファイルを読み込んでみました。

灰色に変換「グレースケース化」や指定した色のン領域をを表示したり、いろいろなことができるようです。

でわでわ。。。

関連ページ

  1.  Java OpenCV 環境セットアップ(on Mac)
  2. Java Install Eclipse〜開発ツールのインストール〜
  3. Java Doc読解 BufferedReader
  4. Java Doc 読解〜BufferedWriter〜

 

ラズパイにJava OpenCV 環境セットアップ

この記事の概要

  1. JavaCV for Raspberry Piをインストール
  2. ラズパイ用OpenCVのセットアップ → 失敗、C言語,Pythonでのインストールだった。
  3. Mac用OpenCVのセットアップ※古いです。

イントロダクション for JavaCV

下の方に記述している、書くOpenCVのインストールに関して、インストールは結局C言語とPythonでの利用時のインストールになっていました。
どうやら「JavaCV」がインストールするべきものだったようです。
上記のリンクを参考に実行すると下のようなコマンドをたたきます。

jarファイルのダウンロードはこちらからできるようです。

ここから jar をダウンロードすることができます: https://drive.google.com/folderview?id=0B0lFIImWo61bc3pTTHdZN3NmNkE&usp=sharing

すべてのコンパイラ ツールとビデオ ライブラリを取得

下のコマンドをたたき、必要なツールをインストールする

sudo apt-get update
sudo apt-get install build-essential cmake pkg-config libpng12-0 libpng12-dev libpng++-dev libpng3 \n
libpnglite-dev libpngwriter0-dev libpngwriter0c2 zlib1g-dbg zlib1g zlib1g-dev pngtools libtiff4-dev \n
libtiff4 libtiffxx0c2 libtiff-tools libjpeg8 libjpeg8-dev libjpeg8-dbg libjpeg-progs ffmpeg libavcodec-dev \n
libavcodec52 libavformat52 libavformat-dev libgstreamer0.10-0-dbg libgstreamer0.10-0  libgstreamer0.10-dev \n
libxine1-ffmpeg  libxine-dev libxine1-bin libunicap2 libunicap2-dev libdc1394-22-dev libdc1394-22 libdc1394-utils \n
swig libv4l-0 libv4l-dev

システム内のSOファイルをリンクする

sudo ldconfig

JavaCVのソースを取得

git clone https://github.com/bytedeco/javacv.git

OpenCVと接続するためのC++のソースを取得

git clone https://github.com/bytedeco/javacpp.git

JavaCVのソースをコンパイルする

cd javacv
mvn clean install -Dplatform.name=linux-arm

イントロダクション for Raspberry Pi

OpenCVをラズパイにインストールして、定点観測をやりたいと思いました。
そんなわけで、早速セットアップを行いたいと思います。セットアップする項目としては以下の通りです。

  • GUI作成用のJavaFXのインストール
  • OpenCVのインストール
  • ハローOpenCV プログラムの実行確認

JavaFXのインストール

ラズパイにJavaFXをインストールします。OpenCVのチュートリアルでは、JavaFXを使用していました。
コーディング喪服勝っていますが、下のような感じで動きました。(Eclipse使用)

そんなわけで、今度はラズパイにJavaFXを準備したいと思っております。

JavaFXのセットアップ in RPi

参考にするサイトは、こちらのオラクルのサイトです。
上記の記事は、「JavaFXはJava11に同梱されているので、Java11をインストールしてね」という内容でした。

Javaのインストール

下のコマンドでインストールできます。

$ cd /home/pi 
$ wget https://download.bell-sw.com/java/13/bellsoft-jdk13-linux-arm32-vfp-hflt.deb 
$ sudo apt-get install ./bellsoft-jdk13-linux-arm32-vfp-hflt.deb 

下のコマンドは、各コマンドの設定を変更するものです。※インストールは上で終わり
インストールしたJavaのバージョンを11に切り替えます。

$ sudo update-alternatives --config javac
$ sudo update-alternatives --config java

インストールができたら、下のコマンドで確認します。

$ java --version 
openjdk version "13-BellSoft" 2019-09-17 
OpenJDK Runtime Environment (build 13-BellSoft+33) 
OpenJDK Server VM (build 13-BellSoft+33, mixed mode)

OpenCVのインストール(for Linux)

ラズパイはLinuxです。なのでこちらのチュートリアルにある内容のLinuxの部分を読み進めます。

必要なものをインストールする

次のものが必要になります。参照先は次の\リンク先に記述しています。

Antはsnapをインストールしてからになるので次のようにコマンドをたたきます。

sudo apt update
sudo apt install snapd
sudo reboot
sudo snap install ant --classic

CMakeのインストール

> sudo apt-get -y install cmake
> which cmake
/usr/bin/cmake
> cmake --version
cmake version 2.8.12.2

最新版が欲しい場合は、こちらのリンクからどうぞ

CMake GUIもインストール

※注意点

ここの操作で注意するべきは、次の通りです。

  1. インストールしているJDK、の場所を指定してやるというところです。
    筆者の場合は「/usr/lib/jvm/java-11-openjdk-armhf/」が、その場所なのでJAVAの項目を変更しています。※動画は変更していません。

  2. こちらのサイトを参考にしました。下のコマンドでインストールできます。
    Configureが完了したときには下のように画面が白くなっていることを確認する

    CMake-Guiのインストール

    > sudo apt-get -y install cmake-qt-gui
    > which cmake-gui
    /usr/bin/cmake-gui
    > cmake-gui --version
    cmake version 2.8.12.2

OpenCV(ライブラリ)のダウンロード

こちらのリンクにコマンドがあります。
ソースからビルドする方法です。結構時間がかかります。

# Install minimal prerequisites (Ubuntu 18.04 as reference)
sudo apt update && sudo apt install -y cmake g++ wget unzip
# Download and unpack sources
wget -O opencv.zip https://github.com/opencv/opencv/archive/4.x.zip
unzip opencv.zip
# Create build directory
mkdir -p build && cd build
# Configure
cmake ../opencv-4.x
# Build
cmake --build .

上記でJARができない?

上の操作を行ったけど、肝心のJARが作成されませんでした。もう一度調べOpenCV4の方の手順を使用することにしました。
こちらのページになります。

手順

全部コマンドで実行します。下のコマンドをたたいていくだけです。

  1. OpenCVのZIPファイルをダウンロード
  2. ZIPファイルを解凍
  3. opemcv-4.xという名前のフォルダをopencvに変更
wget -O opencv.zip https://github.com/opencv/opencv/archive/4.x.zip
unzip opencv.zip
mv opencv-4.x opencv

次はビルドするコマンドです。

  1. 出力用のフォルダbuildを作成
  2. cmakeコマンドを実行
  3. makeコマンドの実行、オプション「-j4」をつけ忘れないように注意
  4. make installの実行
mkdir -p build && cd build
cmake ../opencv
make -j4
make install

色々やってみたが、JARファイルが作成されませんでした。。。

ハローOpenCV

JavaでOpenCVが動くことを確認します。
これがハローワールドのもう一つの役目です。早速コードを書きます。

【前提】
上記で作成したライブラリをビルドパスに追加する。
コマンドで実行する場合は下のように行う「/opencv/build/lib」は上記でビルドしてできたJARファイルが配置されているディレクトリになる。

-Djava.library.path=/opencv/build/lib

そして、ハローワールドのコードです。

public class HelloCV {
        public static void main(String[] args){
                System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
                Mat mat = Mat.eye(3, 3, CvType.CV_8UC1);
                System.out.println("mat = " + mat.dump());
        }
}

実行方法

ズバリ、プロジェクト直下で次のコマンドを実行します。コマンドの内容としては次の通りです。

  • JavaCVのJARファイルを参照するようにCPオプションを指定する
    ※CLASSPTH変数を定義してやるとコマンドでHelloCVクラスの参照ができなくなる
  • -DオプションでDLLファイルのあるディレクトリを指定する
  • パッケージ名を含めたクラスの完全修飾名で起動するクラスを指定する
java -cp ".;C:\OpenCV\opencv\build\java\opencv-480.jar" -Djava.library.path="C:\OpenCV\opencv\build\java\x64" "src.main.java.cam.HelloCV"

IDE開発ツールの用意

デフォルトでインストールされているGeanyを使用します。
BlueJだとパッケージを開くたびにウィンドウを開くのである程度の大きさ、ファイル数になるとコーディングが大変なので、今回は使用しません。

インストール

こちらの本家サイトからダウンロード(Windows)

Linux、ラズパイなど

sudo apt-get install geany
sudo apt-get install geany-plugins

インントロダクション for MacOS

画像解析処理を行いたく思い「OpenCV」をセットアップします。

brewコマンドでインストールなどもできる様ですが、GitでPULLするのが一番早いと思いましたので、そのようにやります。

そもそも。。。

機械学習の理解をしようと色々と試みましたが、撃沈。。。(TensorFlow関連では基本的なこと、モデルの作成の理論までは理解できなかった)ので、OpenCVで機械学習を学ぼうとなりました。

OpenCVには色々な「アルゴリズムを使」うとか、ベクトル、パターン認識、特徴量の計算など「機械学習で必要になるであろう」事が記載されていました。

必要な工程

  1. Eclipseのインストールなどのセットアップ
  2. OpenCVのインストール(ここから記載します)
  3. OpenCVのJARファイルとOpenCVのC言語資源(ソース) インストール
  4. OpenCVの起動確認

OpenCVのインストール(makeコマンドを使う)

コマンドを叩いていけばOKですので。。。

参考サイト :本家家元OpenCVのページです。

参考サイト2:JavaでのOpenCVのページ。Javaでやるのでこちらを参照。

 

以下のコマンドを実行します(gitはインストール済みの場合)

>git clone git://github.com/opencv/opencv.git

gitのインストール:このページを参照しました。

>brew install git

そして以下のコマンドと続きます(対象のバージョンは「3.4.3」

>cd opencv
>checkout 3.4.3
>mkdir build
>cd build
>cmake -DBUILD_SHARED_LIBS=OFF ..

そして処理が流れ始め。。。

javaフォルダができたかな?と思いきや。。。「ない」

そんな時は下のコマンドを叩く様です。

>export JAVA_HOME=/usr/lib/jvm/java-6-oracle
>cmake -DBUILD_SHARED_LIBS=OFF ..

「/usr/lib/jvm/java-6-oracle」の部分は自分のマシンで使用するJDKの場所を指定します。自分の場合は以下の様になります。

>export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/
>cmake -DBUILD_SHARED_LIBS=OFF ..
>make -8j

そして、ビルドの結果

javaフォルダがない。。。

と思ったらopencv/binの中にありました。

そんなわけで、以下のコマンドでファイルをビルドパスに繋げやすい様にファイルを移動します。

>cp ./bin/opencv-343.jar ~/Java/OpenCv/
>cp ./lib/libopencv_java343.dylib ~/Java/OpenCv/

リンク先のファイルが「libopencv_java343.dylib」とは違う様ですが、このファイルで良い様です。

Eclipseのプロジェクトを右クリック > Build Pathを選択

Native Libraryを選択して。。。

Native libraryにOpenCVを登録(設定)します。

そして、実行!撃破!!

ソースは下の様になりました。対象のライブラリ部品から定数で参照する値は名前が違う場合がある様です。。。なのでハードコーディング(笑)

import org.opencv.core.CvType;
import org.opencv.core.Mat;

/**
 * OpenCVの部品を実行するクラス。
 * 
 * @author takunoji
 *
 * 2018/11/11
 */
public class ReceiptCv {
    static {
        System.loadLibrary("opencv_java343");
    }
    public static void main(String[] args) {
        new ReceiptCv().helloCv();
    }

    public void helloCv() {
        Mat m = Mat.eye(3, 3, CvType.CV_8UC1);
        System.out.println("m = " + m.dump());
    }
}

そしてImShow(画像表示)→OpenCV3.Xではできません。

OpenCVの3.XからはHightGUIを使用しないようです。なのでJavaFXでイメージの表示を行います。「Java OpenCv Hello in Java〜OpenCv事始め〜

旧バージョンでのImShowメソッドの使用方法

JARファイルをGitから直接ダウンロードします。

Imshow.jarを直接ダウンロードします。

Downloadボタンをクリックしてダウンロードします。

BuildPathをJARファイルに通します。

プロジェクトを右クリック > BuildPath

「Add External Jar」でダウンロードしたファイルを追加します。

実際の作業

https://www.youtube.com/watch?v=ZlTZDoYCAS8

次は、画像の表示をするための準備を行います。

ImShowのメソッドが使えないのでJavaFXによる画像表示GUIを作成していきます。

参考サイトはこちらです。

ちなみにチュートリアルでは「シーンビルダー」をインストールして画面の土台を作っています、下のような感じです。

関連ページ一覧

<JavaFXの準備>

  1. Eclipse SceneBuilderを追加する
  2. JavaFX SceneBuilder 〜EclipseとSceneBuilder連携~

<TensorFlow関連>

 家計簿アプリ作成

  1. Eclipse アプリ作成 Lv1〜家計簿を作る準備〜
  2. Eclipse アプリ作成 Lv2〜家計簿を作る土台作り〜
  3. Eclipse アプリ作成 Lv3〜3Dグラフ用Cube作り〜
  4. Eclipse アプリ作成 Lv4〜3Dグラフ用Cubeに高さを与える〜
  5. Eclipse アプリ作成 Lv5〜惨敗:CubeにTextureを貼る〜
  6. Eclipse アプリ作成 Lv7〜Cubeを日付順に並べる〜