当前位置:   article > 正文

移动端视觉SLAM学习笔记 (二) 图像获取_android slam

android slam

开发平台一开始考虑了Qt和Unity,都是跨平台的,但是对Android的原生支持都不太好,对权限的获取和硬件的控制都有一些或大或小的坑,考虑到SLAM对传感器的要求比较高,未来要获取和设置摄像头的焦距、曝光等参数,还是选择了原生平台:Android Studio。

图像算法库这块还是对OpenCV比较熟悉,准备以OpenCV未基础。OpenCV也有对Android系统的支持,但是自己去搞是不可能的(●ˇ∀ˇ●),果断找现成的,想起了之前用过的JavaCV(已经把OpenCV编译好了,还有很多别的库,很方便):

 

编程是个糙活,细节咱就不考虑那么多了,有现成的用就最好了,专注于核心功能的开发吧。Android Studio在使用第三方库方面绝对是各平台之首,直接引用需要的版本就好:

确定了用OpenCV,那么其它就都围绕着OpenCV来做了。相机的获取就用Android原生的API:importandroid.hardware.Camera。那么,再找个现成的吧,JavaCV的sample里就有相关的例子:

https://github.com/bytedeco/sample-projects/blob/master/javacv-android-camera-preview/app/src/main/java/org/bytedeco/javacv/android/example/CvCameraPreview.java

直接将相机获取的图像转成cv::Mat,至此图像就得到了。

---------------------------------更改-----------------------------------------

