ペン先とキャップの検出 4: C++ はペン先とキャップの検出アルゴリズムを実装します (ソース コードが含まれていますが、リアルタイム検出)

ペン先とキャップの検出 4: C++ はペン先とキャップの検出アルゴリズムを実装します (ソース コードが含まれていますが、リアルタイム検出)

目次

ペン先とキャップの検出 4: C++ はペン先とキャップの検出アルゴリズムを実装します (ソース コードが含まれていますが、リアルタイム検出)

1.プロジェクト紹介

 2. ペン先とキャップのキーポイント検出方法

(1)トップダウン(トップダウン)方式

(2)ボトムアップ(ボトムアップ)方式:

3. ペン先とキャップのキーポイント検出モデル

(1) ペン先・キャップのキーポイント検出モデルの学習

(2) PytorchモデルをONNXモデルに変換

(3) ONNX モデルから TNN モデルへの変換

4. ペン先とキャップのキーポイント検出 C/C++ の導入

(1) プロジェクトの構成

(2) 開発環境の構築(OpenCV+OpenCL+base-utils+TNN)

(3) TNNモデルの展開

(4) CMakeの設定

(5) メインソースコード

(6) ソースコードのコンパイルと操作

(7) デモテストの効果 

5. プロジェクトのソースコードのダウンロード

6. 特別編:ペン先指先検出


1.プロジェクト紹介

現在、AI スマート教育の分野では、指先読み取り または< という比較的人気のある教育製品があります。 a i =3>ペン先読み取り機能。そのコアアルゴリズムは、深層学習法を通じてペン先または指先の位置を取得し、OCRを通じてテキストを認識し、最終的にテキストを音声に変換することです。 ; その中で、OCR および TTS アルゴリズムは非常に成熟しており、参考として実装できる指先またはペン先の検出方法に関するオープンソース プロジェクトもいくつかあります。このプロジェクトではペン先とキャップのキーポイント検出アルゴリズムを実装します。このアルゴリズムでは、YOLOv5 モデルを使用して手の検出 (手持ちペンのターゲット検出) を実装します。 、HRNet、LiteHRNet、Mobilenet-v2 モデルを使用して、ペン先とキャップのキー ポイント検出を実装します。このプロジェクトは、データ アノテーション、モデル トレーニング、Android 展開などの複数の章に分かれています。この記事は、プロジェクト「ペン先とキャップの検出<」に関する一連の記事の 1 つです。 a i=8>" C++ はペン先とキャップの検出アルゴリズムを実装します; その後のモデル エンジニアリングと Android プラットフォームの展開を容易にするために、プロジェクトは高精度のHRNet 検出モデル、軽量モデル LiteHRNet および Mobilenet モデルのトレーニングとテスト、および Python/C++/Android の複数のバージョンを提供します。

軽量の Mobilenet-v2 モデルは、一般的な Android スマートフォンでリアルタイムの検出結果を実現でき、CPU (4 スレッド) で約 50 ミリ秒、GPU で約 30 ミリ秒かかり、基本的にビジネスのパフォーマンス要件を満たします。 HRNetと軽量モデルLiteHRNet、Mobilenetの計算量とパラメータ量、および検出精度を以下の表に示します。

モデル 入力サイズ パラメータ(M) GFLOP AP
HRNet-w32 192×192 2848万 5734.05M 0.8418
LiteHRNet18 192×192 110万 182.15M 0.7469
モバイルネットv2 192×192 263万 529.25M 0.7531

最初に表示するペン先とキャップのキー ポイントの検出効果:

Androidペン先とキャップのキー ポイント検出APP デモ体験 (ダウンロード< a i= 4>):

https://download.csdn.net/download/guyuealian/88535143

  

[独創性を尊重し、転載する場合は出典を明記してください]https://blog.csdn.net/guyuealian/article/details/134070516


一連の記事「ペン先とキャップの検出」のその他のプロジェクトについては、以下を参照してください。


 2.ペン先とキャップポイント検出方法

