質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

解決済

1回答

1609閲覧

[Java]MatからBitMapに変換した画像が正常に表示されない

naki_a

総合スコア6

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

0クリップ

投稿2022/12/06 14:46

編集2022/12/15 03:32

前提

AndoroidStudioで読み込んだ動画の明度を変換するアプリを作ろうと思っています。
使用言語はJavaです。
CameraXとOpenCVを使った画像処理向けAndroidアプリのひな形
こちらの記事を参考にし、CameraX ライブラリを使用して動画像を取得し、
OpenCV(opencv_java4)でRGB変換を行う予定です。

実現したいこと

Mat型配列へ1画素ずつアクセスし、RGBでの明度変換を行いたい。
(RGB値全てに同じ数を掛けると明度を上げることができる)

コードの流れとしては
AndoroidStudioでCameraXライブラリを使用して動画像を取得
→取得した動画像をOpenCVで使用できるように変換(Imgproc.COLOR_YUV2RGB_NV21 で変換)
→処理を行った後Mat型からBitmap型へ変換(Utils.matToBitmap(mat, bitmap);)
→画面を二分割した下側に表示

という流れで処理を書いています。

発生している問題・エラーメッセージ

読み込んだ画像をMat型に変換し、Bitmapに変換して画面に表示はされるのですが色がおかしいです。
グレースケール画像に変換したときは何ともないのですが、カラーで表示しようとするとおかしくなります。

イメージ説明
イメージ説明

該当のソースコード

Java

1 public void analyze(@NonNull ImageProxy image) { 2 /* Create cv::mat(RGB888) from image(NV21) */ 3 Mat matOrg = getMatFromImage(image); 4 /* 画像を回転 */ 5 Mat fixMat = fixMatRotation(matOrg); 6 7 /*** 8 Log.i(TAG, "[analyze] width = " + image.getWidth() + ", height = " + image.getHeight() + "Rotation = " + previewView.getDisplay().getRotation()); 9 Log.i(TAG, "[analyze] mat width = " + fixMat.cols() + ", mat height = " + fixMat.rows()); 10 type = 16, depth = 0, channels = 3, isContinuous = true 11 Log.i(TAG, "type = " + fixMat.type() + ", depth = " + fixMat.depth() + ", channels = " + fixMat.channels() + ", isContinuous = " + fixMat.isContinuous()); 12 ***/ 13 Size sizeMat = fixMat.size(); 14 Mat mat = fixMat.clone(); 15 16 for (int i = 0; i < fixMat.height(); i++){ 17 for (int j = 0; j < fixMat.width(); j++){ 18 double[] data = fixMat.get(i,j); 19 data[0] = data[0] / 2; 20 data[1] = data[1] / 2; 21 data[2] = data[2] / 2; 22 mat.put(i,j,data); 23 } 24 }

試したこと

fixmatの要素を取得したところ、type = 16, depth = 0, channels = 3, isContinuous = trueが返ってきました。
ビット深度はCV_8U, チャンネル数が3のカラー画像です。

グレースケール画像では正常に表示されるので、
NV21→RGB(Mat型)→RGB2GRAY→GRA2RGB(BGRも試しました)→Bitmapに変換
という流れでカラーにしようと思ったのですが表示されるのはグレースケール画像でカラーに戻りませんでした。

補足情報(FW/ツールのバージョンなど)

Android studio Dolphin 2021/3/1
OpenCV opencv_java4

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2022/12/06 20:54 編集

グレースケールの時のコードはどのようなものだったのでしょうか。 なお、 matToBitmap の bitmap は ARGB_8888 と RGB_565 にしか対応していないと思います。ドキュメントを確認してください。
naki_a

2022/12/07 03:13

ご回答ありがとうございます。 ソースコードの部分に追加しました。 グレースケール化は上のImgproc.cvtColor(mat,mat,Imgproc.COLOR_RGB2GRAY);のみ記述です。 ドキュメントはここ(https://www.tabnine.com/code/java/methods/org.opencv.android.Utils/matToBitmap)でしょうか?すみません、見きれていませんでした。コメント欄に書いてありました。
jimbe

2022/12/07 05:52 編集

公式の java ドキュメントは全く生成する気が無さそうですね。基本 c++ を呼ぶだけなのでそっちを読めということかもしれません。 3.0.0 → https://docs.opencv.org/java/3.0.0/ Utils → https://docs.opencv.org/java/3.0.0/org/opencv/android/Utils.html 自作の明度変更の処理部分をライブラリ提供のグレイスケールへの変換にしただけで直る(?) というのであれば、自作の明度変更の処理部分に問題があるという判断になると思うのですが。 get しているデータは本当に RGB なのでしょうか。 例えば 0=R,1=G,2=B だとして data[0]=0 にして他はそのままというロジックにしたら、本当に R が無くなるかを試してみるとかは如何でしょう。
naki_a

2022/12/07 07:30

明度変更部分の処理を記述しなくても特に結果は変わらなくて、赤と緑の色で二分割された画面が表示されるため恐らく関係無いのではと思っています。 for文の部分を全て消し、Imgproc.cvtColorの変換部分のみにしても明度以外同じ画面が出てきます。
jimbe

2022/12/07 08:59

ということは、Mat mat = fixMat.clone(); の辺りで既に変ということになるでしょうか。 > グレースケール化は上のImgproc.cvtColor(mat,mat,Imgproc.COLOR_RGB2GRAY);のみ記述です。 というのがどこに「のみ」だったのかはっきりするために、全体のコードを載せて頂いたほうが分かり易いと思います。
naki_a

2022/12/07 09:47

分かりにくくてすみません!のみ、というのは //試した事 Imgproc.cvtColor(mat,mat,Imgproc.COLOR_RGB2GRAY); Imgproc.cvtColor(mat,mat,Imgproc.COLOR_GRAY2BGR); の部分で2行のうち上の行だけという意味でした。 非常に長くなってしまうと思いますが、後ほど全体のコードも上げさせて頂きます。 getMatFromImage(),fixMatRotation()は前提で記載した記事に書かれていた関数を参考にしておりますので、宜しければそちらもご覧下さい。
guest

回答1

0

自己解決

エミュレータではなく、実機で実行したら正常に動作しました。
CameraXライブラリを使用したプログラムをエミュレータ上で動作させると正常に動かない場合があるそうです。
また、Type-cケーブルが給電用ではなくデータ送信に対応しているかどうかも確認の必要がありました。

投稿2022/12/15 03:34

naki_a

総合スコア6

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問