I have created a camera app and using the data to do something .But the data is always in landscape mode .
I have tried this which is making the preview in portrait mode but the byte[] I am getting still gives me a landscape photo.
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
mCamera.setDisplayOrientation(90);
I know I can make it as a bitmap and rotate it 90 but I need only the data from onPictureTaken.
I also tried
param.setRotation(90);
Which is not working on some of the devices.
You are right, this is how camera API works (unlike iOS). There are some efficient methods that can rotate the pixels to portrait if you really need this, but they never come at 0 cost. So the best practice is to adjust your code that processes the arriving preview frames.
I'm using Android + Opencv(new to opencv) and I'm currently working with real time object detection (the object stays really close to the android device Camera) , and I noticed that the Android camera's autoFocus keeps modifying my frames (kind of 'zoom in' and 'zoom out' effect) which make it harder for me to keep tracking the object.
I need to turn the "AUTO FOCUS" off because in my case the more blurred image input I have, the better, and I also need to turn the AutoWhiteBalance off as well, or maybe set to a different value.
I would like to know how to do it through my OpenCV CameraBridgeViewBase so I could modify the camera's Focus/WhiteBalance settings.
I've trying to find a way to solve it, and I noticed that many people face the same problems.
Here, at Stack Overflow, would be a great place to find someone who have worked with that and found a good way to overcome these problems.
create your own subclass of javacameraview
public class MyJavaCameraView extends JavaCameraView {
where you can have access to mCamera;
add whatever camera access using method you are interested in
for example
// Setup the camera
public void setFlashMode(boolean flashLightON) {
Camera camera = mCamera;
if (camera != null) {
Camera.Parameters params = camera.getParameters();
params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
camera.setParameters(params);
and use this new class as part of the main activity
//force java camera
mOpenCvCameraView = (MyJavaCameraView) findViewById(R.id.activity_surface_view);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
mOpenCvCameraView.enableView();
In my android app, I am trying to do some image recognition, and I want to open the camera and see the camera generated images before even taking a pic, like the camera browse mode.
Basically as you browse I want to continuously grab the current screen and then read it and generate some object to update some text on the screen. Something like this
#Override
// this gets called every 5 seconds while in camera browse mode. bitmap is the image of the camera currently
public void getScreen(Bitmap bitmap) {
MyData data = myalgorithm(bitmap);
displayCountOnScreen(data);
}
I saw this app https://play.google.com/store/apps/details?id=com.fingersoft.cartooncamera&hl=en
and in camera browse mode, they change the screen and put some other GUI stuff on the screen. I want to do that too.
Anyone know how I can do this?
Thanks
If all you want to do is put some GUI elements on the screen, then there is no need to fetch all the preview frames as Bitmaps (though you could do that as well, if you want):
Create a layout with a SurfaceView for where you want the video data to appear, and then put other views on top.
In onCreate, you can get it like this:
surfaceView = (SurfaceView)findViewById(R.id.cameraSurfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this); // For when you need to know when it changes.
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
When you create a camera, you need to pass it a Surface to display the preview on, see:
http://developer.android.com/reference/android/hardware/Camera.html#setPreviewDisplay(android.view.SurfaceHolder):
Camera camera = ...
...
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
If you want to do image recognition, what you want are the raw image bytes to work with. In this case, register a PreviewCallback, see here:
http://developer.android.com/reference/android/hardware/Camera.html#setPreviewCallbackWithBuffer(android.hardware.Camera.PreviewCallback)
Using API 14 I have created an Activity which uses face detection successfully (I'm a bit of a newb at this Face Detection stuff).
I don't want to show the preview of the Camera however; I just want to know when the user's face is in front of the camera. I added a few buttons to make the SurfaceView Visible/Invisible and I found that the face detection stops working when it is INVISIBLE or GONE.
Is there a way to enable the face detection without requiring the SurfaceView in the layout?
Here is how I have coded it:
mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.startPreview();
if(mCamera.getParameters().getMaxNumDetectedFaces() >0) {
mCamera.setFaceDetectionListener(new Camera.FaceDetectionListener() {
#Override public void onFaceDetection(Face[] faces, Camera camera) {
if(faces.length > 0) {
System.out.println("Found someone");
}
}
});
mCamera.startFaceDetection();
}
To hide the surfaceview I have added a black View. :-)
<View android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000"/>
I've had a reasonable look around and I haven't found much code using startFaceDetection() yet.
Thanks for any ideas / help.
You should rather use a dummy SurfaceTexture for your purposes.
Just create a SurfaceTexture object by passing any integer such as
mSurfaceTexture = new SurfaceTexture(1);
Now, open your camera and do the following:
mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
try{
mCamera.setPreviewTexture(mSurfaceTexture);
}
catch (IOException t) {
//Do Something here
}
3) You can do everything else just the same way i.e. using face detection.
The Camera Preview doesn't get displayed if you omit
setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
I have not yet tested this with Face Detection (no 4.0 device and the emulator doesn't yet support it). But it should work.
Reference: https://groups.google.com/forum/?fromgroups#!topic/android-developers/EzBgJRetaCo
You could also attempt to use setPreviewTexture(SurfaceTexture st) instead of setPreviewDisplay and use a SurfaceTexture that you can control.
in my Android app, I observed that the video recorded from the front camera is being recorded with 7-10 fps while the back camera does the job fine, the native camera app does record video from front cam at 29fps.
I use the following function to set the frame rate
myRecorder.setVideoFrameRate(30);
but somehow it records it at 8fps. what is the problem? Also the lighting conditions seem to improve it to 15fps, but I want it to be atleast >25fps how can I achieve this? Can we use NDK for this purpose?
I'm exploring the same problem. Because the MediaRecorder already has a native implementation, using the NDK doesn't seem to be a promising approach to increasing the frames per second. Improving the buffering with setPreviewCallbackWithBuffer as shown in the code at http://www.androidadb.com/source/cellbots-read-only/experimental/android/ioio/samples/ShootOnSight/src/com/cellbots/ioioshoot/CameraView.java.html seems promising but I first would like to get a better understanding of the many camera parameters and how they affect frame rate.
As you surely know, there is a wide range of Android devices with a wide range of camera capabilities. To see the capabilities of your particular front and back cameras, you can use the following code (e.g., setting mCameraId to 0 for rear facing and to 1 for front facing).
Camera mCamera = Camera.open(mCameraId);
Camera.Parameters cp = mCamera.getParameters();
Log.d(TAG, "camera parameters: " + cp.flatten());
For example, here are the camera parameters dumped by my Nexus S (running OS 4.0.4).
NEXUS-S FRONT FACING CAMERA PARAMETERS:
06-16 15:14:16.909: D/SENSORS_PLUS(24583): camera parameters:
picture-size-values=640x480;
preview-fps-range=7500,30000;
min-exposure-compensation=-4;
vertical-view-angle=39.4;
horizontal-view-angle=51.2;
whitebalance=auto;
jpeg-thumbnail-height=120;
jpeg-quality=100;
preview-format-values=yuv420sp,yuv420p;
rotation=0;
jpeg-thumbnail-quality=100;
focus-mode=fixed;
preview-format=yuv420sp;
preview-size=640x480;
focal-length=0.9;
video-frame-format=yuv420p;
picture-format-values=jpeg;
max-exposure-compensation=4;
exposure-compensation=0;
preview-frame-rate-values=15;
exposure-compensation-step=0.5;
preview-frame-rate=15;
effect-values=none,mono,negative,sepia;
focus-mode-values=fixed;
picture-size=640x480;
effect=none;
jpeg-thumbnail-width=160;
whitebalance-values=auto,incandescent,fluorescent,daylight,cloudy-daylight;
picture-format=jpeg;
focus-distances=0.20,0.25,Infinity;
preview-fps-range-values=(7500,30000);
jpeg-thumbnail-size-values=160x120,0x0;
preview-size-values=640x480,320x240,176x144
NEXUS-S REAR FACING CAMERA PARAMETERS:
06-16 15:46:55.315: D/SENSORS_PLUS(24732): camera parameters:
picture-size-values=2560x1920,2048x1536,1600x1200,1280x960,640x480;
preview-fps-range=15000,30000;
min-exposure-compensation=-4;
vertical-view-angle=39.4;
horizontal-view-angle=51.2;
whitebalance=auto;
jpeg-thumbnail-height=240;
scene-mode=auto;
jpeg-quality=100;
preview-format-values=yuv420sp,yuv420p;
rotation=0;
jpeg-thumbnail-quality=100;
focus-mode=auto;
preview-format=yuv420sp;
preview-size=720x480;
focal-length=3.43;
video-frame-format=yuv420p;
picture-format-values=jpeg;
max-exposure-compensation=4;
flash-mode-values=on,off,auto,torch;
exposure-compensation=0;
preview-frame-rate-values=30;
exposure-compensation-step=0.5;
preview-frame-rate=30;
flash-mode=off;
effect-values=none,mono,negative,sepia;
focus-mode-values=auto,infinity,macro;
picture-size=2560x1920;
effect=none;
jpeg-thumbnail-width=320;
whitebalance-values=auto,incandescent,fluorescent,daylight,cloudy-daylight;
scene-mode-values=auto,portrait,landscape,night,beach,snow,sunset,fireworks,sports,party,candlelight;
picture-format=jpeg;
focus-distances=0.10,1.20,Infinity;
preview-fps-range-values=(15000,30000);
jpeg-thumbnail-size-values=320x240,0x0;
preview-size-values=720x480,640x480,352x288,176x144
Following setting works for some mobile for 30 FPS.
Camera.Parameters parms = camera.getParameters();
parms.setRecordingHint(true);
camera.setParameters(parms);