ペン先とキャップのターゲットは小さいです。ターゲット検出を直接使用すると、ピクセルレベルの検出精度を達成することが困難です。一般的には、人体のキーポイント検出と同様のソリューションを使用することをお勧めします。現在、主流のキーポイント手法は 2 つあります。1 つは トップダウン (トップダウン) 手法で、もう 1 つは < i=3>ボトムアップ(ボトムアップ) メソッド;

(1)Top-Down(自上而下)方法

手検出(ペンを持った状態)とペン先やキャップのキーポイント検出を分離し、画像上で手のターゲット検出を行って手の位置を特定し、各手の画像を切り出してキーを推定ペン先とキャップのポイント。このクラス メソッドは速度が遅くなる傾向がありますが、姿勢推定の精度は高くなります。現在、主流のモデルには主に CPN、Hourglass、CPM、Alpha Pose、HRNet などが含まれます。

(2)Bottom-Up(自下而上)方法:

まず、画像内のすべてのペン先とキャップのキー ポイントを推定し、次にグループ化メソッドによってそれらを 1 つずつインスタンスに結合します。したがって、このタイプのメソッドは、推論をテストする場合、多くの場合、処理速度が速くなりますが、精度が低くなります。代表的な例は、COCO の 2016 年人体キーポイント検出チャンピオンである Open Pose です。

一般に、Tオプダウンの方が精度が高く、ボトムアップの方が速度が速くなります。現在の研究に基づくと、一般的に、トップダウン法はボトムアップ法よりも研究が進んでおり、その精度が高い。

このプロジェクトはトップダウン(トップダウン) を採用しています方法は、YOLOv5 モデルを使用して手検出 (手持ちペン検出) を実装し、HRNet を使用してペン先とキャップのキー ポイントを検出しますが、単純に YOLOv5 を使用してペン先の領域を特定すると理解することもできます。ペンを握った後、HRNet を使用してペン先を検出する ペンキャップの位置が洗練されました。

このプロジェクトはオープンソースの HRNet をベースに改良されており、HRNet プロジェクトについては GitHub を参照してください。

HRNet: https://github.com/leoxiaobin/deep-high-resolution-net.pytorch


3. ペン先とキャップのキーポイント検出モデル

(1) ペン先・キャップのキーポイント検出モデルの学習

このプロジェクトはトップダウン(トップダウン) を採用しています方法: YOLOv5 モデルを使用して手の検出 (手とペンの検出) を実装し、オープンソースの HRNet に基づいて実装を改善しますペン先とキャップのキー ポイントの検出<その後のモデル エンジニアリングと Android プラットフォームの展開を容易にするために、プロジェクトは軽量モデル LiteHRNet および Mobilenet モデルのトレーニングとテストをサポートし、Python/C++/Android の複数のバージョンを提供します< /span>; 軽量の Mobilenet-v2 モデルは、通常の Android スマートフォンでリアルタイムの検出結果を実現できます。CPU (4 スレッド) は約 50 ミリ秒、GPU は約 30 ミリ秒であり、基本的に次のパフォーマンス要件を満たしています。ビジネス

このブログ投稿では主に C++ バージョンのモデル デプロイメントを共有します。Python バージョンのトレーニング コードと関連データ セットは含まれません。ペン先とキャップ a>キー 点検出のトレーニング方法とデータセットの手順については、以下を参照してください。

ペン先とキャップの検出 2: Pytorch はペン先とキャップの検出アルゴリズムを実装します (トレーニング コードとデータ セットを含む)

下表はHRNet、軽量モデルLiteHRNet、Mobilenetの計算量とパラメータ量、およびその検出精度AP、高精度検出モデルHRNet-w32ではAPは0.8418に達しますが、そのパラメータ量は計算量や計算量が比較的多く、モバイル端末への導入には適さない; LiteHRNet18やMobilenet-v2はパラメータや計算量が比較的少ないため、モバイル端末への導入に適しているが、理論上の計算量やパラメータ量は少ないLiteHRNet18 は Mobilenet-v2 よりも性能が低いですが、実際のテストでは Mobilenet-v2 の方が高速に動作することがわかりました。軽量の Mobilenet-v2 モデルは、一般的な Android スマートフォンでリアルタイムの検出結果を実現でき、CPU (4 スレッド) で約 50 ミリ秒、GPU で約 30 ミリ秒かかり、基本的にビジネスのパフォーマンス要件を満たします。

