issues in working with android portrait mode with opencv - android

I know this is one of the most repeated questions, however, no working solution found anywhere, after putting so much of efforts.
This is really a killing issue though it might be a simple one for the experts.
I am working on opencv Haar Cascade classifiers.(Eg: Face Detection, Eye Pair Detection)
I have just taken the face-detection sample code from the "OpenCV-2.4.9-android-sdk" - samples.
This sample code is set in Landscape mode and everything is working fine.
However, i want to make make the classifiers work in portrait mode. I know the haar classifiers were not made to work with portrait mode.
As opencv uses "CameraBridgeViewBase", i don't have all controls to play with the resolution of the camera and displaying the
images back on the screen.(preview)
Now, the moment i set the screen orientation as "android:screenOrientation="portrait", the images is rotated 90deg clock wise.
What have i tried:
To preview the portrait image without rotation: i modified the "deliverAndDrawFrame" in "CameraBridgeViewBase" by adding
Matrix matrix = new Matrix();
matrix.preTranslate((canvas.getWidth() - mCacheBitmap.getWidth()) / 2,(canvas.getHeight() - mCacheBitmap.getHeight()) / 2);
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
matrix.postRotate(90f,(canvas.getWidth()) / 2,(canvas.getHeight()) / 2);
canvas.drawBitmap(mCacheBitmap, matrix, null);
To make the classifier work with portrait mode:
I played with all kinds of permutation and combination of transpose and flip to rotate the grey scale image that i pass to detectmultiscale in "onCameraFrame".
What is my issue?
I am not able to get the images with native resolution which is higher than what i get at "onCameraFrame".
How to get the original or actual or native quality of the images upto the camera sensors capacity?
As i already put a lot efforts on making the classifier work with portrait mode without any luck, any kind of suggestions/sample codes/reference which are working,would help me a lot.

I found a solution:
Matrix matrix = new Matrix();
matrix.preTranslate((canvas.getWidth() - mCacheBitmap.getWidth()) / 2,(canvas.getHeight() - mCacheBitmap.getHeight()) / 2);
matrix.postRotate(90f,(canvas.getWidth()) / 2,(canvas.getHeight()) / 2);
float scale = (float) canvas.getWidth() / (float) mCacheBitmap.getHeight();
matrix.postScale(scale, scale, canvas.getWidth()/2 , canvas.getHeight()/2 );
canvas.drawBitmap(mCacheBitmap, matrix, new Paint());
This delivers portrait mode with CORRECT scale :D try it please. I'm using OpenCV 3.4 .

Related

Rotating a Spirte Rectangle 90 degrees doesn't repect aspect ratio in iOS

am working in a OpenGL ES 2.0 game, in iOS platform using basically C++. And I wanted to implement both both portrait and landscape orientation doing a 90 degrees rotation.
The problem I have is very simple. I have one sprite that is in one rectangle and if I do a rotation of 90 degrees and expected to see the same figure rotated.
The problem I have is that is a noticeable difference in the figure, both in aspect ratio and size.
In one orientation:
8.4 cm x 5.0 cm
The other:
7.6 cm x 5.4 cm
I wonder if it that is posible be casued by errors caused by float machine representation? Has someone had also that problem?
In the first test I do:
glm::mat4 ProjModelViewMatrix = glm::ortho<float>(-1.0, +1.0, -1.5f, 1.5f);
/// DRAW CODE
In the second test I ONLY add a rotation matrix:
glm::mat4 rotation = glm::rotate(glm::mat4(1.0), -PI_F / 2.0f, glm::vec3(0.0f,0.0f,1.0f));
glm::mat4 ProjModelViewMatrix = glm::ortho<float>(-1.0, +1.0, -1.5f, 1.5f) * rotation;
/// DRAW CODE
Just in case:
ALL THE vertices are in the plane z=0.
The sprite is mapped in a rectangle.
I wonder if it that is possible be caused by errors caused by float
machine representation?
If you are running this on the CPU with fp32 calculations it's very very unlikely - you'd need a a large absolute error to get that much size change on screen, and floating point error doesn't accumulate that quickly in only a handful of multiplies.
Couple of ideas:
What are the values in the 4x4 rotation matrix?
Matrix multiplication is order sensitive - are you multiplying the together in the right order? I'm not sure how glm lays out its matrices in memory, so you may be correct here.
I could find the reason. I was thinking that the iOS device has 2:3 aspect ratio and in fact it is 3:4 !

