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

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

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

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

Java

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

Android Studio

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

Q&A

解決済

1回答

1658閲覧

JavaでMatのRGB要素にアクセス・値を変更する方法

naki_a

総合スコア6

OpenCV

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

Java

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

Android Studio

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

0グッド

0クリップ

投稿2022/12/05 16:03

前提

AndoroidStudioで読み込んだ動画の明度を変換するアプリを作ろうと思っています。
使用言語はJavaです。
CameraX ライブラリを使用して動画像を取得し、
OpenCVでRGB変換を行う予定です。

実現したいこと

Mat行列において、画素にアクセスしRGB値を比較したり掛け算をしたい。

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

C言語では
cv::vec3b p = Mat.atcv::Vec3b(2, 5);
画素の変更は
Mat.atcv::Vec3b(y, x)[0] = xx; //青
Mat.atcv::Vec3b(y, x)[1] = xx; //緑
Mat.atcv::Vec3b(y, x)[2] = xx; //赤

のように出来るという記事を見つけましたが、Javaではどのように記述するのか理解できませんでした。

Java

1for (double v = 0; v < mat.rows(); v++){ 2  for (double u = 0; u < mat.cols(); u++){ 3    Scalar p = mat.at(u,v); 4 } 5}

のように記述してみたのですが使えませんでした。

該当する関数はこのように記述しています。

Java