モデル 入力サイズ パラメータ(M) GFLOP AP
HRNet-w32 192×192 2848万 5734.05M 0.8418
LiteHRNet18 192×192 110万 182.15M 0.7469
モバイルネットv2 192×192 263万 529.25M 0.7531

(2) PytorchモデルをONNXモデルに変換

現在、CNN モデルには多くのデプロイメント方法があります。TNN、MNN、NCNN、TensorRT などのデプロイメント ツールを使用できます。私は C/C++ ターミナルのデプロイメントに TNN を使用します。デプロイメント プロセスは 4 つのステップに分けることができます。モデルのトレーニング -> モデルを ONNX モデルに変換 -> ONNX モデルを TNN モデルに変換 -> C/C++ デプロイTNNモデル。

Pytorch モデルをトレーニングした後、後続のモデル展開のためにモデルを ONNX モデルに変換する必要があります。

  • 元のプロジェクトには変換スクリプトが用意されているので、model_file をモデル パスに変更するだけで済みます。
  •  Convert_torch_to_onnx.py は、Pytorch モデルを ONNX モデルに変換するスクリプトを実装します。
python libs/convert_tools/convert_torch_to_onnx.py
"""
This code is used to convert the pytorch model into an onnx format model.
"""
import os
import torch.onnx
from pose.inference import PoseEstimation
from basetrainer.utils.converter import pytorch2onnx
 
 
def load_model(config_file, model_file, device="cuda:0"):
    pose = PoseEstimation(config_file, model_file, device=device)
    model = pose.model
    config = pose.config
    return model, config
 
 
def convert2onnx(config_file, model_file, device="cuda:0", onnx_type="kp"):
    """
    :param model_file:
    :param input_size:
    :param device:
    :param onnx_type:
    :return:
    """
    model, config = load_model(config_file, model_file, device=device)
    model = model.to(device)
    model.eval()
    model_name = os.path.basename(model_file)[:-len(".pth")]
    onnx_file = os.path.join(os.path.dirname(model_file), model_name + ".onnx")
    # dummy_input = torch.randn(1, 3, 240, 320).to("cuda")
    input_size = tuple(config.MODEL.IMAGE_SIZE)  # w,h
    input_shape = (1, 3, input_size[1], input_size[0])
    pytorch2onnx.convert2onnx(model,
                              input_shape=input_shape,
                              input_names=['input'],
                              output_names=['output'],
                              onnx_file=onnx_file,
                              opset_version=11)
 
 
if __name__ == "__main__":
    model_file = "../../work_space/hand/mobilenet_v2_21_192_192_custom_coco_20230928_065444_0934/model/best_model_153_0.7574.pth"
    config_file = "../../work_space/hand/mobilenet_v2_21_192_192_custom_coco_20230928_065444_0934/mobilenetv2_hand_192_192.yaml"
    convert2onnx(config_file, model_file)

(3) ONNX モデルから TNN モデルへの変換

現在、CNN モデルのデプロイ方法は多数あり、TNN、MNN、NCNN、TensorRT などのデプロイ ツールを使用できます。私は C/C++ ターミナルのデプロイに TNN を使用しています。

TNN変換ツール:

​​​​​


4. ペン先とキャップのキーポイント検出 C/C++ の導入

プロジェクト IDE 開発ツールは CLion を使用します。関連する依存ライブラリには主に OpenCV、base-utils、TNN、OpenCL (オプション) が含まれます。OpenCV がインストールされている必要があります。OpenCL はモデルの高速化に使用されます。base-utils と TNN は構成されており、インストールする必要があります。

このプロジェクトは Ubuntu18.04 でのみテストされているため、Windows システムで開発環境を自分で設定してください。

(1) プロジェクトの構成

​​

(2) 開発環境の構築(OpenCV+OpenCL+base-utils+TNN)

プロジェクト IDE 開発ツールは CLion を使用します。関連する依存ライブラリには主に OpenCV、base-utils、TNN、OpenCL (オプション) が含まれます。OpenCV がインストールされている必要があります。OpenCL はモデルの高速化に使用されます。base-utils と TNN は構成されており、インストールする必要があります。

