背景
OpenCVを使って画像処理アプリを作ろうと思い立った。かつて、OpenCV2.4 & C++を使って開発をしたことがあったが、最近Javaばかりやっていたので、Javaでかつ最新版OpenCVを使ってみることにした。
最新版では関数が大きく変わっており、imshowが無く処理結果を見ることができなかった。そこでJavaFXで描画することにした。
環境
OpenCV 3.4.3
JavaFX 8
Windows10
内容
JavaFXの基本構造
javafx.application.Applicationをextendsして、Applicationクラスのstart(Stage primaryStage)メソッドをOverrideして処理を書く。その上で、main関数からlaunch(args)を呼ぶことで実行ができる。startメソッドの引数であるStageの上に、Paneをおき、その上にButtonやTextFieldのようなフォームオブジェクトを置くのが基本構造となる。Paneはレイアウトを形作るフレームのようなもので、BorderPaneなら上下左右中央の5つの領域を提供する。VBox(VirticalBox)は単純に縦にオブジェクトを並べることができる。
上のコードは、文字列”This is JavaFX!” を表示するだけのものである。この文字列の代わりに画像を表示すれば良い。
JavaFXで画像表示
次に指定したパスにある画像を表示するようにコードを修正した。
変化点としては、Labelの代わりにImageViewを作り、ImageViewに対して読み込んだimage(./image/lena.jpg)をセットしている。また、paneは、単純化するためにVBoxに変更している。
OpenCVで画像の読み込み
openCVで画像を読み込むのは、imread関数を使えばいい。Imgcodecs.imread(“画像パス”)とすれば、Matを生成してくれる。注意点としては画像パスに日本語文字列が入っているとうまくいかないようである。
Matさえ作ってしまえば目的は達成するのがこれまでの(imshow()があった)バージョンでOpenCVを使う下準備であった。しかし、今回はMatをJavaFxのImageViewに表示することが目的である。
Matをjavafx.scene.image.Imageに変換
流れとしては、Matをbmp等のファイル形式にエンコードしてbyte配列にしたものをImageクラスに変換する。
createImage()で、画像ファイル(./image/lena.jpg)をMat形式で読み込み、bmp形式のbyte配列に変換した後、Imageオブジェクトに変換している。出力画像サイズは256*256pxにしている。受け取ったImageオブジェクトをImageViewに送ることで表示することができる。
これで基本構造ができたので、Applicationをextendsした抽象クラス化することで、 JavaFXを意識することなく画像処理ロジックの検証ができるようになる。