实现基本功能

添加opencv库
This commit is contained in:
jackfiled 2023-01-09 16:35:11 +08:00
parent bbd0a2fdfe
commit b2078e2938
8 changed files with 216 additions and 10 deletions

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<runningDeviceTargetSelectedWithDropDown>
<Target>
<type value="RUNNING_DEVICE_TARGET" />
<deviceKey>
<Key>
<type value="SERIAL_NUMBER" />
<value value="adb-3040223527000PT-yH8BGJ._adb-tls-connect._tcp" />
</Key>
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2023-01-09T08:15:42.195541Z" />
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -5,7 +5,8 @@
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" /> <!-- For mediapipe -->
<!-- For mediapipe -->
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
@ -22,10 +23,11 @@
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="false">
<meta-data
android:name="android.app.lib_name"
android:value="" />
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

View File

@ -1,11 +1,179 @@
package top.rrricardo.motioncapture
import android.graphics.SurfaceTexture
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.util.Size
import android.view.SurfaceHolder
import android.view.SurfaceView
import android.view.View
import android.view.ViewGroup
import com.google.mediapipe.components.CameraHelper
import com.google.mediapipe.components.CameraXPreviewHelper
import com.google.mediapipe.components.ExternalTextureConverter
import com.google.mediapipe.components.FrameProcessor
import com.google.mediapipe.components.PermissionHelper
import com.google.mediapipe.formats.proto.LandmarkProto.NormalizedLandmarkList
import com.google.mediapipe.framework.AndroidAssetUtil
import com.google.mediapipe.framework.PacketGetter
import com.google.mediapipe.glutil.EglManager
import com.google.protobuf.InvalidProtocolBufferException
class MainActivity : AppCompatActivity() {
// 一些在设置MediaPipe时会用到的字符串常量
private val tag = "MainActivity"
private val binaryGraphName = "pose_tracking_gpu.binarypb"
private val inputVideoStreamName = "input_video"
private val outputVideoStreamName = "output_video"
private val outputLandmarksStreamName = "pose_landmarks"
lateinit var previewFrameTexture: SurfaceTexture
private lateinit var previewDisplayView: SurfaceView
private lateinit var eglManager: EglManager
lateinit var processor: FrameProcessor
lateinit var converter: ExternalTextureConverter
lateinit var cameraHelper: CameraXPreviewHelper
init {
// 加载项目中用到的jni库
System.loadLibrary("mediapipe_jni")
System.loadLibrary("opencv_java3")
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 初始化展示界面
previewDisplayView = SurfaceView(this)
setupPreviewDisplayView()
// 初始化资产管理类
// 方便获取资源
AndroidAssetUtil.initializeNativeAssetManager(this)
eglManager = EglManager(null)
processor = FrameProcessor(
this,
eglManager.nativeContext,
binaryGraphName,
inputVideoStreamName,
outputVideoStreamName
)
processor.videoSurfaceOutput.setFlipY(true)
// 展示
processor.addPacketCallback(
outputLandmarksStreamName
) {
try {
val landmarkRaw = PacketGetter.getProtoBytes(it)
val poseLandmarks = NormalizedLandmarkList.parseFrom(landmarkRaw)
// 从这里可以获得每个特征点的座标
} catch (exception: InvalidProtocolBufferException) {
Log.e(tag, "failed to get protocol.", exception)
}
}
// 检查相机权限
PermissionHelper.checkAndRequestCameraPermissions(this)
}
override fun onResume() {
super.onResume()
converter = ExternalTextureConverter(
eglManager.context,
2
)
converter.setFlipY(true)
converter.setConsumer(processor)
if (PermissionHelper.cameraPermissionsGranted(this)) {
startCamera()
}
}
override fun onPause() {
super.onPause()
converter.close()
previewDisplayView.visibility = View.GONE
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
PermissionHelper.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
private fun startCamera() {
cameraHelper = CameraXPreviewHelper()
cameraHelper.setOnCameraStartedListener {
if (it != null) {
previewFrameTexture = it
}
// 将预览画面设置为可见
// 这将触发添加到holder中的callback
previewDisplayView.visibility = View.VISIBLE
}
val cameraFacing = CameraHelper.CameraFacing.BACK
cameraHelper.startCamera(
this,
cameraFacing,
null,
// 不提供大小
// 让helper自己决定
null
)
}
/**
* 初始化相机预览界面
*/
private fun setupPreviewDisplayView() {
previewDisplayView.visibility = View.GONE
val viewGroup = findViewById<ViewGroup>(R.id.preview_display)
viewGroup.addView(previewDisplayView)
previewDisplayView.holder.addCallback(
object: SurfaceHolder.Callback {
override fun surfaceCreated(holder: SurfaceHolder) {
processor.videoSurfaceOutput.setSurface(holder.surface)
}
override fun surfaceChanged(
holder: SurfaceHolder,
format: Int,
width: Int,
height: Int
) {
// 重新计算显示的尺寸
val viewSize = Size(width, height)
val displaySize = cameraHelper.computeDisplaySizeFromViewSize(viewSize)
val isCameraRotated = cameraHelper.isCameraRotated
// 将摄像机的预览画面作为converter的输入
// 同时按照计算出来的尺寸设置converter
converter.setSurfaceTextureAndAttachToGLContext(
previewFrameTexture,
if (isCameraRotated) displaySize.height else displaySize.width,
if (isCameraRotated) displaySize.width else displaySize.height
)
}
override fun surfaceDestroyed(holder: SurfaceHolder) {
processor.videoSurfaceOutput.setSurface(null)
}
}
)
}
}

View File

@ -1,5 +0,0 @@
package top.rrricardo.motioncapture
class PoseLandMark {
}

Binary file not shown.

View File

@ -6,4 +6,21 @@
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/preview_display"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
tools:ignore="MissingConstraints"
>
<TextView
android:id="@+id/no_camera_access_hint"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/no_camera_access_hint">
</TextView>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,3 +1,4 @@
<resources>
<string name="app_name">MotionCapture</string>
<string name="no_camera_access_hint">Please Make Sure the Camera Permission is Given!</string>
</resources>