このプロジェクトは Ubuntu18.04 でのみテストされています。Windows システムで自分で設定してコンパイルしてください。

  • OpenCVのインストール: 画像処理

画像処理 (画像の読み取り、画像のトリミングなど) には、処理用の OpenCV ライブラリの使用が必要です。

インストール チュートリアル:opencv と opencv_contrib の Ubuntu18.04 インストール

OpenCV ライブラリは opencv-4.3.0 バージョンを使用しますが、opencv_contrib ライブラリは当面使用されないため、インストールする必要はありません。

  • OpenCL のインストール: モデル アクセラレーション

 インストール チュートリアル:Ubuntu16.04 OpenCV と OpenCL のインストール

OpenCL はモデルの GPU アクセラレーションに使用されますが、モデル推論のアクセラレーションに OpenCL が使用されない場合、純粋な C++ 推論モデルは非常に遅くなります。

  • Base-utils: C++ ライブラリ

GitHub: https://github.com/PanJinquan/base-utils (インストールは必要ありません、プロジェクトは構成されています)

Base_utils は個人開発によく使用される C++ ライブラリで、C/C++ OpenCV などの一般的なアルゴリズムを統合しています。

  • TNN: モデル推論

GitHub: https://github.com/Tencent/TNN (インストールは必要ありません。プロジェクトは構成されています)

Tencent Youtu Lab がオープンソース化した高性能で軽量のニューラル ネットワーク推論フレームワークには、クロスプラットフォーム、高性能、モデル圧縮、コードの調整など、多くの優れた利点もあります。 TNN フレームワークは、オリジナルの Rapidnet および ncnn フレームワークに基づいてモバイル デバイスのサポートとパフォーマンスの最適化をさらに強化し、業界の主流のオープンソース フレームワークの高いパフォーマンスと優れたスケーラビリティ特性を利用して、バックグラウンド X86 および NV のサポートを拡張します。 GPU。モバイルサイド TNN は、モバイル QQ、Weishi、PTu などの多くのアプリケーションに実装されています。サーバーサイド TNN は、Tencent Cloud AI の基本的な高速化フレームワークとして、多くのビジネスの実装を加速するサポートを提供してきました。

(3) TNNモデルの展開

プロジェクトは、C/C++ バージョンのペン先とキャップのキー ポイント検出を実装します。手の検出 (手とペンの検出) は YOLOv5 モデルを使用します。ペン先とキャップのキー ポイント検出HRNet モデルを使用、モデル推論は TNN デプロイメント フレームワークを使用 (マルチスレッド CPU および GPU アクセラレーション推論をサポート)、画像処理は OpenCV ライブラリを使用、モデル アクセラレーションは OpenCL を使用、リアルタイム通常のデバイス上で処理を実現できます。

このデモで独自のトレーニング済みモデルをデプロイする場合は、トレーニング済みの Pytorch モデルを ONNX に変換し、それを TNN モデルに変換して、元のモデルを独自の TNN モデルに置き換えます。

(4) CMakeの設定

これは CMakeLists.txt で、主な構成が含まれていますOpenCV+OpenCL+base-utils+TNNこれら 4 つのライブラリは Windows で利用できます自分で設定してコンパイルする

cmake_minimum_required(VERSION 3.5)
project(Detector)

add_compile_options(-fPIC) # fix Bug: can not be used when making a shared object
set(CMAKE_CXX_FLAGS "-Wall -std=c++11 -pthread")
#set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
#set(CMAKE_CXX_FLAGS_DEBUG "-g")

if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
    # -DCMAKE_BUILD_TYPE=Debug
    # -DCMAKE_BUILD_TYPE=Release
    message(STATUS "No build type selected, default to Release")
    set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type (default Debug)" FORCE)
endif ()

# opencv set
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS} ./src/)
#MESSAGE(STATUS "OpenCV_INCLUDE_DIRS = ${OpenCV_INCLUDE_DIRS}")

