実現したいこと
Kotlinでcamera2APIを使って、最終的にはリアルタイムトラッキングをしたいと考えているのですが、それ以前にプレビュー表示においてグレイスケールに変換して表示したりだとか、Canny法によるエッジ検出した映像を出力したいのです。
つまり、SurfaceViewあるいはTextureViewに非同期で加工したカメラのプレビュー映像を表示したいのですが、どのようにプレビュー映像からフレーム単位で画像を取得して、加工して、SurfaceViewあるいはTextureViewに表示すればいいのかわからないです。
Android開発に関して全くの初心者なので当たり前のことがわかってないことが多いですが、ご教示願います。
Cameraクラスのソースコード
現在のappはフルスクリーンでプレビュー表示をするのみのものとなっています。
ここではCameraのクラスを示します。
Kotlin
1package com.example.user.cvcamera 2 3import android.annotation.SuppressLint 4import android.app.Activity 5import android.content.Context 6import android.graphics.SurfaceTexture 7import android.hardware.camera2.* 8import android.hardware.camera2.params.StreamConfigurationMap 9import android.os.Handler 10import android.os.HandlerThread 11import android.util.Log 12import android.util.Size 13import android.view.Surface 14import android.view.TextureView 15import java.util.* 16 17class Camera(activity: Activity, textureView: TextureView) { 18 private var mCamera : CameraDevice? = null 19 var mTextureView : TextureView? = textureView 20 private var mCameraSize : Size? = null 21 private var mPreviewBuilder : CaptureRequest.Builder? = null 22 var mPreviewSession : CameraCaptureSession? = null 23 private val mActivity = activity 24 25 private val mCameraDeviceCallback = object : CameraDevice.StateCallback() { 26 override fun onOpened(camera: CameraDevice?) { 27 mCamera = camera 28 createCaptureSession() 29 } 30 31 override fun onDisconnected(camera: CameraDevice?) { 32 Log.d("debug", "Disconnected") 33 camera?.close() 34 mCamera = null 35 } 36 37 override fun onError(camera: CameraDevice?, error: Int) { 38 Log.d("debug", "Error") 39 camera?.close() 40 mCamera = null 41 } 42 } 43 44 private val mCameraCaptureSessionCallback = object : CameraCaptureSession.StateCallback() { 45 override fun onConfigured(session: CameraCaptureSession?) { 46 mPreviewSession = session 47 updatePreview() 48 } 49 50 override fun onConfigureFailed(session: CameraCaptureSession?) { 51 Log.d("Debug", "onConfiguredFailed ") 52 } 53 } 54 55 @SuppressLint("MissingPermission") 56 fun open() { 57 try { 58 val manager = mActivity.getSystemService(Context.CAMERA_SERVICE) as CameraManager 59 for(cameraId in manager.cameraIdList) { 60 Log.d("ID", cameraId.toString()) 61 val characteristics : CameraCharacteristics = manager.getCameraCharacteristics(cameraId) 62 if(characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_BACK) { 63 val map : StreamConfigurationMap = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP) 64 mCameraSize = map.getOutputSizes(SurfaceTexture::class.java)[0] 65 manager.openCamera(cameraId, mCameraDeviceCallback, null) 66 return 67 } 68 } 69 } catch (e : CameraAccessException) { 70 e.printStackTrace() 71 } 72 } 73 74 @SuppressLint("Recycle") 75 private fun createCaptureSession() { 76 if(!mTextureView!!.isAvailable) { 77 return 78 } 79 80 val texture = mTextureView!!.surfaceTexture 81 texture.setDefaultBufferSize(mCameraSize!!.width, mCameraSize!!.height) 82 val surface = Surface(texture) 83 try{ 84 mPreviewBuilder = mCamera?.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW) 85 }catch (e : CameraAccessException) { 86 e.printStackTrace() 87 } 88 89 mPreviewBuilder?.addTarget(surface) 90 try { 91 mCamera?.createCaptureSession(Collections.singletonList(surface), mCameraCaptureSessionCallback, null) 92 }catch (e : CameraAccessException) { 93 e.printStackTrace() 94 } 95 } 96 97 fun updatePreview() { 98 mPreviewBuilder?.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE) 99 mPreviewBuilder?.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH) 100 val thread = HandlerThread("Preview") 101 thread.start() 102 val backgroundHandler = Handler(thread.looper) 103 104 try { 105 mPreviewSession?.setRepeatingRequest(mPreviewBuilder?.build(), null, backgroundHandler) 106 }catch (e : CameraAccessException) { 107 e.printStackTrace() 108 } 109 } 110}
試したこと
OpenCVモジュールに用意されているCameraBridgeViewBaseを使い、onCameraFrameメソッドでinputFrameを加工してJavaCameraViewへの表示を試みましたが、思っていた以上に解像度が低かっためこちらの方法にシフトしました。
補足情報(FW/ツールのバージョンなど)
Android Studio 3.0
OpenCV 3.4.0
Kotlin 1.2.21
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。