Screen support in LigGDX(Ios and Android)

I am building my game for a resolution of 800x480.
I would like to know will the engine automatically scale the scene if it is on a smaller or larger device?
Also, how do you set a default width and height for the new Robovm projects?
I am using Box2D and not to sure how the screen supports work for the different devices such as iphone and the android.
P.S i know scaling isnt the best option but for my case it will be fine.
A piece of advice, if you are using box2d than with this approach you are going to face lot of problems with your physics behaviour as your values are to large for camera.For example Bodies will pass each other without colliding and other such stuff.
To solve this problem use camera value as
camera.viewportHeight = scrh/40f;
camera.viewportWidth = scrw/40f;
camera.position.set(camera.viewportWidth/2f,camera.viewportHeight/2f, 0f);
camera.update();
`
and while drawing any asset set its size to orignal size/40f
so that world step calculations will be in terms of 20 ,12 and not 800,480 an dthus improving ur physics behaviour.
For non box2d screens Sandeep's solution will always work fine for u.
yes the engine will scalee it but for that you have to set a view port
in your create method do this
float scrw = 800;
float scrh = 480;
camera = new OrthographicCamera();
camera.viewportHeight = scrh;
camera.viewportWidth = scrw;
camera.position.set(camera.viewportWidth * .5f,camera.viewportHeight * .5f, 0f);
camera.update();`
Yes you have to do this in each screen...

How can I code my game to work on every resolution of Android devices? (with Unity)

I have a game what I made in 480x320 resolution (I have set it in the build settings) in Unity. But I would like to publish my game for every Android device with every resolution. How can I do it, to tell Unity to scale my game up to the device's resolution? Is it possible to do?
Thanks in advance!
The answer to your question largely depends on how you've implemented the game. If you've created it using GUI textures, then it largely depends on how you've placed/sized your objects versus screen size, which makes things a little tricky.
If the majority of your game is done using objects (such as planes, cubes, etc) then there's two methods I usually choose to use.
1) First method is very easy to implement, though doesn't always look too good. You can simply change the camera's aspect ratio to match the one you've designed your game around. So in your case, since you've designed your game at 4:3, you'd do something like this:
Camera.aspect = 4f/3f;
However, if someone's playing on a screen meant for 16:9, the game will end up looking distorted and stretched.
2) The second method isn't as easy, requiring quite a bit of work and calculations, but will give a much cleaner looking result for you. If you're using an orthographic camera, one important thing to keep in mind is that regardless of what screen resolution is being used, the orthographic camera keeps the height at a set height and only changes the width. For example, with an orthographic camera at a size of 10, the height will be set to 2. With this in mind what you'd need to do is compensate for the widest possible camera within each level (for example, have a wide background) or dynamically change the Orthographic Size of the camera until its width matches what you've created.
If you've done a 3d game with a stereoscopic camera , screen resolution shouldn't really affect how it looks, but I guess that depends on the game, so more info would be required
The way i did is to change camera viewport according to device aspect ratio
Consider you made the game for 800x1280
The you can do this in any one of the script
float xFactor = Screen.width / 800f;
float yFactor = Screen.height / 1280f;
Camera.main.rect=new Rect(0,0,1,xFactor/yFactor);
and this works like magic
A easy way to do this is considering your target, I mean if you're doing a game for Iphone 5 then the aspect ratio is 9:16 v or 16:9 h.
public float targetRatio = 9f/16f; //The aspect ratio you did for the game.
void Start()
{
Camera cam = GetComponent<Camera>();
cam.aspect = targetRatio;
}
Here is my script for scaling the ortographic camera in 2D games
public float screenHeight = 1920f;
public float screenWidth = 1080f;
public float targetAspect = 9f / 16f;
public float orthographicSize;
private Camera mainCamera;
// Use this for initialization
void Start () {
// Initialize variables
mainCamera = Camera.main;
orthographicSize = mainCamera.orthographicSize;
// Calculating ortographic width
float orthoWidth = orthographicSize / screenHeight * screenWidth;
// Setting aspect ration
orthoWidth = orthoWidth / (targetAspect / mainCamera.aspect);
// Setting Size
Camera.main.orthographicSize = (orthoWidth / Screen.width * Screen.height);
}
I assume it's 2D instead of 3D, this what I do:
Create a Canvas object
Set the Canvas Scaler to Scale with Screen Size
Set the Reference Resolution to for example: 480x320
Set the Screen Match Mode to match width or height
Set the match to 1 if your current screen width is smaller (0 if height is smaller)
Create an Image as background inside the Canvas
Add Aspect Ratio Fitter script
Set the Aspect Mode to Fit in Parent (so the UI anchor can be anywhere)
Set the Aspect Ratio to 480/320 = 1.5
And add this snippet on main Canvas' Awake method:
var canvasScaler = GetComponent<CanvasScaler>();
var ratio = Screen.height / (float) Screen.width;
var rr = canvasScaler.referenceResolution;
canvasScaler.matchWidthOrHeight = (ratio < rr.x / rr.y) ? 1 : 0;
//Make sure to add Using Unity.UI on top of your Aspect Ratio Script!
For 3D objects you can use any of the answers above
The best solution for me is to use the theorem of intersecting lines so that there is neither a cut-off on the sides nor a distortion of the game view. That means that you have to step back or forward depending on the different aspect ratio.
If you like, I have an asset on the Unity asset store which automatically corrects the camera distance so you never have a distortion or a cut off no matter which handheld device you are using.