# base_utils
set(BASE_ROOT 3rdparty/base-utils) # 设置base-utils所在的根目录
add_subdirectory(${BASE_ROOT}/base_utils/ base_build) # 添加子目录到build中
include_directories(${BASE_ROOT}/base_utils/include)
include_directories(${BASE_ROOT}/base_utils/src)
MESSAGE(STATUS "BASE_ROOT = ${BASE_ROOT}")


# TNN set
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake buil ds it for you.
# Gradle automatically packages shared libraries with your APK.
# build for platform
# set(TNN_BUILD_SHARED OFF CACHE BOOL "" FORCE)
if (CMAKE_SYSTEM_NAME MATCHES "Android")
    set(TNN_OPENCL_ENABLE ON CACHE BOOL "" FORCE)
    set(TNN_ARM_ENABLE ON CACHE BOOL "" FORCE)
    set(TNN_BUILD_SHARED OFF CACHE BOOL "" FORCE)
    set(TNN_OPENMP_ENABLE ON CACHE BOOL "" FORCE)  # Multi-Thread
    #set(TNN_HUAWEI_NPU_ENABLE OFF CACHE BOOL "" FORCE)
    add_definitions(-DTNN_OPENCL_ENABLE)           # for OpenCL GPU
    add_definitions(-DTNN_ARM_ENABLE)              # for Android CPU
    add_definitions(-DDEBUG_ANDROID_ON)            # for Android Log
    add_definitions(-DPLATFORM_ANDROID)
elseif (CMAKE_SYSTEM_NAME MATCHES "Linux")
    set(TNN_OPENCL_ENABLE ON CACHE BOOL "" FORCE)
    set(TNN_CPU_ENABLE ON CACHE BOOL "" FORCE)
    set(TNN_X86_ENABLE OFF CACHE BOOL "" FORCE)
    set(TNN_QUANTIZATION_ENABLE OFF CACHE BOOL "" FORCE)
    set(TNN_OPENMP_ENABLE ON CACHE BOOL "" FORCE)  # Multi-Thread
    add_definitions(-DTNN_OPENCL_ENABLE)           # for OpenCL GPU
    add_definitions(-DDEBUG_ON)                    # for WIN/Linux Log
    add_definitions(-DDEBUG_LOG_ON)                # for WIN/Linux Log
    add_definitions(-DDEBUG_IMSHOW_OFF)            # for OpenCV show
    add_definitions(-DPLATFORM_LINUX)
elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
    set(TNN_OPENCL_ENABLE ON CACHE BOOL "" FORCE)
    set(TNN_CPU_ENABLE ON CACHE BOOL "" FORCE)
    set(TNN_X86_ENABLE ON CACHE BOOL "" FORCE)
    set(TNN_QUANTIZATION_ENABLE OFF CACHE BOOL "" FORCE)
    set(TNN_OPENMP_ENABLE ON CACHE BOOL "" FORCE)  # Multi-Thread
    add_definitions(-DTNN_OPENCL_ENABLE)           # for OpenCL GPU
    add_definitions(-DDEBUG_ON)                    # for WIN/Linux Log
    add_definitions(-DDEBUG_LOG_ON)                # for WIN/Linux Log
    add_definitions(-DDEBUG_IMSHOW_OFF)            # for OpenCV show
    add_definitions(-DPLATFORM_WINDOWS)
endif ()
set(TNN_ROOT 3rdparty/TNN)
include_directories(${TNN_ROOT}/include)
include_directories(${TNN_ROOT}/third_party/opencl/include)
add_subdirectory(${TNN_ROOT}) # 添加外部项目文件夹
set(TNN -Wl,--whole-archive TNN -Wl,--no-whole-archive)# set TNN library
MESSAGE(STATUS "TNN_ROOT = ${TNN_ROOT}")

# Detector
include_directories(src)
set(SRC_LIST
        src/Interpreter.cpp
        src/pose_detector.cpp
        src/object_detection.cpp
        src/pose_filter.cpp
        src/yolov5.cpp
        )
add_library(dlcv SHARED ${SRC_LIST})
target_link_libraries(dlcv ${OpenCV_LIBS} base_utils)
MESSAGE(STATUS "DIR_SRCS = ${SRC_LIST}")
add_executable(Detector src/main.cpp)
target_link_libraries(Detector dlcv ${TNN} -lpthread)


