一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

詳解Object Detection Demo的移植

谷歌開發(fā)者 ? 來源:Android高效開發(fā) ? 2025-02-05 13:42 ? 次閱讀

以下文章來源于Android高效開發(fā),作者2BAB

本文作者 /Android 谷歌開發(fā)者專家 El Zhang (2BAB)

繼上一篇移植了 Mediapipe 的 LLM Inference 后,這篇文章我們將繼續(xù)探索 Object Detection Demo 的移植。通過本文你將了解到:

移植 Mediapipe 的 Object Detection Android 官方 Demo 到 KMP,支持在 iOS 上運行。項目地址:https://github.com/2BAB/MediaPiper/tree/object-detection

Compose Multiplatform 與 iOS 原生控件的集成與交互 (Camera Preview),包括權(quán)限申請。

在 KMP 使用依賴注入 iOS 控件的小技巧 (基于 Koin)。

該 Demo 里兩種 Object Detection 算法的簡單背景知識。

b4c30d28-da36-11ef-9310-92fbcf53809c.png ? ? ?

Object Detection Android Sample

首先,我們先打開 Object Detection 的原版工程,發(fā)現(xiàn)其 Android 部分既有 android.view.View 版本的實現(xiàn),也有 Jetpack Compose 的版本。因此我們延續(xù)上一篇的方式,基于 Jetpack Compose 的版本直接移植到 KMP 上。

接著,仔細(xì)體驗該 App 會發(fā)現(xiàn)其復(fù)雜度更高。LLM Inference 中的 SDK 僅僅是提供文本的推理接口,可直接在 Kotlin 層封裝對應(yīng)平臺的 SDK 方便抽象 (盡管因為一些 cinterop 支持原因我們最后用了備用方案),UI 上則完全復(fù)用。但 Object Detection 是基于圖像的實時處理,演示里涉及攝像頭實時檢測、本地視頻的檢測、本地圖片的檢測三種。攝像頭預(yù)覽的需求一般都強依賴于平臺實現(xiàn),播放器在渲染層面也鮮有自繪 (即使用平臺 Native 方案)。

b4e07cd2-da36-11ef-9310-92fbcf53809c.png

小結(jié),在開始設(shè)計時我們就得考慮把 Compose Multiplatform (CMP) 難以實現(xiàn)的部分留出 (例如上圖中的 CameraView),抽象成獨立的 expect Composable 函數(shù)留給兩端各自實現(xiàn)。而為了方便學(xué)習(xí)需減少 Demo 的規(guī)模,我們也決定只實現(xiàn) CameraView 的部分,把 Gallery (Video+Image) 的部分留給大家去嘗試。實際上,只要掌握了 Camera Preview 的嵌入方法,其他兩部分也可以參照實現(xiàn),包括 Compose 和 UiKit 的交互、iOS 權(quán)限申請等。

b4eda164-da36-11ef-9310-92fbcf53809c.png

結(jié)合 iOS 版的 Demo 交叉比對,我們把 CameraView 有關(guān)的 UI 層整理成了四個部分,如上圖所示。其中:

Camera Preview 層一定是交由兩端各自實現(xiàn)。

ResultOverlay 即各種結(jié)果的方框繪制,可以考慮在 Common 層實現(xiàn),但涉及到其與 Camera Preview 的圖層匹配 (因 Camera Preview 的大小根據(jù)鏡頭的不同會有不同的比例選項)、坐標(biāo)轉(zhuǎn)換,較為復(fù)雜,本次 Demo 繼續(xù)交由兩端各自實現(xiàn)。

Scaffold 和 Inference Time Label 在 Common 層實現(xiàn)。

移植流程

移植主體的 UI 和數(shù)據(jù)結(jié)構(gòu)

我們在上一節(jié)的基礎(chǔ)上繼續(xù)在 Mediapiper 工程中增加一個新文件夾 objectdetection。有了上一節(jié)的經(jīng)驗,我們發(fā)現(xiàn)其實很多 UI 的內(nèi)容都不復(fù)雜——除了這節(jié)的重點,相機預(yù)覽界面。因此,我們可以先行把除了camera和 gallery的文件都移動過來:

b4ff8f82-da36-11ef-9310-92fbcf53809c.png

此處需要的修改分為兩塊:

數(shù)據(jù)和邏輯部分:

我們采集原來的 SDK 中的 ObjectDetectionResult 屬性聲明,創(chuàng)建了一個 Common 版本的 data class,也包括其用到的各種附屬類型。如此一來,兩邊的 SDK 返回結(jié)果都可以通過簡單轉(zhuǎn)換直接替換成 Common 版本的,不管是要顯示推理時間、統(tǒng)一采樣埋點,甚至為以后把ResultOverlay 搬來 Common 做好了準(zhǔn)備。

一些工具類和默認(rèn)值枚舉也被一并移至 Common 層,并且基本不需要修改,只要把推理結(jié)果的類置換成上述 Common 版本的。

UI 部分:

一些統(tǒng)一的修改和上一節(jié)完全相同,R引用改 Res,主題換成上一節(jié)統(tǒng)一的,一些簡單的 Import 包修改。

而特別的部分在于該 Demo 沒有使用 CMP 版本的 Navigation,所以在 Home 和 Option 頁面切換只是在頂層做了一個簡單的 if...else...。

至此已經(jīng)可以運行一個不含相機功能的應(yīng)用了,下圖演示了這些 CMP 代碼在 iOS 上運行時的兩個頁面。

b519b132-da36-11ef-9310-92fbcf53809c.jpg

集成 CameraView 功能

如上文分析我們需要拆除 CameraView 的部分用 Native 實現(xiàn),因此在 Common 的 CameraView里我們使用了兩個 expect的 Composable 函數(shù) CameraPermissionControl 和CameraPreview:

@Composable
fun CameraView(
   threshold: Float,
   maxResults: Int,
   delegate: Int,
   mlModel: Int,
   setInferenceTime: (newInferenceTime: Int) -> Unit,
) {
   CameraPermissionControl {
       CameraPreview(
           threshold,
           maxResults,
           delegate,
           mlModel,
           setInferenceTime,
           onDetectionResultUpdate = { detectionResults ->
              ...
           })
   }
}