android.graphics.camera Error

I am developing an Android app on eclipse and have been using android.graphics.camera to 3d transform images. In a nutshell, my app takes a 2d image and gives it perspective. My problem is that I also want to rotate the image around the screen while it is being transformed.
final Matrix mMatrix = canvas.getMatrix();
canvas.save();
mCamera.save();
mCamera.rotateX(60);
mCamera.rotateY(0);
mCamera.rotateZ(0);
mCamera.getMatrix(mMatrix);
mMatrix.preTranslate(-this.gridWidth / 2, -this.gridHeight);
mMatrix.postTranslate(this.gridWidth / 2, this.gridHeight);
canvas.concat(mMatrix);
mCamera.restore();
//Draw and move image here
canvas.restore();
When the image gets to the bottom of the screen, where the camera is translated, the image becomes distorted. I see pieces of it on the screen but its like its being drawn backwards or sideways. I've also tried rotating the image using the rotateZ property but the same effect occurs. Once the image gets 'behind' the translation point, it just goes nuts.
I thought it might be an emulator bug so I loaded it on my Droid X and Acer Iconia and the effect remains the same.
I haven't seen anybody else have this problem so i figured someone here might have a clue as to what's going on.
Any Ideas?
This issue can be addressed with newer versions of Android that let you change the camera distance:
http://developer.android.com/reference/android/graphics/Camera.html#setLocation(float, float, float)

Want to have several alternative perspective options in GL

So I've set up the perspective for my view in the onSurfaceCreate method using this:
float size = .01f * (float) Math.tan(Math.toRadians(45.0) / 2);
float ratio = _width / _height;
// perspective:
gl.glFrustumf(-size, size, -size / ratio, size / ratio, 0.01f, 110.0f);
It's more or less identical to this tutorial:
http://www.droidnova.com/android-3d-game-tutorial-part-vi,436.html
BUT i want to be able to switch between 45.0 and other angles of view. When I try to change the values of
gl.glFrustumf
later, the screen goes blank! I can manually set the angle in the onSurfaceCreate method but I can't figure out how to have the option to change between 2 perspective views without restarting the app. Can anyone help?
Thanks for your time
Do you clear the projection matrix before calling glFrustum the second time? OpenGL somewhat unintuitively multiplies the frustum matrix with the previous matrix on the stack. If you call glFrustum several times in succession without resetting the projection matrix you will get a nonsensical result.

Categories

Resources