[ポートレートカットアウト] 導入に vs2022、onnxruntime フレームワークを使用 (ビデオおよびマルチ画像処理)

1. ポートレートマットの応用シナリオ

1. 画像編集: 画像編集ソフトウェアでは、ポートレートのマット化はよく使用される操作の 1 つです。切り抜きにより、文字を元の背景から分離して新しい背景に配置することができ、文字の背景を変更する効果を得ることができる。これは、映画のポストプロダクション特殊効果、ゲームの役割の置き換えなどの分野で幅広い用途に使用できます。

2. ビデオ特殊効果: ビデオ編集および特殊効果制作において、ポートレート マッティングも重要なテクノロジーの 1 つです。ビデオフレーム内のキャラクターをリアルタイムに切り出して追跡することで、キャラクターの消滅や着替えなどの特殊効果を実現し、ビデオの視覚効果を大幅に豊かにします。3. AR 特殊効果: AR (拡張現実) や静止画の特殊効果を作成する場合、人物や対象物を選択することは非常に重要なステップです。人物や物体を正確に抽出することによってのみ、リアルタイムシーン内でそれらをリアルタイムに置き換えたり追跡したりすることができ、さまざまな興味深いAR特殊効果を実現できます。これは、多くの携帯電話の AR コスメティクスやインターフェイスに反映されています。4. 顔認識: 顔認識システムでは、顔を検出して位置を特定することが最初のステップであり、システムのパフォーマンスと精度を向上させるために、ポートレートマット技術が検出と位置特定のプロセスを支援するために頻繁に使用されます。5.バーチャルメイクアップ:ポートレートマットにより、キャラクターの顔領域を分離できます。次に、顔の領域にさまざまなメイクアップや装飾を追加し、元のイメージに戻して、現代のメイクアップの分野で広く求められている、キャラクターにさまざまなダイナミックなメイクアップや装飾を身に着けているような効果を実現します。要約すると、ポートレートマットには、画像処理、コンピュータービジョン、人工知能の分野において非常に重要な応用価値があります。関連技術の進歩により、ポートレートマットの効果は向上し続け、適用範囲も拡大し続けており、基盤技術として、より多様な応用シーンに対応できるようになります。これはまた、関連業界に従事する研究者や開発者に多くの機会と課題をもたらします。

2. カットアウト効果

26bd5d2b20ebf743acabe03eb8c4295f.png

22195cc69aaaf7dc466d76ebae8d0eab.png

フォルダーの切り抜きを横切る

ビデオポートレートカットアウト

3. 導入

参考URL1からソースコードをダウンロードし、Readmeファイルに従ってonnxruntime-win-x64-gpu-1.9.0をダウンロードし、(opencv4.5.5とonnxruntime-win-x64-gpu-1.9.0)のインクルードディレクトリ、ライブラリディレクトリを追加、Windows ランタイム ライブラリ ディレクトリ、リンカー - 入力 - 追加の依存関係 (opencv_world455.lib、onnxruntime.lib)。

構成プロパティ -Vcpkg-Use Vcpkg は No に設定されます

ヘッダーファイルのcuda参照を変更します。

//#include <cuda_provider_factory.h> 
#include <tensorrt_provider_factory.h>

Detect_video.cpp ファイルを変更する

#include "Detect_video.h"
#include "Detect.h"