(5) メインソースコード

メイン プログラムに関数 main を実装すると、ペン先とキャップのキー ポイント検出を使用する方法が提供され、写真、ビデオ、カメラのテストがサポートされます。

  •     Test_image_file(); // テスト画像ファイル
  •     Test_video_file(); // テストビデオファイル
  •     Test_camera(); //カメラをテストする
//
// Created by [email protected] on 2020/6/3.
//

#include "object_detection.h"
#include "yolov5.h"
#include "Types.h"
#include <iostream>
#include <string>
#include <vector>
#include "file_utils.h"
#include "image_utils.h"

using namespace dl;
using namespace vision;
using namespace std;

const int num_thread = 1; // 开启CPU线程数目
DeviceType device = GPU;  // 选择运行设备CPU/GPU

// 目标检测SSD或者YOLOv5
const float scoreThresh = 0.5;
const float iouThresh = 0.3;
//const char *det_model_file = (char *) "../data/tnn/ssd/rfb1.0_person_320_320_sim.opt.tnnmodel";
//const char *det_proto_file = (char *) "../data/tnn/ssd/rfb1.0_person_320_320_sim.opt.tnnproto";
//ObjectDetectionParam model_param = PERSON_MODEL;//模型参数
//ObjectDetection *detector = new ObjectDetection(det_model_file, det_proto_file, model_param, num_thread, device);

const char *det_model_file = (char *) "../data/tnn/yolov5/yolov5s05_320.sim.tnnmodel";
const char *det_proto_file = (char *) "../data/tnn/yolov5/yolov5s05_320.sim.tnnproto";
YOLOv5Param dets_model_param = YOLOv5s05_320;//模型参数
YOLOv5 *detector = new YOLOv5(det_model_file,
                              det_proto_file,
                              dets_model_param,
                              num_thread,
                              device);
// 关键点检测
const float poseThresh = 0.3;
const char *pose_model_file = (char *) "../data/tnn/pose/litehrnet18_192_192.sim.tnnmodel";
const char *pose_proto_file = (char *) "../data/tnn/pose/litehrnet18_192_192.sim.tnnproto";
PoseParam pose_model_param = HAND_PARAM;//模型参数
PoseDetector *pose = new PoseDetector(pose_model_file, pose_proto_file, pose_model_param, num_thread, device);

void test_image_file() {
    //测试图片的目录
    string image_dir = "../data/test_image";
    std::vector<string> image_list = get_files_list(image_dir);
    for (string image_path:image_list) {
        cv::Mat bgr = cv::imread(image_path);
        if (bgr.empty()) continue;
        FrameInfo resultInfo;
        // 进行目标检测
        detector->detect(bgr, &resultInfo, scoreThresh, iouThresh);
        // 进行关键点检测
        pose->detect(bgr, &resultInfo, poseThresh);
        // 可视化代码
        pose->visualizeResult(bgr, resultInfo, pose_model_param.skeleton, false, 0);
    }

    delete detector;
    detector = nullptr;
    delete pose;
    pose = nullptr;
    printf("FINISHED.\n");
}


/***
 * 测试视频文件
 * @return
 */
int test_video_file() {
    //测试视频文件
    string video_file = "../data/video/video-test.mp4";
    cv::VideoCapture cap;
    bool ret = get_video_capture(video_file, cap);
    cv::Mat frame;
    while (ret) {
        cap >> frame;
        if (frame.empty()) break;
        FrameInfo resultInfo;
        // 进行目标检测
        detector->detect(frame, &resultInfo, scoreThresh, iouThresh);
        // 进行关键点检测
        pose->detect(frame, &resultInfo, poseThresh);
        // 可视化代码
        pose->visualizeResult(frame, resultInfo, pose_model_param.skeleton, false, 5);
    }
    cap.release();

    delete detector;
    detector = nullptr;
    delete pose;
    pose = nullptr;
    printf("FINISHED.\n");
    return 0;

}


/***
 * 测试摄像头
 * @return
 */
