I developed a custom camera using camera2 api, i make zoom in and zoom out feature like this.
Camera.Parameters params = mCamera.getParameters();
int value = params.getMaxZoom();
params.setZoom(value);
It works for me, but how can I zoom camera by float number like 2.4f ?
Can any one help me, please?
https://developer.android.com/reference/android/hardware/Camera.Parameters.html#getMaxZoom()
Sets current zoom value. If the camera is zoomed (value > 0), the actual picture size may be smaller than picture size setting.
https://developer.android.com/reference/android/hardware/Camera.Parameters.html#setZoom(int)
setZoom takes an Integer (whole number) so you can't set the zoom to a float.
The newest Android CameraX api's can Zoom using a Rect: https://developer.android.com/reference/androidx/camera/core/Preview.html#zoom(android.graphics.Rect) (but under the hood it relies on Camera2 so I wouldn't hold out much hope for hardware float zoom.
Related
I'm using Google Vision for face detection on Android. Currently my code:
public void onPreviewFrame(byte[] data, Camera camera) {
// creating Google Vision frame from a camera frame for face recognition
com.google.android.gms.vision.Frame frame = new com.google.android.gms.vision.Frame.Builder()
.setImageData(ByteBuffer.wrap(data), previewWidth,
previewHeight, ImageFormat.NV21)
.setId(frameId++)
.setRotation(com.google.android.gms.vision.Frame.ROTATION_270)
.setTimestampMillis(lastTimestamp).build();
// recognize the face in the frame
SparseArray<Face> faces = detector.detect(frame);
// wrong coordinates
float x = faces.valueAt(0).getPosition().x;
float y = faces.valueAt(0).getPosition().y;
}
The problem is that x and y are not correct and even negative sometimes. I know that to get correct coordinates it should be rotated somehow, but how exactly?
These coordinates can be negative if the face extends beyond the top and/or the left edges of the image. Even though the head may not be entirely within the photo, the face detector will estimate the bounding box of the face beyond the image bounds based upon what is visible.
The coordinates should be correct relative to the image. However, if you are drawing on a preview from the front-facing camera, note that this preview is displayed reversed (like a mirror image). In this case, you'd need to reverse the coordinates on order to draw on the preview. See an example of how this is done here:
https://github.com/googlesamples/android-vision/blob/master/visionSamples/FaceTracker/app/src/main/java/com/google/android/gms/samples/vision/face/facetracker/ui/camera/GraphicOverlay.java#L101
I'm trying to draw a text on a face using android face detection API.
Right now, I did this
for(Landmark landmark : face.getLandmarks()){
if(landmark.getType() == Landmark.NOSE_BASE){
Bitmap moustache = BitmapFactory.decodeResource(resources, R.drawable.moustache);
canvas.drawText("=====", landmark.getPosition().x, landmark.getPosition().y, mIdPaint);
}
}
but turns out the text ===== is draw on top of the head, and I don't know why.
If someone need more code, just let me know
If you are drawing graphics over a live camera preview, you need to take a few things into account:
the device's rotation
the scale of the view relative to the size of the preview image
whether you are using the front facing camera (which will mirror the image)
The sample code for the face tracker demo has utility methods (translateX, translateY, scaleX, scaleY) to help with this:
https://github.com/googlesamples/android-vision/blob/master/visionSamples/FaceTracker/app/src/main/java/com/google/android/gms/samples/vision/face/facetracker/FaceGraphic.java#L99
https://github.com/googlesamples/android-vision/blob/master/visionSamples/FaceTracker/app/src/main/java/com/google/android/gms/samples/vision/face/facetracker/ui/camera/GraphicOverlay.java#L100
I am developing a game in libgdx where I need to zoom in and zoom out a popup for clearing every stage in the game. Could you please guide me how to do zoom effects in libgdx.
Just a note I am doing this for android device.
Kindly assist.
You can zoom using the property of same name of OrtographicCamera.
camera.zoom = 1; //Normal zoom (default)
camera.zoom = 2; //Zoomed in
camera.zoom = 0.5F; //Zoomed out
If you mean "zooming" a particular image, then just make it bigger and smaller.
To make your sprite larger or smaller use sprite.setScale, where 1 is the default size, 2 is 2 time bigger, 0.5 half.. you understand.
But if you want to make like a screen transition better use camera zoom, as described in the post above.
I just setup a very basic camera preview that displays the camera full screen. I compared the smoothness of both my app and the android camera and figured that the android camera seems a lot smoother.
Why is that the case? Are there any special tricks to improve the camera preview performance?
I faced the same issue a time ago, and it turned out to be related with the camera resolution. Chances are that your Camera is initializing with the maximum available resolution, which may slow down performance during preview. Try and set a lower picture size with something like this.-
Camera.Parameters params = camera.getParameters();
params.setPictureSize(1280, 960);
camera.setParameters(params);
Notice that you'll need to set an available picture size. You can check available sizes with
camera.getParameters().getSupportedPictureSizes();
Hope it helps.
EDIT
It seems using a picture size with different aspect ratio than the default one, slows down performance as well. This is how I choose my pictureSize.-
First off, I get the aspect ratio of the camera default pictureSize
Camera.Parameters params = camera.getParameters();
defaultCameraRatio = (float) params.getPictureSize().width / (float) params.getPictureSize().height;
And then I get a lower pictureSize that fits the same ratio.-
private Size getPreferredPictureSize() {
Size res = null;
List<Size> sizes = camera.getParameters().getSupportedPictureSizes();
for (Size s : sizes) {
float ratio = (float) s.width / (float) s.height;
if (ratio == defaultCameraRatio && s.height <= PHOTO_HEIGHT_THRESHOLD) {
res = s;
break;
}
}
return res;
}
Where PHOTO_HEIGHT_THRESHOLD is the max height you want to allow.
This answer is a bit late, but after struggling with the same problem, I figured I'd share what I found.
Not only was I unable to match the stock camera's "smoothness", but I was also unable to match the metering of the stock camera. My live preview was much darker compared to the stock camera, especially in low light situations.
My solution was ultimately an FPS issue, as originally proposed by Robin in an early comment.
The default preview FPS on the Nexus 5 is a static 15 FPS. The stock android app detects and sets a preview FPS that uses a dynamic range (as long as that range includes 30fps). On a nexus 5, that range is 7fps -> 30fps. In low light the camera drops to a lower FPS to keep the preview bright, while in bright conditions it jumps to a smooth 30 fps.
Relevant code from the stock android photo app:
The call to set the FPS starts on line 1560 of com.android.camera.PhotoModule (https://android.googlesource.com/platform/packages/apps/Camera2/+/android-4.4.4_r2.0.1/src/com/android/camera/PhotoModule.java).
The utility it uses to identify the ideal FPS starts on line 833 of com.android.camera.util.CameraUtil (https://android.googlesource.com/platform/packages/apps/Camera2/+/android-4.4.4_r2.0.1/src/com/android/camera/util/CameraUtil.java)
Here's are the camera api calls to set the FPS using hard coded values (for the sake of simplicity) specific to a Nexus 5.
public void setFps(Camera camera) {
Camera.Parameters params = camera.getParameters();
params.setPreviewFpsRange(7000, 30000);
camera.setParameters(params);
}
I'd like to project images on a wall using camera. Images, essentially, must scale regarding the distance between camera and the wall.
Firstly, I made distance calculations by using right triangle trigonometry(visionHeight * Math.tan(a)). It's not 100% exact but yet close to real values.
Secondly, knowing the distance we can try to figure out all panorama height by using isosceles triangle trigonometry formula: c = a * tan(A);
A = mCamera.getParameters().getVerticalViewAngle();
The results are about 30% greater than the actual object height and it's kinda weird.
double panoramaHeight = (distance * Math.tan( mCamera.getParameters().getVerticalViewAngle() / 2 * 0.0174532925)) * 2;
I've also tried figuring out those angles using the same isosceles triangle's formula, but now knowing the distance and the height. I got 28 and 48 degrees angles.
Does it mean that android camera doesn't render everything it shoots ? And, what other solutions you can suggest ?
Web search shows that the values returned by getVerticalViewAngle() cannot be blindly trusted on all devices; also note that you should take into account the zoom level and aspect ratio, see Determine angle of view of smartphone camera