// 调用摄像头或者读取本地视频文件,进行抠图效果展示
void detect_video(float downsample_ratio, Ort::Session& session, string choose,
  std::vector<std::vector<int64_t>>& dynamic_input_node_dims,
  std::vector<float>& dynamic_src_value_handler,
  std::vector<float>& dynamic_r1i_value_handler,
  std::vector<float>& dynamic_r2i_value_handler,
  std::vector<float>& dynamic_r3i_value_handler,
  std::vector<float>& dynamic_r4i_value_handler,
  std::vector<float>& dynamic_dsr_value_handler,
  std::vector<const char*>& input_node_names,
  std::vector<const char*>& output_node_names,
  bool& context_is_update,
  unsigned int& num_inputs,
  unsigned int& num_outputs
)
{


  double inferenceTime = 0.0;


  cv::VideoCapture video_capture;
  cv:String outpath;
  // 选择视频地址抠图或者摄像头抠图
  if (choose == "movie") {
    cout << "视频地址:" << endl;
    cin >> choose;
    video_capture.open(choose);
    outpath = choose + "_out.mp4";
  }
  else
  {
    cout << "请输入调用摄像头的序号:" << endl;
    int num = 0;
    cin >> num;
    video_capture.open(num);
    outpath= cv::format("%d", num) + "_out.mp4";
  }


  if (!video_capture.isOpened())
  {
    std::cout << "Can not open video" << "\n";
    return;
  }
  // 获取视频信息 
  int fps = video_capture.get(cv::CAP_PROP_FPS);
  cv::Size size = cv::Size((int)video_capture.get(cv::CAP_PROP_FRAME_WIDTH),
    (int)video_capture.get(cv::CAP_PROP_FRAME_HEIGHT));
  // 创建视频写入对象 
  cv::VideoWriter outputVideo;
  //cv:String outpath = choose == "movie" ? choose + "_out.mp4" : cv::format("%d",num) + "_out.mp4";
  outputVideo.open(outpath,
    cv::VideoWriter::fourcc('M', 'J', 'P', 'G'),
    fps, size, true);


  if (!outputVideo.isOpened()) {
    printf("Failed to open video writer!");
    return ;
  }
  // 2. matting loop
  cv::Mat mat,dst1,dst2;


  while (video_capture.read(mat))
  {
    //开始时间
    double t1 = static_cast<double>(cv::getTickCount());
    cv::resize(mat, dst1, cv::Size(), 0.5, 0.5, cv::INTER_NEAREST);
    cv::imshow("原图", dst1);
    // 人像抠图
    mat = detect_human(mat, downsample_ratio, session,
      dynamic_input_node_dims,
      dynamic_src_value_handler,
      dynamic_r1i_value_handler,
      dynamic_r2i_value_handler,
      dynamic_r3i_value_handler,
      dynamic_r4i_value_handler,
      dynamic_dsr_value_handler,
      input_node_names,
      output_node_names,
      context_is_update,
      num_inputs,
      num_outputs
    );


    // 人像抠图显示mask
    /*mat = detect(mat,true, downsample_ratio, session,
      dynamic_input_node_dims,
      dynamic_src_value_handler,
      dynamic_r1i_value_handler,
      dynamic_r2i_value_handler,
      dynamic_r3i_value_handler,
      dynamic_r4i_value_handler,
      dynamic_dsr_value_handler,
      input_node_names,
      output_node_names,
      context_is_update,
      num_inputs,
      num_outputs
    );*/


    //结束时间,计算fps
    double t2 = static_cast<double>(cv::getTickCount());
    inferenceTime = (t2 - t1) / cv::getTickFrequency() * 1000;
    std::stringstream fpsSs;
    fpsSs << "FPS: " << int(1000.0f / inferenceTime * 100) / 100.0f;
    // 向每帧写入fps
    cv::putText(mat, fpsSs.str(), cv::Point(16, 32),
      cv::FONT_HERSHEY_COMPLEX, 0.8, cv::Scalar(0, 0, 255));
    //缩放显示
    cv::resize(mat, dst2, cv::Size(), 0.5, 0.5, cv::INTER_NEAREST);
    cv::imshow("抠图", dst2);
    // 写入该帧到视频  
    if (outputVideo.isOpened())
      outputVideo.write(mat);
    cv::waitKey(1);
    // 4. check context states.
    if (!context_is_update) break;


    if (_kbhit()) // 如果有按键被按下
    {
      if (_getch() == 'q') //如果按下了q键则跳出循环
      {
        break;
      }


    }
  }
  // 5. release
  video_capture.release();
  outputVideo.release();
  destroyAllWindows();
}

main.cpp

void showmenu()
{
  printf("----菜单----\n");
  printf("1-遍历文件夹抠图(保存对应抠图文件,默认选项)\n");
  printf("2-图片抠图展示(不保存)\n");
  printf("3-视频抠图展示(保存)\n");
  printf("4-摄像头抠图展示(保存)\n");
  printf("5-摄像头换背景展示(不保存)\n");
  printf("0-退出函数\n");
}

プログラムを生成した後、私の cuda パスには複数のバージョンがあるため、

9f59ad460d77f08c6d6490ffd2ae1017.png

したがって、欠落している DLL プロンプトに従って、C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1 にあるすべての DLL をリリースにコピーします。不足している hdf5.dll もシステムから見つかり (すべて V:\vcpkg-master\installed\x64-windows\bin で検索されます。他の場所もあります)、それをコピーします。

OK、この調整後は、生成されたexeをvs環境で実行せずにダブルクリックしても問題ありません。

参考URL:

1. https://github.com/caip1299920300/RobustVideoMatting_onnxruntime (ソースアドレス)

2. https://github.com/microsoft/onnxruntime/releases/tag/v1.9.0

fadfdd950116a6956894b5e50dfefef3.png

終わり

おすすめ

転載: blog.csdn.net/cxyhjl/article/details/130664591