int test_camera() {
    int camera = 0; //摄像头ID号(请修改成自己摄像头ID号)
    cv::VideoCapture cap;
    bool ret = get_video_capture(camera, cap);
    cv::Mat frame;
    while (ret) {
        cap >> frame;
        if (frame.empty()) break;
        FrameInfo resultInfo;
        // 进行目标检测
        detector->detect(frame, &resultInfo, scoreThresh, iouThresh);
        // 进行关键点检测
        pose->detect(frame, &resultInfo, poseThresh);
        // 可视化代码
        pose->visualizeResult(frame, resultInfo, pose_model_param.skeleton, false, 5);
    }
    cap.release();
    delete detector;
    detector = nullptr;
    delete pose;
    pose = nullptr;
    printf("FINISHED.\n");
    return 0;

}



int main() {
    test_image_file();   // 测试图片文件
    test_video_file();   // 测试视频文件
    test_camera();       //测试摄像头
    return 0;
}

(6) ソースコードのコンパイルと操作

スクリプトをコンパイルするか、直接: bash build.sh

#!/usr/bin/env bash
if [ ! -d "build/" ];then
  mkdir "build"
else
  echo "exist build"
fi
cd build
cmake ..
make -j4
sleep 1
./Detector

  • CPUの動作パフォーマンスをテストしたい場合は、src/main.cppを変更してください。

DeviceType デバイス = CPU;

  • GPU動作のパフォーマンスをテストしたい場合は、src/main.cppを変更してください(OpenCLの設定が必要です) 

DeviceType デバイス = GPU;

PS: 純粋な CPU C++ 推論モードは時間がかかり、数秒かかりますが、OpenCL アクセラレーションをオンにすると、GPU モードではわずか十数ミリ秒しかかからず、パフォーマンスが大幅に向上します。

(7) デモテストの効果 

 C++版とPython版の結果はほぼ同じですが、ペン先とキャップのキーポイント検出結果を表示すると以下のようになります。


5. プロジェクトのソースコードのダウンロード

プロジェクト ソース コードのダウンロード アドレス:C++ はペン先とキャップの検出アルゴリズムを実装しています (ソース コードが含まれていますが、リアルタイム検出)

プロジェクトのソース コードの完全なセットには次のものが含まれます。

  1. C/C++ ソース コードは YOLOv5 の手検出 (ペンを持つ手) をサポートします。
  2. C/C++ ソース コードは、HRNet ペン先とキャップのキー ポイント検出の高精度バージョンを提供します
  3. C/C++ ソース コードは、軽量モデル LiteHRNet および Mobilenet-v2 のペン先とキャップのキー ポイント検出を提供します。
  4. C/C++ ソース コードは CPU と GPU をサポートしています。GPU (OpenCL) をオンにすると、リアルタイムで検出および識別できます (純粋な CPU 推論は非常に遅く、モデル アクセラレーションには OpenCL の設定が必要で、GPU 推論には約 15 ミリ秒かかります)。
  5. C/C++ ソース コード デモは画像、ビデオ、カメラのテストをサポートします
  6. プロジェクトはbase-utilsとTNNで構成されていますが、OpenCVとOpenCLは独自にコンパイルしてインストールする必要があります。

 Androidペン先とキャップのキー ポイント検出APP デモ体験 (ダウンロード< a i= 4>):

https://download.csdn.net/download/guyuealian/88535143

    


6. 特別編:ペン先指先検出

長さの関係で、この記事ではペン先とキャップのキー ポイント検出のみを実装します。本質的には、指先の読み取りまたは a> a>; 実装方法はペン先やキャップのキーポイント検出と同様です。 機能。ペンキャップ検出は必要ないかもしれませんが、ペン先ポイント読み取り

以下は、製品導入に成功したペン先 + 指先検出アルゴリズムのデモで、ペン先とキャップの検出よりも検出精度と速度パフォーマンスが優れています。

ペン先+指先検出アルゴリズムが必要な場合は、公式アカウントからご相談ください。

指先のペン先 Android デモ身体検査:https://download.csdn.net/download/guyuealian/88558414

指先ペン先検出 Demo01

指先ペン先検出 Demo02

おすすめ

転載: blog.csdn.net/guyuealian/article/details/134070516