1 private class MyImageAnalyzer implements ImageAnalysis.Analyzer { 2 private Mat matPrevious = null; 3 4 @Override 5 public void analyze(@NonNull ImageProxy image) { 6 /* Create cv::mat(RGB888) from image(NV21) */ 7 Mat matOrg = getMatFromImage(image); 8 9 /* Fix image rotation (it looks image in PreviewView is automatically fixed by CameraX???) */ 10 Mat mat = fixMatRotation(matOrg); 11 12 Log.i(TAG, "[analyze] width = " + image.getWidth() + ", height = " + image.getHeight() + "Rotation = " + previewView.getDisplay().getRotation()); 13 Log.i(TAG, "[analyze] mat width = " + matOrg.cols() + ", mat height = " + matOrg.rows()); 14 //type = 16, depth = 0, channels = 3, isContinuous = true 15 Log.i(TAG, "type = " + matOrg.type() + ", depth = " + matOrg.depth() + ", channels = " + matOrg.channels() + ", isContinuous = " + matOrg.isContinuous()); 16 17 for (double v = 0; v < mat.rows(); v++){ 18 for (double u = 0; u < mat.cols(); u++){ 19 Scalar p = mat.at(u,v); 20 //1画素ずつ取り出す 21 //RGBの値を比較して、2したり1/2したい 22 } 23 } 24 25 /* Convert cv::mat to bitmap for drawing */ 26 Bitmap bitmap = Bitmap.createBitmap(mat.cols(), mat.rows(),Bitmap.Config.ARGB_8888); 27 Utils.matToBitmap(mat, bitmap); 28 29 /* Display the result onto ImageView */ 30 runOnUiThread(new Runnable() { 31 @Override 32 public void run() { 33 imageView.setImageBitmap(bitmap); 34 } 35 }); 36 37 /* Close the image otherwise, this function is not called next time */ 38 image.close(); 39 }

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

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

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

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

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

jimbe

2022/12/05 16:59

その Mat というクラスはどこのパッケージのものでしょうか。
naki_a

2022/12/06 01:11

回答ありがとうございます! MatはOpenCV由来のクラスです。 <T> Mat.Atable<T> at​(java.lang.Class<T> clazz, int row, int col) というところですよね、最初のクラスに何を指定すればいいのか分からなくて躓いてしまいました。 (double)とか(int)も入れてみたんですがよく分からず…… 大人しくgetなんかを使った方が良いんでしょうか
jimbe

2022/12/06 03:19

>MatはOpenCV由来のクラス hoshi-rakanori さんのコメントのリンクのクラスであっているということでしょうか。 クラスは自由に作れるものですので、名前だけでは特定出来ません。由来等というふんわりした表現をしても、バージョンによって使い方が違っていたら意味がありません。 >(double)とか(int)も入れてみたんですが java.lang.Class<T> ですから、 Class オブジェクトです。 at(Integer.class, row, column) とやれば Mat.Atable<Integer> オブジェクトが得られるということです。 >大人しくgetなんかを使った方が良いんでしょうか 大人しくとはどういうことでしょう。 get なら使えるのでしたらそれで良いように思いますが…何が問題なのでしょうか。
naki_a

2022/12/06 04:28

曖昧な説明をしてしまいすみません。 Javaを学び始めたばかりで、MatはOpenCVで使うものという認識があったのでふわっとした言い方になってしまいました。 そのClass<T>というものがよく分からなくて、clazzと指定されている引数の部分にinteger.classと入力すればいいのでしょうか? 自分で調べた際に、Mat型配列の画素値にアクセスする場合はatを使う方が圧倒的に多いようで、getを使うものを見つけられていませんでした。どちらにしろ使い方が分からない関数だったので、出来れば参考資料が多い方の関数を使いたかったという個人的な感想です。
jimbe

2022/12/06 06:34

>そのClass<T>というものがよく分からなくて、clazzと指定されている引数の部分にinteger.classと入力すればいいのでしょうか? 頭が大文字の Integer.class ですね。 Integer クラスは int のオブジェクト版です。 Class<T> となっていますので、 clazz として Integer.class を渡すと、そのメソッドの他の T の部分が Integer として扱われるようになります。 int でなく double で欲しいとか long でとかであれば、 Double.class 、 Long.class (頭大文字に注意)を渡せば良いことになります。 >Mat型配列の画素値にアクセスする場合はatを使う方が圧倒的に多いようで、getを使うものを見つけられていませんでした ですがそれらは、質問本文で書かれているように c だったのではありませんか? c と java では、同じ構造でも表現が違って使用方法も変わるのはあり得ることですので、『c はこうなのに java で同じに出来ない』というのは当然と思われても良いと思います。 少ないかもしれませんが java での資料を地道に探すか、実際に試すしか無いでしょう。
naki_a

2022/12/06 13:58

>int でなく double で欲しいとか long でとかであれば、 Double.class 、 Long.class (頭大文字に注意)を渡せば良いことになります。 何度もご回答ありがとうございます。使い方がよくわかりました。Classは分かってもclazzとは?というところでよくわからなくなってしまっていたので、これで引数の指定ができそうです。 >c と java では、同じ構造でも表現が違って使用方法も変わるのはあり得ることですので、『c はこうなのに java で同じに出来ない』というのは当然と思われても良いと思います。 少ないかもしれませんが java での資料を地道に探すか、実際に試すしか無いでしょう。 一応JavaにもVec3dという型(?なのかよくわかりませんが)はあるようですが、jimbeさんのおっしゃる通りCと同じような記述はできなさそうでした。今やっているプログラムはget関数で解決しそうなのですが、今後のためにも調べてみようと思います。 ありがとうございました。
guest

回答1

0

自己解決

回答ではなく質問の部分で解決してしまいBAが選べなかったため、便宜上自己解決とさせていただきます。

質問欄でMat.at()ではなくget関数で良いのではとご指摘いただいたことを受け、
Using get() and put() to access pixel values in OpenCV for Java
こちらの質問を参考にコードを書き直しました。
/2の部分を*2にすると明度が変更されることを確認できたので、別の問題は浮上してきましたが元の目的はある程度達成できました。
知恵を貸していただきありがとうございました。

Java

1private class MyImageAnalyzer implements ImageAnalysis.Analyzer { 2 private Mat matPrevious = null; 3 4 @Override 5 public void analyze(@NonNull ImageProxy image) { 6 /* Create cv::mat(RGB888) from image(NV21) */ 7 Mat matOrg = getMatFromImage(image); 8 /* 画像を回転 */ 9 Mat fixMat = fixMatRotation(matOrg); 10 11 Size sizeMat = fixMat.size(); 12 Mat mat = fixMat.clone(); 13 14 for (int i = 0; i < fixMat.height(); i++){ 15 for (int j = 0; j < fixMat.width(); j++){ 16 double[] data = fixMat.get(i,j); 17 data[0] = data[0] / 2; 18 data[1] = data[1] / 2; 19 data[2] = data[2] / 2; 20 mat.put(i,j,data); 21 } 22 } 23 24 /* mat -> bitmap */ 25 Bitmap bitmap = Bitmap.createBitmap(mat.cols(), mat.rows(),Bitmap.Config.ARGB_8888); 26 Utils.matToBitmap(mat, bitmap); 27 28 /* Display the result onto ImageView */ 29 runOnUiThread(new Runnable() { 30 @Override 31 public void run() { 32 imageView.setImageBitmap(bitmap); 33 } 34 }); 35 36 image.close(); 37 }

投稿2022/12/06 14:17

naki_a

総合スコア6

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.39%

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

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

質問する

関連した質問