

OpenCV
のリファレンスとソースコードを探してみたのですが、インカメラ＋縦向きで実行したいのですが、カメラのプレビューが意図したとおりに、することができません。  
スマートフォンが横向きでは、プレビューは正常です。縦向きにすると、プレビューの上下が逆さまになります。  
上下逆さまを`setDisplayOrientation`と`setRotation`を使って、正しい向きにしたいのですが、私のプログラムでは、意図したとおりに動作しませんでした。  
お分かりになる方、教えてください。

  * Eclipse 4.4 + ADT
  * API 19
  * Nexus 5

やってみたこと。  
メンバ変数`mOpenCvCameraView`の`CameraBridgeViewBase`型を`JavaCameraView`型にして動作するか確認。->
意図したとおりに動作することを確認。

`JavaCameraView`クラスに、画面の向きを変更するメソッドが見つからなかったので、`JavaCameraView`を継承した`JavaCameraView2`クラスを作成して、向きを変えるメソッドを追加

`FdActivity`クラスのonCreateメソッド内で、作成したメソッドを呼ぶ  
-> ここで、つまづいています。
[code]

    public class JavaCameraView2 extends JavaCameraView {
        // snip..
        public void setCameraRotation(int angle) {
            Log.i(TAG, "called setCameraRotation");
    
            try {
                this.mCamera.setDisplayOrientation(angle);
    
            } catch (Exception e) {
                Log.e(TAG, "failed camera setting");
                e.printStackTrace();
            }
        }
    }
    
    
    public class FdActivity extends Activity implements CvCameraViewListener2 {
        private JavaCameraView2        mOpenCvCameraView;
    // snip..
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            Log.i(TAG, "called onCreate");
            super.onCreate(savedInstanceState);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    
            setContentView(R.layout.face_detect_surface_view);
    
            mOpenCvCameraView = (JavaCameraView2) findViewById(R.id.fd_activity_surface_view);
            mOpenCvCameraView.setCvCameraViewListener(this);
            mOpenCvCameraView.setCameraRotation(90);
        }
    // snip..
    }
    
[/code]

`mOpenCvCameraView.setCameraRotation(90);` で `Java.lang.NullPointerException`
が発生します。

どうぞ、よろしくお願いします。

追記  
アドバイスを元に「onResume」メソッドにコードを追加しました。

[code]

    public void onResume() {
      super.onResume();
    
      OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
      // 以下追加
      mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
      mOpenCvCameraView.setCameraRotation(90);
      mOpenCvCameraView.enableView();
    }
    
[/code]

結果は、NullPointerExceptionが発生し、意図したとおりにはなりませんでした。  
何か参考になる情報があれば、教えてください。

1/27 追記  
プレビューを意図した向きにすることができました。以下のサイトを参考にしています。  
[OpenCV4Android - Displaying Preview in Portrait
Mode](http://buildsmartrobots.ning.com/profiles/blogs/opencv4android-
displaying-preview-in-portrait-mode)

カメラをOpenした直後に、`setDisplayOrientation`メソッドを実行しても、向きが変化しないのは、  
OpenCVの中で、向きを変更できないようなコーディングがされていると思い、参考サイトで向きを調整  
しました。  
ただ、このままだと比率が正しくないので、潰れた状態でプレビューされます。  
この方法が正しいのかどうかは、自信がありません。

今は、潰れないように、比率が正しくなるように調整しています。

[code]

    public class FdActivity extends Activity implements CvCameraViewListener2 {
        private Mat mRgbaF;
        private Mat mRgbaT;
    
        public void onCameraViewStarted(int width, int height) {
            mGray = new Mat();
            mRgba = new Mat();
    
            mRgbaF = new Mat(height, width, CvType.CV_8UC4);
            mRgbaT = new Mat(width, width, CvType.CV_8UC4);
        }
    
        public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
            // 省略
    
            // Rotate mRgba 90 degrees
            Core.transpose(mRgba, mRgbaT);
            Imgproc.resize(mRgbaT, mRgbaF, mRgbaF.size(), 0, 0, 0);
            Core.flip(mRgbaF, mRgba, 0 );
    
            return mRgba;
        }
    
[/code]

}

この方法以外の情報がございましたら、教えてください。  
よろしくお願いします。

追記 2/9  
上記方法ですと、プレビュー画面が潰れてしまい（縦と横の比率がおかしい）、意図したとおりにならないため、参考になるサイトを探しておりました。  
以下のサイトを参考にしましたが、バックカメラ＋portrait は意図したとおりになることを確認しましたが、インカメラ＋portrait
では、プレビュー画面の上下が逆さまになってしまいます。

参考サイト：  
<http://answers.opencv.org/question/7313/rotating-android-camera-to-portrait/>  
<http://littlecheesecake.me/blog/13804736/opencv-android-orientation>

結論として、OpenCVは「インカメラ＋portrait」の条件では、意図したとおりに動作できない。と判断しました。  
ありがとうござました。


CC BY-SA 3.0
2015-01-22T11:16:36.490
5083
2015-02-09T02:09:00.430
2015-02-09T02:09:00.430
7402
7402
question
android opencv
Android + OpenCV でサンプルプログラム「face-detection」をインカメラ＋縦向きで実行したい。


`mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);`で  
`VISIBLE`に設定してないこと、そしてそれを`enableView`などで状態を通知していないため、`mCamera`がnullになっていることが落ちる原因です。

opencvのサンプルソースコードに従っているのでしたら`onResune`で`enableView`を呼んだ後、上記処理を実施して下さい。  
該当箇所:<https://github.com/Itseez/opencv/blob/79f593a42923a411fb0c421cd3b766acee004387/samples/android/face-
detection/src/org/opencv/samples/facedetect/FdActivity.java#L100>

以下、根拠と蛇足。  
`mCamera`にインスタンスが入るために、`initializeCamera`→`connectCamera`と  
呼ばれなくてはいけませんが、この`connectCamera`は明示的に呼ばれない限り、  
[CameraBridgeViewBaseの355行目](https://github.com/Itseez/opencv/blob/da1ac359304df7e3a933e83babc5be5f49bc48a9/modules/java/generator/src/java/android%2BCameraBridgeViewBase.java#L355)で  
実施されます。ここにたどり着くために同じクラスの`checkCurrentState()`から`processEnterState()`が呼ばれなくてはいけませんが、この条件式が次の通りでした。  
[`mEnabled && mSurfaceExist && getVisibility() ==
VISIBLE`](https://github.com/Itseez/opencv/blob/da1ac359304df7e3a933e83babc5be5f49bc48a9/modules/java/generator/src/java/android%2BCameraBridgeViewBase.java#L301)  
従って上記条件式を当てはめるように状況を設定し、  
[`processEnterState()(実際はsurfaceChanged())`](https://github.com/Itseez/opencv/blob/da1ac359304df7e3a933e83babc5be5f49bc48a9/modules/java/generator/src/java/android%2BCameraBridgeViewBase.java#L192)が叩かれて状態変更が通知されるように  
しなれければいけません。


CC BY-SA 3.0
2015-01-22T12:38:09.667
5088
2015-01-22T22:35:19.057
2015-01-22T22:35:19.057
2904
2904
5083
answer