Step counter test1
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* @file PoseAnalyzer.kt
|
||||
* @brief CameraX ImageAnalysis.Analyzer that bridges frames into ML Kit's streaming pose detector.
|
||||
*/
|
||||
package com.example.jnicpp.bowling
|
||||
|
||||
import androidx.annotation.OptIn
|
||||
@@ -10,8 +14,8 @@ import com.google.mlkit.vision.pose.PoseDetector
|
||||
import com.google.mlkit.vision.pose.accurate.AccuratePoseDetectorOptions
|
||||
|
||||
/**
|
||||
* Bridges CameraX's [ImageAnalysis] frame stream into ML Kit's streaming
|
||||
* pose detector.
|
||||
* @brief Bridges CameraX's [ImageAnalysis] frame stream into ML Kit's
|
||||
* streaming pose detector.
|
||||
*
|
||||
* CameraX invokes [analyze] on whatever executor was passed to
|
||||
* `ImageAnalysis.setAnalyzer(executor, this)` -- as long as that's a
|
||||
@@ -26,6 +30,11 @@ import com.google.mlkit.vision.pose.accurate.AccuratePoseDetectorOptions
|
||||
* `STREAM_MODE` on the detector itself also makes ML Kit assume frames
|
||||
* arrive close together and reuse state between them, which is what makes
|
||||
* it track a moving body smoothly instead of re-detecting from scratch.
|
||||
*
|
||||
* @param isFrontCamera Callback returning whether the currently-bound
|
||||
* camera is front-facing, consulted fresh for each frame.
|
||||
* @param onResult Invoked on the main thread with each frame's detection result.
|
||||
* @param onError Invoked on the main thread if ML Kit fails to process a frame.
|
||||
*/
|
||||
class PoseAnalyzer(
|
||||
private val isFrontCamera: () -> Boolean,
|
||||
@@ -34,14 +43,23 @@ class PoseAnalyzer(
|
||||
) : ImageAnalysis.Analyzer {
|
||||
|
||||
/**
|
||||
* Everything [PoseOverlayView] needs to both draw a pose and correctly
|
||||
* map it from analysis-image pixels to view pixels, plus the joint
|
||||
* angles derived from that same pose (see [PoseAngleCalculator]) so
|
||||
* downstream consumers (overlay text, future frame-by-frame logging)
|
||||
* don't need to recompute them from [landmarks] themselves. [landmarks]
|
||||
* is already smoothed across frames (see [PoseLandmarkSmoother]) rather
|
||||
* than raw ML Kit output, so anything drawn straight from it doesn't
|
||||
* need to smooth it again.
|
||||
* @brief Everything [PoseOverlayView] needs to both draw a pose and
|
||||
* correctly map it from analysis-image pixels to view pixels,
|
||||
* plus the joint angles derived from that same pose.
|
||||
*
|
||||
* See [PoseAngleCalculator] for the angles, so downstream consumers
|
||||
* (overlay text, frame-by-frame logging) don't need to recompute them
|
||||
* from [landmarks] themselves. [landmarks] is already smoothed across
|
||||
* frames (see [PoseLandmarkSmoother]) rather than raw ML Kit output, so
|
||||
* anything drawn straight from it doesn't need to smooth it again.
|
||||
*
|
||||
* @param landmarks Smoothed landmarks for this frame, keyed by ML Kit's
|
||||
* `PoseLandmark` type constant.
|
||||
* @param imageWidth Raw analysis-image buffer width, pre-rotation.
|
||||
* @param imageHeight Raw analysis-image buffer height, pre-rotation.
|
||||
* @param rotationDegrees Rotation needed to bring the buffer upright.
|
||||
* @param isFrontCamera Whether this frame came from the front camera.
|
||||
* @param angles Joint angles derived from [landmarks] for this frame.
|
||||
*/
|
||||
data class PoseFrameResult(
|
||||
val landmarks: Map<Int, SmoothedLandmark>,
|
||||
@@ -71,6 +89,20 @@ class PoseAnalyzer(
|
||||
@Volatile
|
||||
private var isProcessing = false
|
||||
|
||||
/**
|
||||
* @brief CameraX entry point: called once per analyzed frame with the
|
||||
* latest camera buffer.
|
||||
*
|
||||
* Drops the frame immediately (after closing it) if a detection call is
|
||||
* already in flight or the buffer has no backing image. Otherwise hands
|
||||
* the frame to ML Kit asynchronously; [onResult]/[onError] fire later
|
||||
* from the detector's own callback once inference completes.
|
||||
*
|
||||
* @param imageProxy The camera frame to analyze. Always closed before
|
||||
* this function returns or before the async detector call
|
||||
* completes, whichever applies -- CameraX stalls the analysis
|
||||
* pipeline otherwise.
|
||||
*/
|
||||
@OptIn(ExperimentalGetImage::class)
|
||||
override fun analyze(imageProxy: ImageProxy) {
|
||||
val mediaImage = imageProxy.image
|
||||
@@ -116,6 +148,7 @@ class PoseAnalyzer(
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Releases the underlying ML Kit detector. Call when this analyzer's stream is done. */
|
||||
fun close() {
|
||||
detector.close()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user