Java – how to force the Android camera to display in portrait mode or let me rotate
I'm a new post, so please! I saw almost all the other questions related to this and tried the most, but I was completely frustrated I just want my Android phone to display the camera in portrait mode, not the scenery I just modified the image manipulations example provided by OpenCV
I use opencv 3.01, Android SDK version 23, Android studio 2.0 and Android version 6.0 1 nexus 5 mobile phone This is April 28, 2016. This is the latest stable version of almost everything
I'm already at Android manifest Force the application into vertical mode in the XML file:
android:screenOrientation="portrait"
And the entire application is displayed correctly in portrait mode, but the displayed camera image is rotated 90 degrees In other words, if you tilt your head 90 degrees to the left, you will see the appropriate image So I need to rotate the image to the right
I tried using OpenCV tutorial3 code and setdisplayorientation (90):
public void setResolution(Size resolution) { disconnectCamera(); mMaxHeight = resolution.height; mMaxWidth = resolution.width; // mCamera.setDisplayOrientation(90); //* Crashes if placed here connectCamera(getWidth(),getHeight()); mCamera.setDisplayOrientation(90); //* Doesn't crash if here,but doesn't work either }
That doesn't work In any case, this tutorial uses the "camera" class discarded in Android version 21 and replaces it with the "Camera2" class I didn't go any further because I wanted to use the latest API, but maybe something in Camera2 could work?
Some people have released the use of "transpose" and "flip" functions to rotate images. I have tried to do many such things in the oncameraframe method:
Original, works, but rotation:
public Mat onCameraFrame(CvCameraViewFrame inputFrame) { Mat rgba = inputFrame.rgba(); ... do stuff to the image ... return rgba;
The image display darkens and my FPS calculation becomes zero (strange):
public Mat onCameraFrame(CvCameraViewFrame inputFrame) { Mat rgba = inputFrame.rgba(); // Rotate clockwise 90 degrees Core.transpose(rgba,rgba); Core.flip(rgba,rgba,1); ... do stuff to the image ... return rgba;
Rotate 180 degrees and the video display again, now flip, but still in landscape mode:
public Mat onCameraFrame(CvCameraViewFrame inputFrame) { Mat rgba = inputFrame.rgba(); // Rotate clockwise 90 degrees,then 90 degrees again Core.transpose(rgba,1); Core.transpose(rgba,1); ... do stuff to the image ... return rgba;
Therefore, if oncameraframe returns a mat different from the original resolution, it is displayed as blank The documentation about oncameraframe is rough – so is this true?
Is there another place where I should try to rotate this image before calling oncameraframe? Is there any other way to simply force the camera to provide a frame in portrait mode?
Solution
Setdisplayorientation is applicable to the standard preview output of the camera (directly connected to camear's surfaceview or TextureView), but opencv is located here, and the way of receiving data is not affected by setdisplayorientation
Transpose will change the size of the image array. Unless the rest of the sample knows how to deal with this, you will encounter problems You must track the code to see assumptions about the buffer size (for example, the output buffer drawn to the UI) and update them accordingly to become the transpose size after you insert the transpose point
Ideally, there are some ways to set the direction on the output view drawn by opencv, but I don't know if such a control exists in the opencv sample