实际试了下,发现问题还挺多,还是用Android官方的例子android-Camera2Basic改吧,网上有不少相关的例子,整理代码如下(其中从cv::Mat还是用JavaCV做的):

  1. package com.example.visualtest;
  2. import androidx.annotation.NonNull;
  3. import androidx.appcompat.app.AppCompatActivity;
  4. import androidx.core.app.ActivityCompat;
  5. import androidx.core.content.ContextCompat;
  6. import android.Manifest;
  7. import android.app.Activity;
  8. import android.content.pm.PackageManager;
  9. import android.graphics.Bitmap;
  10. import android.graphics.BitmapFactory;
  11. import android.graphics.ImageFormat;
  12. import android.graphics.SurfaceTexture;
  13. import android.hardware.camera2.CameraAccessException;
  14. import android.hardware.camera2.CameraCaptureSession;
  15. import android.hardware.camera2.CameraCharacteristics;
  16. import android.hardware.camera2.CameraDevice;
  17. import android.hardware.camera2.CameraManager;
  18. import android.hardware.camera2.CaptureRequest;
  19. import android.hardware.camera2.params.StreamConfigurationMap;
  20. import android.media.Image;
  21. import android.media.ImageReader;
  22. import android.os.Bundle;
  23. import android.os.Handler;
  24. import android.os.HandlerThread;
  25. import android.util.Log;
  26. import android.util.Size;
  27. import android.view.SurfaceHolder;
  28. import android.view.SurfaceView;
  29. import android.view.View;
  30. import android.view.Window;
  31. import android.view.WindowManager;
  32. import java.nio.ByteBuffer;
  33. import java.util.Arrays;
  34. import org.bytedeco.javacv.AndroidFrameConverter;
  35. import org.bytedeco.javacv.OpenCVFrameConverter;
  36. import org.bytedeco.opencv.opencv_core.*;
  37. public class MainActivity extends Activity {
  38. private static final int ImgW = 1920;
  39. private static final int ImgH = 1080;
  40. private CaptureRequest.Builder previewRequestBuilder;
  41. private HandlerThread handlerThread = new HandlerThread("camera");
  42. private Handler mCameraHandler;
  43. private ImageReader mImageReader;
  44. public static CameraDevice mCameraDevice;
  45. private SurfaceHolder mHoderCamera;
  46. private SurfaceView surfaceView;
  47. @Override
  48. protected void onCreate(Bundle savedInstanceState) {
  49. super.onCreate(savedInstanceState);
  50. getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
  51. getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
  52. setContentView(R.layout.activity_main);
  53. surfaceView = findViewById(R.id.view);
  54. mHoderCamera = surfaceView.getHolder();
  55. initLooper();
  56. mHoderCamera.addCallback(new SurfaceHolder.Callback() {
  57. @Override
  58. public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder)
  59. {
  60. try {
  61. open_camera2();
  62. }
  63. catch(Exception e)
  64. {
  65. e.printStackTrace();
  66. }
  67. }
  68. @Override
  69. public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
  70. }
  71. @Override
  72. public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
  73. }
  74. });
  75. }
  76. // ImageReader的监听类,当预览中有新图像时会进入
  77. private final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
  78. @Override
  79. public void onImageAvailable(ImageReader reader) {
  80. Image image = reader.acquireNextImage();
  81. ByteBuffer buffer = image.getPlanes()[0].getBuffer();
  82. byte[] bytes = new byte[buffer.remaining()];
  83. buffer.get(bytes);
  84. // 此处获取的bitmap 就是预览视频中的每一张图
  85. Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
  86. image.close();
  87. //在子线程进行图像处理,防止预览界面卡顿
  88. mCameraHandler.post(new Runnable() {
  89. @Override
  90. public void run() {
  91. //先转成Mat
  92. Mat imgMat = new OpenCVFrameConverter.ToMat().convert(new AndroidFrameConverter().convert(bitmap));
  93. //Log.d("ImgSize:", Integer.toString(imgMat.cols()) + "," + Integer.toString(imgMat.rows()));
  94. }
  95. });
  96. }
  97. };
  98. private CameraDevice.StateCallback mStateCallBack_device = new CameraDevice.StateCallback() {
  99. @Override
  100. public void onOpened(@NonNull CameraDevice cameraDevice)
  101. {
  102. try
  103. {
  104. Log.d("opencv", "start open2");
  105. mCameraDevice = cameraDevice;
  106. //设置捕获请求为预览,这里还有拍照啊、录像啊等
  107. previewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
  108. mImageReader = ImageReader.newInstance(ImgW, ImgH, ImageFormat.JPEG, 2);
  109. mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mCameraHandler);
  110. previewRequestBuilder.addTarget(surfaceView.getHolder().getSurface());
  111. previewRequestBuilder.addTarget(mImageReader.getSurface());
  112. mCameraDevice.createCaptureSession(Arrays.asList(surfaceView.getHolder().getSurface(), mImageReader.getSurface()), mStateCallBack_session, mCameraHandler);
  113. }
  114. catch (CameraAccessException e) {
  115. e.printStackTrace();
  116. }
  117. }
  118. @Override
  119. public void onDisconnected(@NonNull CameraDevice cameraDevice) {
  120. cameraDevice.close();
  121. }
  122. @Override
  123. public void onError(@NonNull CameraDevice cameraDevice, int i) {
  124. if (cameraDevice != null) {
  125. cameraDevice.close();
  126. }
  127. }
  128. };
  129. private CameraCaptureSession.StateCallback mStateCallBack_session = new CameraCaptureSession.StateCallback(){
  130. @Override
  131. public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
  132. try {
  133. //自动对焦
  134. // previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
  135. previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);
  136. //拍照
  137. CaptureRequest request = previewRequestBuilder.build();
  138. //cameraCaptureSession.capture(request, null, mCameraHandler);
  139. //displaying the camera preview
  140. cameraCaptureSession.setRepeatingRequest(request, null, mCameraHandler);
  141. } catch (CameraAccessException e) {
  142. e.printStackTrace();
  143. }
  144. }
  145. @Override
  146. public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
  147. }
  148. };
  149. private void initLooper()
  150. {
  151. handlerThread = new HandlerThread("CAMERA2");
  152. handlerThread.start();
  153. mCameraHandler = new Handler(handlerThread.getLooper());
  154. }
  155. public void open_camera2() throws CameraAccessException
  156. {
  157. surfaceView.setVisibility(View.VISIBLE);
  158. if (ContextCompat.checkSelfPermission(getApplicationContext(),Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
  159. Log.d("Info:", "Camera Permission OK");
  160. } else {
  161. ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.CAMERA},1);
  162. }
  163. Log.d("opencv", "start open");
  164. //获得所有摄像头的管理者CameraManager
  165. CameraManager cameraManager = (CameraManager)this.getSystemService(this.CAMERA_SERVICE);
  166. //获得某个摄像头的特征,支持的参数
  167. CameraCharacteristics characteristics = null;
  168. characteristics = cameraManager.getCameraCharacteristics("0");
  169. //支持的STREAM CONFIGURATION
  170. StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
  171. //摄像头支持的预览siz数组
  172. Size[] mPreviewSize = map.getOutputSizes(SurfaceTexture.class);
  173. try {
  174. cameraManager.openCamera("0", mStateCallBack_device, mCameraHandler);
  175. } catch (CameraAccessException e) {
  176. e.printStackTrace();
  177. }
  178. }
  179. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/544689
推荐阅读
相关标签
  

闽ICP备14008679号