Ask Your Question
4

Rotating Android Camera to Portrait

asked 2013-02-12 08:28:41 -0600

jameo gravatar image

updated 2013-02-12 08:29:22 -0600

I am implementing the Android OpenCV SDK to make a camera app. I would like it to work for multiple UI orientations. I am extending the JavaCameraView in SDK 2.4.3.2. I am trying to figure out how to rotate the camera. I know what I have to do is write something like this

camera.setDisplayOrientation(90);

to get it to work in portrait, but I have tried it in multiple places, and none have worked for me. The camera still displays "sideways". If anyone has done a similar thing, please let me know

edit retag flag offensive close merge delete

Comments

rics gravatar imagerics ( 2013-03-11 08:51:10 -0600 )edit

@jameo Did you find an answer?

powder366 gravatar imagepowder366 ( 2013-08-22 15:23:36 -0600 )edit

You ever find an answer to this? There seems to not be a solution anywhere on the internet for this. cam.setDisplayOrientation(90) simply doesn't work. Any other solutions (like itay's posted below) out there rely on pixel manipulations that vastly degrade the framerate....

wpccolorblind gravatar imagewpccolorblind ( 2014-02-12 01:00:55 -0600 )edit

Is this really still active?

Poyan gravatar imagePoyan ( 2015-03-24 10:03:20 -0600 )edit

4 answers

Sort by ยป oldest newest most voted
1

answered 2014-03-12 08:07:01 -0600

Zarokka gravatar image

I don't think there is a way to to this, without some pixel manipulation. However, at least the resizing suggested by itay is not necessary and Performance impact of my solution was small.

The problem is that onPreviewFrame callback will always return the frame in landscape mode (no matter what orientation was set to the camera)(thats documented behavior).

The Second problem is that JavaCameraView will get a wrong (small) preview size if used in portrait mode.

I solved it by creating my own subclass of the CameraBridgeViewBase class (for most parts the same as JavaCameraView) It uses the reversed (landscape) width and height to get the preview size and for the frame chain, but the portrait width and height as the size of the returned CameraFrame.

This solution also includes transpose and flip, but no resizing:

public class PortraitCameraView extends CameraBridgeViewBase implements PreviewCallback {

private static final int MAGIC_TEXTURE_ID = 10;
private static final String TAG = "JavaCameraView";

private byte mBuffer[];
private Mat[] mFrameChain;
private int mChainIdx = 0;
private Thread mThread;
private boolean mStopThread;

protected Camera mCamera;
protected JavaCameraFrame[] mCameraFrame;
private SurfaceTexture mSurfaceTexture;
private int mCameraId;

public static class JavaCameraSizeAccessor implements ListItemAccessor {

    public int getWidth(Object obj) {
        Camera.Size size = (Camera.Size) obj;
        return size.width;
    }

