Android + OpenCV でサンプルプログラム「face-detection」をインカメラ+縦向きで実行したい。
OpenCV のリファレンスとソースコードを探してみたのですが、インカメラ+縦向きで実行したいのですが、カメラのプレビューが意図したとおりに、することができません。
スマートフォンが横向きでは、プレビューは正常です。縦向きにすると、プレビューの上下が逆さまになります。
上下逆さまをsetDisplayOrientation
とsetRotation
を使って、正しい向きにしたいのですが、私のプログラムでは、意図したとおりに動作しませんでした。
お分かりになる方、教えてください。
- Eclipse 4.4 + ADT
- API 19
- Nexus 5
やってみたこと。
メンバ変数mOpenCvCameraView
のCameraBridgeViewBase
型をJavaCameraView
型にして動作するか確認。-> 意図したとおりに動作することを確認。
JavaCameraView
クラスに、画面の向きを変更するメソッドが見つからなかったので、JavaCameraView
を継承したJavaCameraView2
クラスを作成して、向きを変えるメソッドを追加
FdActivity
クラスのonCreateメソッド内で、作成したメソッドを呼ぶ
-> ここで、つまづいています。
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..
}
mOpenCvCameraView.setCameraRotation(90);
で Java.lang.NullPointerException
が発生します。
どうぞ、よろしくお願いします。
追記
アドバイスを元に「onResume」メソッドにコードを追加しました。
public void onResume() {
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
// 以下追加
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCameraRotation(90);
mOpenCvCameraView.enableView();
}
結果は、NullPointerExceptionが発生し、意図したとおりにはなりませんでした。
何か参考になる情報があれば、教えてください。
1/27 追記
プレビューを意図した向きにすることができました。以下のサイトを参考にしています。
OpenCV4Android - Displaying Preview in Portrait Mode
カメラをOpenした直後に、setDisplayOrientation
メソッドを実行しても、向きが変化しないのは、
OpenCVの中で、向きを変更できないようなコーディングがされていると思い、参考サイトで向きを調整
しました。
ただ、このままだと比率が正しくないので、潰れた状態でプレビューされます。
この方法が正しいのかどうかは、自信がありません。
今は、潰れないように、比率が正しくなるように調整しています。
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;
}
}
この方法以外の情報がございましたら、教えてください。
よろしくお願いします。
追記 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」の条件では、意図したとおりに動作できない。と判断しました。
ありがとうござました。