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

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

ただいまの
回答率

88.22%

Android版OpenCVで画像を並べて表示

受付中

回答 0

投稿

  • 評価
  • クリップ 0
  • VIEW 1,413

kiritsukiR

score 10

OpenCV 3.4.2を使用してAndroidでカメラ画像を加工し、その過程を左右に並べて表示しようとしています。
そのための足掛かりとしてまずは同じ画像を左右に並べようとしています。
SDKに付属しているサンプルを参考に単純にCameraBridgeViewBaseを2つに増やしてみましたが、以下の画像に示す通り上手くいきませんでした。

起動直後は次の画像のようになり、右側のビューのみが有効化しました。
左側には間違いなくビューが存在することは確認済みです。
起動直後

そこで左右それぞれについてenableViewdisableViewを行うボタンを設置して操作すると左側のビューも動作しました。
しかし今度は右側のビューの更新が停止してしまいました。
画像だと分かりにくいですが、次の画像は右側はそのまま、左側のみが更新されている様子を撮影したものです。
片方のみ更新される様子

左右のビューを同時に更新するにはどうすればいいでしょうか。
(それともそもそもできないのでしょうか。)

import android.app.Activity
import android.os.Bundle
import android.util.Log
import kotlinx.android.synthetic.main.activity_main.*
import org.opencv.android.BaseLoaderCallback
import org.opencv.android.CameraBridgeViewBase
import org.opencv.android.LoaderCallbackInterface
import org.opencv.android.OpenCVLoader
import org.opencv.core.CvType
import org.opencv.core.Mat
import org.opencv.core.Size
import org.opencv.imgproc.Imgproc

class MainActivity : Activity() {
    // 画面左のビュー
    private lateinit var mOpenCvCameraView: CameraBridgeViewBase
    // 画面右のビュー
    private lateinit var mOpenCvCameraView2: CameraBridgeViewBase
    // 準備完了を受け取るコールバック
    private val mLoaderCallback = object : BaseLoaderCallback(this) {
        override fun onManagerConnected(status: Int) {
            when (status) {
                LoaderCallbackInterface.SUCCESS -> {
                    // 左側の表示を開始
                    Log.d("LEFT", "before enableView()")
                    mOpenCvCameraView.enableView()
                    mOpenCvCameraView.enableFpsMeter()
                    Log.d("LEFT", "after enableView()")
                    // 右側の表示を開始
                    Log.d("RIGHT", "before enableView()")
                    mOpenCvCameraView2.enableView()
                    mOpenCvCameraView2.enableFpsMeter()
                    Log.d("RIGHT", "after enableView()")

                    // 最後に有効化したものだけ有効になるという仮説の下
                    // 上の2つの順番を入れ替えたが、最初に有効になるビューは右のまま変わらず。
                }
                else -> {
                    super.onManagerConnected(status)
                }
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        mOpenCvCameraView = findViewById(R.id.java_camera_view)
        mOpenCvCameraView.setCvCameraViewListener(CameraListener("LEFT"))

        mOpenCvCameraView2 = findViewById(R.id.java_camera_view2)
        mOpenCvCameraView2.setCvCameraViewListener(CameraListener("RIGHT"))

        // 以下テスト用のボタン類

        bt_left_e.setOnClickListener {
            mOpenCvCameraView.enableView()
        }

        bt_right_e.setOnClickListener {
            mOpenCvCameraView2.enableView()
        }

        bt_left_d.setOnClickListener {
            mOpenCvCameraView.disableView()
        }

        bt_right_d.setOnClickListener {
            mOpenCvCameraView2.disableView()
        }
    }

    override fun onPause() {
        super.onPause()
        mOpenCvCameraView.disableView()
        mOpenCvCameraView2.disableView()
    }

    override fun onResume() {
        super.onResume()
        if (OpenCVLoader.initDebug()) {
            mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS)
        } else {
            OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_4_0, this, mLoaderCallback)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        mOpenCvCameraView.disableView()
        mOpenCvCameraView2.disableView()
    }

    class CameraListener(val tag: String) : CameraBridgeViewBase.CvCameraViewListener2 {
        private lateinit var edgeMat: Mat
        private lateinit var dilatedMat: Mat
        private lateinit var denoisedMat: Mat
        private lateinit var colorMat: Mat
        private lateinit var dilateKernel: Mat

        override fun onCameraViewStarted(width: Int, height: Int) {
            Log.d(tag, "onCameraViewStarted($width, $height)")

            edgeMat = Mat(width, height, CvType.CV_8UC1)
            dilatedMat = Mat(width, height, CvType.CV_8UC1)
            denoisedMat = Mat(width, height, CvType.CV_8UC1)
            colorMat = Mat(width, height, CvType.CV_8UC3)
            dilateKernel = Mat()
        }

        override fun onCameraViewStopped() {
            Log.d(tag, "onCameraViewStopped()")

            edgeMat.release()
            dilatedMat.release()
            denoisedMat.release()
            colorMat.release()
            dilateKernel.release()
        }

        override fun onCameraFrame(inputFrame: CameraBridgeViewBase.CvCameraViewFrame): Mat {
            Log.d(tag, "onCameraFrame(inputFrame)")
            // エッジ抽出
            Imgproc.Canny(inputFrame.gray(), edgeMat, 80.0, 100.0)
            // 膨張
            Imgproc.dilate(edgeMat, dilatedMat, dilateKernel)
            // ぼかし
            Imgproc.GaussianBlur(dilatedMat, denoisedMat, Size(3.0, 3.0), 10.0)
            //色変換
            Imgproc.applyColorMap(denoisedMat, colorMat, Imgproc.COLORMAP_SUMMER)
            return colorMat //一連の加工はテストで深い意味は無し
        }
    }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

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

  • ただいまの回答率 88.22%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る