    public int getHeight(Object obj) {
        Camera.Size size = (Camera.Size) obj;
        return size.height;
    }
}

public PortraitCameraView(Context context, int cameraId) {
    super(context, cameraId);
}

public PortraitCameraView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

protected boolean initializeCamera(int width, int height) {
    Log.d(TAG, "Initialize java camera");
    boolean result = true;
    synchronized (this) {
        mCamera = null;

        boolean connected = false;
        int numberOfCameras = android.hardware.Camera.getNumberOfCameras();
        android.hardware.Camera.CameraInfo cameraInfo = new android.hardware.Camera.CameraInfo();
        for (int i = 0; i < numberOfCameras; i++) {
            android.hardware.Camera.getCameraInfo(i, cameraInfo);
            if (cameraInfo.facing == android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK) {
                try {
                    mCamera = Camera.open(i);
                    mCameraId = i;
                    connected = true;
                } catch (RuntimeException e) {
                    Log.e(TAG, "Camera #" + i + "failed to open: " + e.getMessage());
                }
                if (connected) break;
            }
        }

        if (mCamera == null) return false;

        /* Now set camera parameters */
        try {
            Camera.Parameters params = mCamera.getParameters();
            Log.d(TAG, "getSupportedPreviewSizes()");
            List<Camera.Size> sizes = params.getSupportedPreviewSizes();

            if (sizes != null) {
                /* Select the size that fits surface considering maximum size allowed */
                Size frameSize = calculateCameraFrameSize(sizes, new JavaCameraSizeAccessor(), height, width); //use turn around values here to get the correct prev size for portrait mode

                params.setPreviewFormat(ImageFormat.NV21);
                Log.d(TAG, "Set preview size to " + Integer.valueOf((int)frameSize.width) + "x" + Integer.valueOf((int)frameSize.height));
                params.setPreviewSize((int)frameSize.width, (int)frameSize.height);

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
                    params.setRecordingHint(true);

                List<String> FocusModes = params.getSupportedFocusModes();
                if (FocusModes != null && FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
                {
                    params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
                }

                mCamera.setParameters(params);
                params = mCamera.getParameters();

                mFrameWidth = params.getPreviewSize().height; //the frame width and height of the super class are used to generate the cached bitmap and they need to be the size of the resulting frame
                mFrameHeight = params.getPreviewSize().width;

                int realWidth = mFrameHeight; //the real width and height are the width and height of the frame received in onPreviewFrame ...
(more)
edit flag offensive delete link more

Comments

hi, i am new to opencv ecosystem, i tried to incorporate the same code with my facedetection sample but cannot understand from where to call this class, Should i call it from onCameraFrame or i need to change the whole code in the sample,(which i dont think is a better approach for me), can someone help me as to how to use this code, because onCameraFrame returns a mat image and even if i use this class from onCameraFrame i am not getting any Rotated image. @Idol can you please paste the code where you incorporated it in tutorial1

RickDroid gravatar imageRickDroid ( 2014-11-27 00:18:57 -0600 )edit

This is resulting in performance degradation. The camera preview is not realtime and lags by an unacceptable margin

abhilash1in gravatar imageabhilash1in ( 2016-07-14 11:37:03 -0600 )edit

Not working

seroj1293 gravatar imageseroj1293 ( 2016-09-28 03:58:14 -0600 )edit

Thanks. i tried to use the code but i encounter problem that if i use front camera it always show as upside down even though I use Core.flip(mRotated, mRotated, 1); one more time in the gray() & rgba(). Any idea?

oonetech gravatar imageoonetech ( 2017-02-05 08:07:13 -0600 )edit
0

answered 2019-12-09 02:47:24 -0600

I found a solution for this.

Tested - working fine. :)

Just added few lines of code to OpenCV Library JavaCameraView class.

Step 1. Go to OpenCVLibrary > Java > org.opencv > android > JavaCameraView

image description

Step 2. Add this method anywhere in the JavaCameraView class

private void setDisplayOrientation(Camera mCamera, int angle) {
    Method downPolymorphic;
    try
    {
        downPolymorphic = mCamera.getClass().getMethod("setDisplayOrientation", new Class[] { int.class });
        if (downPolymorphic != null)
            downPolymorphic.invoke(mCamera, new Object[] { angle });
    }
    catch (Exception e1)
    {
    }
}

Step 3. Search for mCamera.startPreview(); in the class and paste this code just above this.

setDisplayOrientation(mCamera, 90);
mCamera.setPreviewDisplay(getHolder());

Just like this. image description

Run your code.

Happy Coding!

edit flag offensive delete link more

Comments

====================================================== ERROR E/AndroidRuntime: FATAL EXCEPTION: Thread-4 Process: com.example.androidseries, PID: 24068 java.lang.NullPointerException: Attempt to invoke virtual method 'void org.opencv.dnn.Net.setInput(org.opencv.core.Mat)' on a null object reference at com.example.androidseries.MainActivity.onCameraFrame(MainActivity.java:183) at org.opencv.android.CameraBridgeViewBase.deliverAndDrawFrame(CameraBridgeViewBase.java:392) at org.opencv.android.JavaCameraView$CameraWorker.run(JavaCameraView.java:393) at java.lang.Thread.run(Thread.java:764)

mrescorcia gravatar imagemrescorcia ( 2020-10-27 21:14:16 -0600 )edit

=============================================MainActivity.java:183

180:Mat imageBlob = Dnn.blobFromImage(frame, 0.00392, new Size(416,416),new Scalar(0, 0, 0),/swapRB/false, /crop/false);

183:tinyYolo.setInput(imageBlob);

mrescorcia gravatar imagemrescorcia ( 2020-10-27 21:17:06 -0600 )edit

@mrescorcia your comments are meaningless here. if you need help ask a question

sturkmen gravatar imagesturkmen ( 2020-10-27 21:25:06 -0600 )edit
0

answered 2013-09-29 01:02:58 -0600

itay gravatar image

Try this code it works for me:

 public Mat onCameraFrame(CvCameraViewFrame inputFrame) { 
 mRgba = inputFrame.rgba();
 Mat mRgbaT = mRgba.t();
 Core.flip(mRgba.t(), mRgbaT, 1);
 Imgproc.resize(mRgbaT, mRgbaT, mRgba.size());
 return mRgbaT; }

Little explanation: first i load the input matrix, then i made a matrix pattern with the new size, then i flip it (so the image flip by 90 degrees) and finally i return to the original matrix size.

edit flag offensive delete link more

Comments

This results in massive performance degradation... still trying to find a way to do it without pixel manipulations in opencv...

wpccolorblind gravatar imagewpccolorblind ( 2014-02-12 01:00:13 -0600 )edit

I tried this, it does flip the image by 90 degrees but degrades performance and pinches the image.

khanaliaamir gravatar imagekhanaliaamir ( 2019-12-09 01:15:11 -0600 )edit
-1

answered 2013-03-02 03:54:53 -0600

matfar92 gravatar image

I've just set up my environment yesterday and plan to start working later on. I have just done the 'hello world' example in this link http://docs.opencv.org/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.html#dev-with-ocv-on-android

and after searching quite well for this issue I found this article which I have not tried yet:

http://developer.sonymobile.com/knowledge-base/tutorials/android_tutorial/get-started-with-opencv-on-android/

and this is my 2nd prefered link:

http://littlecheesecake.wordpress.com/2012/03/12/display-orientation-issue-when-working-with-opencv-on-android/

All the best and good luck

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2013-02-12 08:28:41 -0600

Seen: 34,353 times

Last updated: Mar 12 '14