@Composable
expect fun CameraPermissionControl(PermissionGrantedContent:  @Composable @UiComposable () -> Unit)
```kotlin
@Composable
expect fun CameraPreview(
   threshold: Float,
   maxResults: Int,
   delegate: Int,
   mlModel: Int,
   setInferenceTime: (newInferenceTime: Int) -> Unit,
   onDetectionResultUpdate: (result: ObjectDetectionResult) -> Unit
)

Android 側(cè)的 CameraView 實現(xiàn)

Android 端的實現(xiàn)十分簡單,直接將原有的 Jetpack Compose 代碼拷貝過來:

// Android implementation
@OptIn(ExperimentalPermissionsApi::class)
@Composable
actual fun CameraPermissionControl(
  PermissionGrantedContent:  @Composable @UiComposable () -> Unit) {   
   val storagePermissionState: PermissionState =
       rememberPermissionState(Manifest.permission.CAMERA)
   LaunchedEffect(key1 = Unit) {
       if (!storagePermissionState.hasPermission) {
           storagePermissionState.launchPermissionRequest()
       }
   }


   if (!storagePermissionState.hasPermission) {
       Text(text = "No Storage Permission!")
   } else {
       PermissionGrantedContent()
   }
}


@Composable
actual fun CameraPreview(...) {
   ... // Some properties' definition


   DisposableEffect(Unit) {
       onDispose {
           active = false;
           cameraProviderFuture.get().unbindAll()
       }
   }


   // Next we describe the UI of this camera view.
   BoxWithConstraints(..) {       
       val cameraPreviewSize = getFittedBoxSize(
           containerSize = Size(
               width = this.maxWidth.value,
               height = this.maxHeight.value,
           ),
           boxSize = Size(
               width = frameWidth.toFloat(),
               height = frameHeight.toFloat()
           )
       )


       Box(
           Modifier
               .width(cameraPreviewSize.width.dp)
               .height(cameraPreviewSize.height.dp),
       ) {
           // We're using CameraX to use the phone's camera, and since it doesn't have a prebuilt
           // composable in Jetpack Compose, we use AndroidView to implement it
           AndroidView(
               factory = { ctx ->                   
                   val previewView = PreviewView(ctx)
                   val executor = ContextCompat.getMainExecutor(ctx)
                   cameraProviderFuture.addListener({
                       val cameraProvider = cameraProviderFuture.get()
                       val preview = Preview.Builder().build().also {
                           it.setSurfaceProvider(previewView.surfaceProvider)
                       }


                       val cameraSelector = CameraSelector.Builder()
                           .requireLensFacing(CameraSelector.LENS_FACING_BACK)
                           .build()


                       // We instantiate an image analyser to apply some transformations on the
                       // input frame before feeding it to the object detector
                       val imageAnalyzer =
                           ImageAnalysis.Builder()
                               .setTargetAspectRatio(AspectRatio.RATIO_4_3)
                               .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
                               .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
                               .build()


                       // Now we're ready to apply object detection. For a better performance, we
                       // execute the object detection process in a new thread.
                       val backgroundExecutor = Executors.newSingleThreadExecutor()


                       backgroundExecutor.execute {


                           // To apply object detection, we use our ObjectDetectorHelper class,
                           // which abstracts away the specifics of using MediaPipe  for object
                           // detection from the UI elements of the app
                           val objectDetectorHelper =
                               AndroidObjectDetector(
                                   context = ctx,
                                   threshold = threshold,
                                   currentDelegate = delegate,
                                   currentModel = mlModel,
                                   maxResults = maxResults,                               
                                   objectDetectorListener = ObjectDetectorListener(
                                       onErrorCallback = { _, _ -> },
                                       onResultsCallback = {
                                           // On receiving results, we now have the exact camera
                                           // frame dimensions, so we set them here
                                           frameHeight = it.inputImageHeight
                                           frameWidth = it.inputImageWidth


                                           // Then we check if the camera view is still active,
                                           // if so, we set the state of the results and
                                           // inference time.
                                           if (active) {
                                               results = it.results.first()
                                               setInferenceTime(it.inferenceTime.toInt())
                                           }
                                       }
                                   ),
                                   runningMode = RunningMode.LIVE_STREAM
                               )


                           // Now that we have our ObjectDetectorHelper instance, we set is as an
                           // analyzer and start detecting objects from the camera live stream
                           imageAnalyzer.setAnalyzer(
                               backgroundExecutor,
                               objectDetectorHelper::detectLivestreamFrame
                           )
                       }


                       // We close any currently open camera just in case, then open up
                       // our own to be display the live camera feed
                       cameraProvider.unbindAll()
                       cameraProvider.bindToLifecycle(
                           lifecycleOwner,
                           cameraSelector,
                           imageAnalyzer,
                           preview
                       )
                   }, executor)
                   // We return our preview view from the AndroidView factory to display it
                   previewView
               },
               modifier = Modifier.fillMaxSize(),
           )


           // Finally, we check for current results, if there's any, we display the results overlay
           results?.let {
               ResultsOverlay(
                   results = it,
                   frameWidth = frameWidth,
                   frameHeight = frameHeight
               )
           }
       }
   }
}
iOS 側(cè)的 CameraView 實現(xiàn)

iOS 則稍微需要一些精力。對于相機權(quán)限控制,我們直接在這個 Composable 函數(shù)中調(diào)用 iOS 的 platform.AVFoundation相關(guān) API,異步發(fā)起請求然后根據(jù)結(jié)果顯示加載中、失敗、或成功時直接顯示相機預(yù)覽??梢钥吹轿覀冏龅?iOS 實現(xiàn)已十分完善,考慮到了三個不同場景 :D

...
import platform.AVFoundation.AVAuthorizationStatusAuthorized
import platform.AVFoundation.AVAuthorizationStatusDenied
import platform.AVFoundation.AVAuthorizationStatusNotDetermined
import platform.AVFoundation.AVAuthorizationStatusRestricted
import platform.AVFoundation.AVCaptureDevice
import platform.AVFoundation.AVMediaTypeVideo
import platform.AVFoundation.authorizationStatusForMediaType
import platform.AVFoundation.requestAccessForMediaType
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine


@Composable
actual fun CameraPermissionControl(PermissionGrantedContent:  @Composable @UiComposable () -> Unit) {
   var hasCameraPermission by remember { mutableStateOf(null) }


   LaunchedEffect(Unit) {
       hasCameraPermission = requestCameraAccess()
   }


   when (hasCameraPermission) {
       true -> {
           PermissionGrantedContent()
       }
       false -> {
           Text("Camera permission denied. Please grant access from settings.")
       }
       null -> {
           Text("Requesting camera permission...")
       }
   }
}




private suspend fun requestCameraAccess(): Boolean = suspendCoroutine { continuation ->
   val authorizationStatus = AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo)


   when (authorizationStatus) {
       AVAuthorizationStatusNotDetermined -> {
           AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo) { granted ->
               continuation.resume(granted)
           }
       }
       AVAuthorizationStatusRestricted, AVAuthorizationStatusDenied -> {
           continuation.resume(false)
       }
       AVAuthorizationStatusAuthorized -> {
           continuation.resume(true)
       }
       else -> {
           continuation.resume(false)
       }
   }
}

然后來到核心的相機預(yù)覽功能。從 CMP 的文檔中我們知道,使用 UIKitView 即可在 Composable 函數(shù)中嵌入一個 iOS 的 View。

// Example 1
UIKitView(
   factory = { MKMapView() },
   modifier = Modifier.size(300.dp),
)


// Example 2
@OptIn(ExperimentalForeignApi::class)
@Composable
fun UseUITextField(modifier: Modifier = Modifier) {
   var message by remember { mutableStateOf("Hello, World!") }
   UIKitView(
       factory = {
           val textField = object : UITextField(CGRectMake(0.0, 0.0, 0.0, 0.0)) {
               @ObjCAction
               fun editingChanged() {
                   message = text ?: ""
               }
           }
           textField.addTarget(
               target = textField,
               action = NSSelectorFromString(textField::editingChanged.name),
               forControlEvents = UIControlEventEditingChanged
           )
           textField
       },
       modifier = modifier.fillMaxWidth().height(30.dp),
       update = { textField ->
           textField.text = message
       }
   )
}

文檔 https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-uikit-integration.html

仔細(xì)觀察這兩個示例會發(fā)現(xiàn)其使用的都是默認(rèn) UIKit 控件,而非工程自定義的;對應(yīng)的引用則是 JetBrains 提前轉(zhuǎn)換了相關(guān)的代碼接口到 Kotlin,例如 platform.UIKit.UITextField 默認(rèn)可以導(dǎo)入到 KMP 工程的 iOS target。但對于我們的工程情況不太相同,我們想要復(fù)用的是一個帶有識別功能的自定義 CameraPreview 視圖。

b52c8b2c-da36-11ef-9310-92fbcf53809c.png

換個角度看,KMP 產(chǎn)出的 app.framework 是一個基礎(chǔ)共享層,iOS 原生代碼依賴于這個庫。從依賴關(guān)系上,我們無法直接調(diào)用 iOS App 源碼中的CamerePreview。解決方法也不難,一般分兩種:

把相關(guān)代碼打包成一個獨立模塊,產(chǎn)出 cameraview.freamework,讓app 依賴它。

iOS App 在初始化 app.framework 時,傳入一個 lambda 到app 用來初始化并返回一個UIView。

此處我們采用第二種方案,定義 IOSCameraPreviewCreator 作為兩側(cè)交互的協(xié)議。

// 定義
typealias IOSCameraPreviewCreator = (
   threshold: Float,
   maxResults: Int,
   delegate: Int,
   mlModel: Int,
   setInferenceTime: (newInferenceTime: Int) -> Unit,
   callback: IOSCameraPreviewCallback
) -> UIView


typealias IOSCameraPreviewCallback = (result: ObjectDetectionResult) -> Unit


// 在啟動時從 iOS 端傳入相關(guān)實現(xiàn),并加入到 Koin 的 Definition
fun onStartup(iosCameraPreviewCreator: IOSCameraPreviewCreator) {
   Startup.run { koinApp ->
       koinApp.apply {
           modules(module {
               single { LLMOperatorFactory() }
               single { iosCameraPreviewCreator }
           })
       }
   }
}


// 回到 CameraPreview 的實現(xiàn),我們只要執(zhí)行注入,
// 并 invoke 這個函數(shù)獲得 UIView 實例。
...
import androidx.compose.ui.viewinterop.UIKitView
import platform.UIKit.UIView


@Composable
actual fun CameraPreview(
   threshold: Float,
   maxResults: Int,
   delegate: Int,
   mlModel: Int,
   setInferenceTime: (newInferenceTime: Int) -> Unit,
   onDetectionResultUpdate: (result: ObjectDetectionResult) -> Unit,
) {
   val iOSCameraPreviewCreator = koinInject()
   // 和 Android 端集成原生 Camera View 的方式有幾分相似
   UIKitView(
       factory = {
           val iosCameraPreview: UIView = iOSCameraPreviewCreator(
               threshold,
               maxResults,
               delegate,
               mlModel,
               setInferenceTime,
               onDetectionResultUpdate)
           iosCameraPreview
       },
       modifier = Modifier.fillMaxSize(),
       update = { _ -> }
   )
}

上述代碼使用 Koin 管理依賴簡化了流程。至此 CMP 的部分已經(jīng)完成,我們順延啟動參數(shù)的注入去探究 iOS 的部分。

MainKt.onStartup(iosCameraPreviewCreator: { threshold, maxResults, delegate, mlModel, onInferenceTimeUpdate, resultCallback in
   return IOSCameraView.init(
       frame: CGRectMake(0, 0, 0, 0),
       modelName: Int(truncating: mlModel) == 0 ? "EfficientDet-Lite0" : "EfficientDet-Lite2",
       maxResults: Int(truncating: maxResults),
       scoreThreshold: Float(truncating: threshold),
       onInferenceTimeUpdate: onInferenceTimeUpdate,
       resultCallback: resultCallback
   )
})
該IOSCameraView 實際上即原 iOS Demo 中的 CameraViewController,我們僅修改一些初始化和生命周期的內(nèi)容,并簡化掉了參數(shù)變化監(jiān)聽的部分以突出核心遷移內(nèi)容:

生命周期處理:ViewController 使用 viewDidLoad 等生命周期方法,UIView 則用 didMoveToWindow 處理視圖添加或移除時的邏輯。ViewController 通過生命周期管理初始化,而 UIView 提供自定義初始化方法來傳遞模型和檢測參數(shù)。

子視圖設(shè)置:ViewController 使用@IBOutlet 和 Interface Builder,而UIView 通過 setupView 方法直接創(chuàng)建并添加子視圖,手動使用 AutoLayout 設(shè)置約束以及手動設(shè)置點擊事件。

回調(diào)和委托:ViewController 使用委托,而 UIView 增加了回調(diào)閉包 onInferenceTimeUpdate 和resultCallback,初始化時傳入這些參數(shù)并設(shè)置好類型轉(zhuǎn)換,方便后面回調(diào)到 KMP 層。

b53f5356-da36-11ef-9310-92fbcf53809c.jpg

我們同時保留了OverlayView CameraFeedService ObjectDetectorService 和部分DefaultConstants,此處不對他們的代碼進行修改。其中ObjectDetectorService 即是對 Object Detection SDK 的封裝,如果觀察它的 API 調(diào)用,會發(fā)現(xiàn)其和 iOS 的 Camera API 緊密耦合 (CMSampleBuffer 等),說明了其難以在 Common 抽象,呼應(yīng)了文初對 Camera 相關(guān)服務(wù)的分析。

b559f47c-da36-11ef-9310-92fbcf53809c.png

至此,我們就可以把 iOS 端的相機預(yù)覽加 Object Detection 也跑起來。

簡單測試

上方的動圖展示了 EfficientDet-Lite0 加 CPU 模式在 iPhone 13mini 執(zhí)行的效果。官方使用 Pixel 6 CPU/GPU 的測試中,轉(zhuǎn)去 GPU 執(zhí)行還能再小幅提高一些性能。不難看出,其實時性已足夠滿足生產(chǎn)環(huán)境的需求,同時在準(zhǔn)確率方面表現(xiàn)尚可。

隨 Demo 工程搭載的可選模型有兩個:

EfficientDet-Lite0 模型使用 320x320 輸入,平衡了延遲和準(zhǔn)確性,適合輕量級應(yīng)用。Demo 中默認(rèn)搭載了其 float 32 版本的模型。

EfficientDet-Lite2 模型使用 448x448 輸入,準(zhǔn)確性更高,但速度較慢,適合對準(zhǔn)確性要求更高的場景。Demo 中默認(rèn)搭載了其 float 32 版本的模型。

這兩種模型均使用包含 150 萬個實例和 80 種物體標(biāo)簽的訓(xùn)練集進行訓(xùn)練。

b5a39b4a-da36-11ef-9310-92fbcf53809c.png

總結(jié)

一些傳統(tǒng)的 ML 模型在移動設(shè)備上的應(yīng)用已經(jīng)相對成熟,可以應(yīng)對不少單一和專途的場景。而本文的兩個模型亦只有 13~25MB,相比 LLM 的模型動輒 1GB 以上,這類模型完全沒有落地的負(fù)擔(dān)。

使用 Compose Multiplatform 內(nèi)嵌 UiKit 的 View 可以解決很多高性能、需要原生 API 和硬件的情況。

為了盡可能還原 Demo 的效果同時減少遷移成本,ResultOverlay 在本次遷移中雖然已經(jīng)放到 Common 層,且 iOS 側(cè)也已設(shè)置結(jié)果回調(diào)到 KMP,但 iOS 上依舊使用了原生 View 實現(xiàn)。現(xiàn)實場景中,我們可進一步擴展思考:

倘若業(yè)務(wù)場景簡單,例如也是方框識別且全屏展示 camera preview,則可以在 Compose 層簡單復(fù)用ResultOverlay。

倘若業(yè)務(wù)場景復(fù)雜,例如視頻聊天時的人臉識別加貼圖選擇和渲染,因業(yè)務(wù)部分的高復(fù)雜度使得復(fù)用同一個 StickerOverlay 的價值非常高,這個情況下 Camera Preview 無論大小如何,適配成本反倒都可以接受。另外對于 StickerOverlay 的位置計算,理論上也存在優(yōu)化的空間,例如采樣計算然后中間用插值動畫移動。

一些依賴管理的復(fù)雜場景包括 UI 視圖的注入,借助類似 Koin 依賴注入框架可大幅簡化。

這次遷移的部分還有相冊選擇、照片與視頻解析等等未實現(xiàn),感興趣的朋友可以自行添加測試,像讀取權(quán)限申請、播放器 View 的嵌入和本文的遷移過程會非常類似。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • Android
    +關(guān)注

    關(guān)注

    12

    文章

    3959

    瀏覽量

    129224
  • 攝像頭
    +關(guān)注

    關(guān)注

    60

    文章

    4927

    瀏覽量

    97420
  • 移植
    +關(guān)注

    關(guān)注

    1

    文章

    392

    瀏覽量

    28510
  • LLM
    LLM
    +關(guān)注

    關(guān)注

    1

    文章

    316

    瀏覽量

    642

原文標(biāo)題:【GDE 分享】移植 Mediapipe Demo 到 Kotlin Multiplatform (2)

文章出處:【微信號:Google_Developers,微信公眾號:谷歌開發(fā)者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    使用person-detection-action-recognition-0006模型運行智能課堂C++演示遇到報錯怎么解決?

    使用以下命令運行帶有 person-detection-action-recognition-0006 模型的智能課堂 C++ 演示: smart_classroom_demo
    發(fā)表于 03-05 07:13

    使用Yolo-v3-TF運行OpenVINO?對象檢測Python演示時的結(jié)果不準(zhǔn)確的原因?

    的模型與對象檢測 Python* Demo 配合使用時無法檢測對象: python3 open_model_zoo/demos/object_detection_demo/python
    發(fā)表于 03-06 06:31

    【米爾百度大腦EdgeBoard邊緣AI計算盒試用連載】III. 板載深度學(xué)習(xí)DEMO-detection測試-上(ZMJ)

    參考README.md進行操作即可。進入build文件夾,攝像頭運行YOLOV3-DEMO指令:./video_detection ../configs/yolov3/screw.json
    發(fā)表于 04-02 19:56

    【米爾百度大腦EdgeBoard邊緣AI計算盒試用連載】III. 板載深度學(xué)習(xí)DEMO-detection測試-下(ZMJ)

    本帖最后由 卿小小_9e6 于 2021-4-11 16:16 編輯 【米爾百度大腦EdgeBoard邊緣AI計算盒試用連載】III. 板載深度學(xué)習(xí)DEMO-detection測試-下(ZMJ
    發(fā)表于 04-11 16:17

    STM32程序的移植詳解步驟

    一,概括程序的移植包括以下幾步1.觀察待移植程序調(diào)用了哪些文件,將這些文件放入移植的工程當(dāng)中2.在keil當(dāng)中添加這些文件,并且添加.h文件的路徑3.處理頭文件及軟件版本匹配的問題二,詳解
    發(fā)表于 08-23 07:27

    如何執(zhí)行object_detection_demo.py以使用攝像頭作為對象檢測Python演示的輸入?

    執(zhí)行命令: python3 object_detection_demo.py -m person-vehicle-bike-detection-2001.xml -at ssd -d MYRIAD
    發(fā)表于 08-15 06:28

    Java Object Serialization Spec

    Java Object Serialization SpecificationObject serialization in the Java™system is the process
    發(fā)表于 10-14 17:39 ?7次下載

    Object-Oriented Programming in

    This chapter applies a different programming paradigm to G: Object-Oriented Programming(OOP). New
    發(fā)表于 03-02 14:18 ?28次下載

    RTAI分析及在s3c4510上的移植詳解

    RTAI分析及在s3c4510上的移植詳解
    發(fā)表于 03-28 09:52 ?24次下載

    什么是CORBA (Common Object Reques

    什么是CORBA (Common Object Request Broker Architecture)  英文縮寫: CORBA (Common Object Request Broker Architecture) 中文譯名: 通用對象請求
    發(fā)表于 02-22 11:48 ?1073次閱讀

    嵌入式Linux內(nèi)核移植詳解(頂嵌)

    嵌入式內(nèi)核移植步驟詳解 含配置含義及內(nèi)容等方面
    發(fā)表于 11-20 16:00 ?19次下載

    《Linux設(shè)備驅(qū)動開發(fā)詳解》第23章、Linux設(shè)備驅(qū)動的移植

    《Linux設(shè)備驅(qū)動開發(fā)詳解》第23章、Linux設(shè)備驅(qū)動的移植
    發(fā)表于 10-27 10:58 ?9次下載
    《Linux設(shè)備驅(qū)動開發(fā)<b class='flag-5'>詳解</b>》第23章、Linux設(shè)備驅(qū)動的<b class='flag-5'>移植</b>

    Uboot移植步驟詳解

    Uboot移植步驟詳解
    發(fā)表于 10-30 08:46 ?21次下載
    Uboot<b class='flag-5'>移植</b>步驟<b class='flag-5'>詳解</b>

    uCOS_ARM移植要點詳解

    uCOS_ARM移植要點詳解
    發(fā)表于 10-31 11:25 ?11次下載
    uCOS_ARM<b class='flag-5'>移植</b>要點<b class='flag-5'>詳解</b>

    AM64x/AM243x多協(xié)議Demo搭建與詳解

    AM64x/AM243x多協(xié)議Demo搭建與詳解
    發(fā)表于 10-28 11:59 ?2次下載
    AM64x/AM243x多協(xié)議<b class='flag-5'>Demo</b>搭建與<b class='flag-5'>詳解</b>