Commit abaad570 authored by limm's avatar limm
Browse files

add demo module

parent a64900f3
Pipeline #2814 canceled with stages
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MMDeployCSharp" Version="1.3.1" />
<PackageReference Include="OpenCvSharp4" Version="4.5.5.20211231" />
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.5.5.20211231" />
</ItemGroup>
</Project>
using System;
using System.Collections.Generic;
using OpenCvSharp;
using MMDeploy;
using System.Linq;
namespace pose_tracker
{
internal class Program
{
static class CocoSkeleton
{
public static List<(int, int)> Skeleton = new List<(int, int)>
{
(15, 13), (13, 11), (16, 14), (14, 12), (11, 12), (5, 11), (6, 12),
(5, 6), (5, 7), (6, 8), (7, 9), (8, 10), (1, 2), (0, 1),
(0, 2), (1, 3), (2, 4), (3, 5), (4, 6)
};
public static List<Scalar> Palette = new List<Scalar>
{
new Scalar(255, 128, 0), new Scalar(255, 153, 51), new Scalar(255, 178, 102),
new Scalar(230, 230, 0), new Scalar(255, 153, 255), new Scalar(153, 204, 255),
new Scalar(255, 102, 255), new Scalar(255, 51, 255), new Scalar(102, 178, 255),
new Scalar(51, 153, 255), new Scalar(255, 153, 153), new Scalar(255, 102, 102),
new Scalar(255, 51, 51), new Scalar(153, 255, 153), new Scalar(102, 255, 102),
new Scalar(51, 255, 51), new Scalar(0, 255, 0), new Scalar(0, 0, 255),
new Scalar(255, 0, 0), new Scalar(255, 255, 255),
};
public static List<int> LinkColor = new List<int>
{
0, 0, 0, 0, 7, 7, 7, 9, 9, 9, 9, 9, 16, 16, 16, 16, 16, 16, 16
};
public static List<int> PointColor = new List<int>
{
16, 16, 16, 16, 16, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0
};
}
static bool Visualize(OpenCvSharp.Mat frame, PoseTrackerOutput result, int long_edge,
int frame_id, bool with_bbox)
{
var skeleton = CocoSkeleton.Skeleton;
var palette = CocoSkeleton.Palette;
var link_color = CocoSkeleton.LinkColor;
var point_color = CocoSkeleton.PointColor;
float scale = 1;
if (long_edge != 0)
{
scale = (float)long_edge / (float)Math.Max(frame.Cols, frame.Rows);
}
if (scale != 1)
{
Cv2.Resize(frame, frame, new Size(), scale, scale);
}
else
{
frame = frame.Clone();
}
Action<List<float>, Scalar> drawBbox = (bbox, color) =>
{
for (int i = 0; i < bbox.Count; i++)
{
bbox[i] *= scale;
}
Cv2.Rectangle(frame, new OpenCvSharp.Point(bbox[0], bbox[1]),
new OpenCvSharp.Point(bbox[2], bbox[3]), color);
};
for (int i = 0; i < result.Count; i++)
{
PoseTrack pt = result.Results[i];
for (int j = 0; j < pt.Keypoints.Count; j++)
{
Pointf p = pt.Keypoints[j];
p.X *= scale;
p.Y *= scale;
pt.Keypoints[j] = p;
}
float score_thr = 0.5f;
int[] used = new int[pt.Keypoints.Count * 2];
for (int j = 0; j < skeleton.Count; j++)
{
int u = skeleton[j].Item1;
int v = skeleton[j].Item2;
if (pt.Scores[u] > score_thr && pt.Scores[v] > score_thr)
{
used[u] = used[v] = 1;
var p_u = new OpenCvSharp.Point(pt.Keypoints[u].X, pt.Keypoints[u].Y);
var p_v = new OpenCvSharp.Point(pt.Keypoints[v].X, pt.Keypoints[v].Y);
Cv2.Line(frame, p_u, p_v, palette[link_color[j]], 1, LineTypes.AntiAlias);
}
}
for (int j = 0; j < pt.Keypoints.Count; j++)
{
if (used[j] == 1)
{
var p = new OpenCvSharp.Point(pt.Keypoints[j].X, pt.Keypoints[j].Y);
Cv2.Circle(frame, p, 1, palette[point_color[j]], 2, LineTypes.AntiAlias);
}
}
if (with_bbox)
{
var bbox = new List<float> { pt.Bbox.Left, pt.Bbox.Top, pt.Bbox.Right, pt.Bbox.Bottom };
drawBbox(bbox, new Scalar(0, 255, 0));
}
}
Cv2.ImShow("pose_tracker", frame);
return Cv2.WaitKey(1) != 'q';
}
static void CvMatToMat(OpenCvSharp.Mat cvMat, out MMDeploy.Mat mat)
{
mat = new MMDeploy.Mat();
unsafe
{
mat.Data = cvMat.DataPointer;
mat.Height = cvMat.Height;
mat.Width = cvMat.Width;
mat.Channel = cvMat.Dims;
mat.Format = PixelFormat.BGR;
mat.Type = DataType.Int8;
mat.Device = null;
}
}
static void PrintHelperMessage()
{
string message = "usage:\n pose_tracker device det_model pose_model video";
Console.WriteLine(message);
}
static void Main(string[] args)
{
if (args.Length != 4)
{
PrintHelperMessage();
Environment.Exit(1);
}
string device_ = args[0];
string det_model_ = args[1];
string pose_model_ = args[2];
string video = args[3];
Model det_model = new Model(det_model_);
Model pose_model = new Model(pose_model_);
Device device = new Device(device_);
Context context = new Context(device);
// initialize tracker
PoseTracker tracker = new PoseTracker(det_model, pose_model, context);
PoseTracker.Params param = new PoseTracker.Params();
// set default param
param.Init();
// set custom param
param.DetMinBboxSize = 100;
param.DetInterval = 1;
param.PoseMaxNumBboxes = 6;
// optionally use OKS for keypoints similarity comparison
float[] sigmas = {0.026f, 0.025f, 0.025f, 0.035f, 0.035f, 0.079f, 0.079f, 0.072f, 0.072f,
0.062f, 0.062f, 0.107f, 0.107f, 0.087f, 0.087f, 0.089f, 0.089f };
param.SetKeypointSigmas(sigmas);
// create state
PoseTracker.State state = tracker.CreateState(param);
VideoCapture cap = new VideoCapture(video);
if (!cap.IsOpened())
{
Console.WriteLine("failed to open video: " + video);
Environment.Exit(1);
}
int frame_id = 0;
OpenCvSharp.Mat frame = new OpenCvSharp.Mat();
while (true)
{
cap.Read(frame);
if (frame.Empty())
{
break;
}
CvMatToMat(frame, out var mat);
// process
PoseTrackerOutput result = tracker.Apply(state, mat);
// visualize
if (!Visualize(frame, result, 0, frame_id++, true))
{
break;
}
}
param.DeleteKeypointSigmas();
tracker.Close();
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MMDeployCSharp" Version="0.12.0" />
<PackageReference Include="OpenCvSharp4" Version="4.5.5.20211231" />
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.5.5.20211231" />
</ItemGroup>
</Project>
using System;
using System.Collections.Generic;
using OpenCvSharp;
using MMDeploy;
namespace object_detection
{
class Program
{
static void CvMatToMat(OpenCvSharp.Mat[] cvMats, out MMDeploy.Mat[] mats)
{
mats = new MMDeploy.Mat[cvMats.Length];
unsafe
{
for (int i = 0; i < cvMats.Length; i++)
{
mats[i].Data = cvMats[i].DataPointer;
mats[i].Height = cvMats[i].Height;
mats[i].Width = cvMats[i].Width;
mats[i].Channel = cvMats[i].Dims;
mats[i].Format = PixelFormat.BGR;
mats[i].Type = DataType.Int8;
mats[i].Device = null;
}
}
}
static void CvWaitKey()
{
Cv2.WaitKey();
}
static void Main(string[] args)
{
if (args.Length != 3)
{
Console.WriteLine("usage:\n object_detection deviceName modelPath imagePath\n");
Environment.Exit(1);
}
string deviceName = args[0];
string modelPath = args[1];
string imagePath = args[2];
// 1. create handle
RotatedDetector handle = new RotatedDetector(modelPath, deviceName, 0);
// 2. prepare input
OpenCvSharp.Mat[] imgs = new OpenCvSharp.Mat[1] { Cv2.ImRead(imagePath, ImreadModes.Color) };
CvMatToMat(imgs, out var mats);
// 3. process
List<RotatedDetectorOutput> output = handle.Apply(mats);
// 4. show result
foreach (var obj in output[0].Results)
{
if (obj.Score < 0.1)
{
continue;
}
float xc = obj.Cx;
float yc = obj.Cy;
float wx = obj.Width / 2 * (float)Math.Cos(obj.Angle);
float wy = obj.Width / 2 * (float)Math.Sin(obj.Angle);
float hx = -obj.Height / 2 * (float)Math.Sin(obj.Angle);
float hy = obj.Height / 2 * (float)Math.Cos(obj.Angle);
OpenCvSharp.Point p1 = new OpenCvSharp.Point(xc - wx - hx, yc - wy - hy);
OpenCvSharp.Point p2 = new OpenCvSharp.Point(xc + wx - hx, yc + wy - hy);
OpenCvSharp.Point p3 = new OpenCvSharp.Point(xc + wx + hx, yc + wy + hy);
OpenCvSharp.Point p4 = new OpenCvSharp.Point(xc - wx + hx, yc - wy + hy);
var contours = new OpenCvSharp.Point[1][];
contours[0] = new OpenCvSharp.Point[4] { p1, p2, p3, p4 };
Cv2.DrawContours(imgs[0], contours, -1, new Scalar(0, 255, 0), 2);
}
Cv2.NamedWindow("mmrotate", WindowFlags.GuiExpanded);
Cv2.ImShow("mmrotate", imgs[0]);
CvWaitKey();
handle.Close();
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MMDeployCSharp" Version="0.12.0" />
<PackageReference Include="OpenCvSharp4" Version="4.5.5.20211231" />
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.5.5.20211231" />
</ItemGroup>
</Project>
# Copyright (c) OpenMMLab. All rights reserved.
cmake_minimum_required(VERSION 3.14)
project(mmdeploy-example)
if (NOT (${CMAKE_PROJECT_NAME} STREQUAL "MMDeploy"))
find_package(MMDeploy REQUIRED)
endif ()
function(add_example task folder name)
if ((NOT task) OR (task IN_LIST MMDEPLOY_TASKS))
# Search for c/cpp sources
file(GLOB _SRCS ${folder}/${name}.c*)
add_executable(${name} ${_SRCS})
if (NOT (MSVC OR APPLE))
# Disable new dtags so that executables can run even without LD_LIBRARY_PATH set
target_link_libraries(${name} PRIVATE -Wl,--disable-new-dtags)
endif ()
if (MMDEPLOY_BUILD_SDK_MONOLITHIC)
target_link_libraries(${name} PRIVATE mmdeploy ${OpenCV_LIBS})
else ()
# Load MMDeploy modules
mmdeploy_load_static(${name} MMDeployStaticModules)
mmdeploy_load_dynamic(${name} MMDeployDynamicModules)
# Link to MMDeploy libraries
target_link_libraries(${name} PRIVATE MMDeployLibs ${OpenCV_LIBS})
endif ()
install(TARGETS ${name} RUNTIME DESTINATION bin)
endif ()
endfunction()
add_example(classifier c image_classification)
add_example(classifier c batch_image_classification)
add_example(detector c object_detection)
add_example(detector c batch_object_detection)
add_example(segmentor c image_segmentation)
add_example(restorer c image_restorer)
add_example(text_detector c ocr)
add_example(pose_detector c pose_detection)
add_example(rotated_detector c rotated_object_detection)
add_example(video_recognizer c video_recognition)
# TODO: figure out a better way
# add_example("" c det_cls)
add_example(classifier cpp classifier)
add_example(detector cpp detector)
add_example(segmentor cpp segmentor)
add_example(restorer cpp restorer)
add_example(text_detector cpp text_ocr)
add_example(text_detector cpp text_det_recog)
add_example(pose_detector cpp pose_detector)
add_example(rotated_detector cpp rotated_detector)
add_example(pose_tracker cpp pose_tracker)
add_example(pose_detector cpp det_pose)
add_example(video_recognizer cpp video_cls)
#include <fstream>
#include <opencv2/imgcodecs/imgcodecs.hpp>
#include <string>
#include "mmdeploy/classifier.h"
static int batch_inference(mmdeploy_classifier_t classifier,
const std::vector<int>& image_ids,
const std::vector<mmdeploy_mat_t>& mats);
int main(int argc, char* argv[]) {
if (argc < 5) {
fprintf(stderr, "usage:\n image_classification device_name dump_model_directory "
"imagelist.txt batch_size\n");
return 1;
}
auto device_name = argv[1];
auto model_path = argv[2];
mmdeploy_classifier_t classifier{};
int status{};
status = mmdeploy_classifier_create_by_path(model_path, device_name, 0, &classifier);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to create classifier, code: %d\n", (int)status);
return 1;
}
// `file_path` is the path of an image list file
std::string file_path = argv[3];
const int batch = std::stoi(argv[argc-1]);
// read image paths from the file
std::ifstream ifs(file_path);
std::string img_path;
std::vector<std::string> img_paths;
while (ifs >> img_path) {
img_paths.emplace_back(std::move(img_path));
}
// read images and process batch inference
std::vector<cv::Mat> images;
std::vector<int> image_ids;
std::vector<mmdeploy_mat_t> mats;
for (int i = 0; i < (int)img_paths.size(); ++i) {
auto img = cv::imread(img_paths[i]);
if (!img.data) {
fprintf(stderr, "failed to load image: %s\n", img_paths[i].c_str());
continue;
}
images.push_back(img);
image_ids.push_back(i);
mmdeploy_mat_t mat{
img.data, img.rows, img.cols, 3, MMDEPLOY_PIXEL_FORMAT_BGR, MMDEPLOY_DATA_TYPE_UINT8};
mats.push_back(mat);
// process batch inference
if ((int)mats.size() == batch) {
if (batch_inference(classifier, image_ids, mats) != 0) {
continue;
}
// clear buffer for next batch
mats.clear();
image_ids.clear();
images.clear();
}
}
// process batch inference if there are still unhandled images
if (!mats.empty()) {
(void)batch_inference(classifier, image_ids, mats);
}
mmdeploy_classifier_destroy(classifier);
return 0;
}
int batch_inference(mmdeploy_classifier_t classifier, const std::vector<int>& image_ids,
const std::vector<mmdeploy_mat_t>& mats) {
mmdeploy_classification_t* res{};
int* res_count{};
auto status = mmdeploy_classifier_apply(classifier, mats.data(), (int)mats.size(),
&res, &res_count);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to apply classifier to batch images %d, code: %d\n",
(int)mats.size(), (int)status);
return 1;
}
// print the inference results
auto res_ptr = res;
for (int j = 0; j < (int)mats.size(); ++j) {
fprintf(stderr, "results in the %d-th image:\n", image_ids[j]);
for (int k = 0; k < res_count[j]; ++k, ++res_ptr) {
fprintf(stderr, " label: %d, score: %.4f\n", res_ptr->label_id, res_ptr->score);
}
}
// release results buffer
mmdeploy_classifier_release_result(res, res_count, (int)mats.size());
return 0;
}
#include <fstream>
#include <opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <string>
#include "mmdeploy/detector.h"
static int batch_inference(mmdeploy_detector_t detector, std::vector<cv::Mat>& images,
const std::vector<int>& image_ids,
const std::vector<mmdeploy_mat_t>& mats);
static void visualize_detection(const std::string& output_name, cv::Mat& image,
const mmdeploy_detection_t* bboxes_ptr, int bboxes_num);
int main(int argc, char* argv[]) {
if (argc < 5) {
fprintf(stderr, "usage:\n object_detection device_name sdk_model_path "
"file_path batch_size\n");
return 1;
}
auto device_name = argv[1];
auto model_path = argv[2];
mmdeploy_detector_t detector{};
int status{};
status = mmdeploy_detector_create_by_path(model_path, device_name, 0, &detector);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to create detector, code: %d\n", (int)status);
return 1;
}
// file_path is the path of an image list file
std::string file_path = argv[3];
const int batch = std::stoi(argv[argc-1]);
// read image paths from the file
std::ifstream ifs(file_path);
std::string img_path;
std::vector<std::string> img_paths;
while (ifs >> img_path) {
img_paths.emplace_back(std::move(img_path));
}
// read images and process batch inference
std::vector<cv::Mat> images;
std::vector<int> image_ids;
std::vector<mmdeploy_mat_t> mats;
for (int i = 0; i < (int)img_paths.size(); ++i) {
auto img = cv::imread(img_paths[i]);
if (!img.data) {
fprintf(stderr, "failed to load image: %s\n", img_paths[i].c_str());
continue;
}
images.push_back(img);
image_ids.push_back(i);
mmdeploy_mat_t mat{
img.data, img.rows, img.cols, 3, MMDEPLOY_PIXEL_FORMAT_BGR, MMDEPLOY_DATA_TYPE_UINT8};
mats.push_back(mat);
// process batch inference
if ((int)mats.size() == batch) {
if (batch_inference(detector, images, image_ids, mats) != 0) {
continue;
}
// clear buffer for next batch
mats.clear();
image_ids.clear();
images.clear();
}
}
// process batch inference if there are still unhandled images
if (!mats.empty()) {
(void)batch_inference(detector, images, image_ids, mats);
}
mmdeploy_detector_destroy(detector);
return 0;
}
int batch_inference(mmdeploy_detector_t detector, std::vector<cv::Mat>& images,
const std::vector<int>& image_ids,
const std::vector<mmdeploy_mat_t>& mats) {
mmdeploy_detection_t* bboxes{};
int* res_count{};
auto status = mmdeploy_detector_apply(detector, mats.data(), mats.size(), &bboxes, &res_count);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to apply detector, code: %d\n", (int)status);
return 1;
}
mmdeploy_detection_t* bboxes_ptr = bboxes;
for (int i = 0; i < (int)mats.size(); ++i) {
fprintf(stdout, "results in the %d-th image:\n bbox_count=%d\n", image_ids[i], res_count[i]);
const std::string output_name = "output_detection_" + std::to_string(image_ids[i]) + ".png";
visualize_detection(output_name, images[i], bboxes_ptr, res_count[i]);
bboxes_ptr = bboxes_ptr + res_count[i];
}
mmdeploy_detector_release_result(bboxes, res_count, mats.size());
return 0;
}
void visualize_detection(const std::string& output_name, cv::Mat& image,
const mmdeploy_detection_t* bboxes_ptr, int bbox_num) {
for (int i = 0; i < bbox_num; ++i, ++bboxes_ptr) {
const auto& box = bboxes_ptr->bbox;
const auto& mask = bboxes_ptr->mask;
fprintf(stdout,
" box %d, left=%.2f, top=%.2f, right=%.2f, bottom=%.2f, "
"label=%d, score=%.4f\n",
i, box.left, box.top, box.right, box.bottom, bboxes_ptr->label_id, bboxes_ptr->score);
// skip detections with invalid bbox size (bbox height or width < 1)
if ((box.right - box.left) < 1 || (box.bottom - box.top) < 1) {
continue;
}
// skip detections less than specified score threshold
if (bboxes_ptr->score < 0.3) {
continue;
}
// generate mask overlay if model exports masks
if (mask != nullptr) {
fprintf(stdout, "mask %d, height=%d, width=%d\n", i, mask->height, mask->width);
cv::Mat imgMask(mask->height, mask->width, CV_8UC1, &mask->data[0]);
auto x0 = std::max(std::floor(box.left) - 1, 0.f);
auto y0 = std::max(std::floor(box.top) - 1, 0.f);
cv::Rect roi((int)x0, (int)y0, mask->width, mask->height);
// split the RGB channels, overlay mask to a specific color channel
cv::Mat ch[3];
split(image, ch);
int col = 0;
cv::bitwise_or(imgMask, ch[col](roi), ch[col](roi));
merge(ch, 3, image);
}
cv::rectangle(image, cv::Point{(int)box.left, (int)box.top},
cv::Point{(int)box.right, (int)box.bottom}, cv::Scalar{0, 255, 0});
}
cv::imwrite(output_name, image);
}
#include "mmdeploy/archive/json_archive.h"
#include "mmdeploy/core/logger.h"
#include "mmdeploy/core/mat.h"
#include "mmdeploy/core/module.h"
#include "mmdeploy/core/registry.h"
#include "mmdeploy/core/utils/formatter.h"
#include "mmdeploy/core/value.h"
#include "mmdeploy/experimental/module_adapter.h"
#include "mmdeploy/pipeline.h"
#include "opencv2/imgcodecs.hpp"
const auto config_json = R"(
{
"type": "Pipeline",
"input": "img",
"output": ["dets", "labels"],
"tasks": [
{
"type": "Inference",
"input": "img",
"output": "dets",
"params": { "model": "../_detection_tmp_model" }
},
{
"type": "Pipeline",
"input": ["boxes=*dets", "imgs=+img"],
"tasks": [
{
"type": "Task",
"module": "CropBox",
"scheduler": "crop",
"input": ["imgs", "boxes"],
"output": "patches"
},
{
"type": "Inference",
"input": "patches",
"output": "labels",
"params": { "model": "../_mmcls_tmp_model" }
}
],
"output": "*labels"
}
]
}
)"_json;
using namespace mmdeploy;
class CropBox {
public:
Result<Value> operator()(const Value& img, const Value& dets) {
auto patch = img["ori_img"].get<framework::Mat>();
if (dets.is_object() && dets.contains("bbox")) {
auto _box = from_value<std::vector<float>>(dets["bbox"]);
cv::Rect rect(cv::Rect2f(cv::Point2f(_box[0], _box[1]), cv::Point2f(_box[2], _box[3])));
patch = crop(patch, rect);
}
return Value{{"ori_img", patch}};
}
private:
static framework::Mat crop(const framework::Mat& img, cv::Rect rect) {
cv::Mat mat(img.height(), img.width(), CV_8UC(img.channel()), img.data<void>());
rect &= cv::Rect(cv::Point(0, 0), mat.size());
mat = mat(rect).clone();
std::shared_ptr<void> data(mat.data, [mat = mat](void*) {});
return framework::Mat{mat.rows, mat.cols, img.pixel_format(), img.type(), std::move(data)};
}
};
MMDEPLOY_REGISTER_FACTORY_FUNC(Module, (CropBox, 0),
[](const Value&) { return CreateTask(CropBox{}); });
int main() {
auto config = from_json<Value>(config_json);
mmdeploy_device_t device{};
mmdeploy_device_create("cpu", 0, &device);
mmdeploy_profiler_t profiler{};
mmdeploy_profiler_create("profile.bin", &profiler);
mmdeploy_context_t ctx{};
mmdeploy_context_create(&ctx);
mmdeploy_context_add(ctx, MMDEPLOY_TYPE_DEVICE, nullptr, device);
mmdeploy_context_add(ctx, MMDEPLOY_TYPE_PROFILER, nullptr, profiler);
auto thread_pool = mmdeploy_executor_create_thread_pool(4);
auto infer_thread = mmdeploy_executor_create_thread();
mmdeploy_context_add(ctx, MMDEPLOY_TYPE_SCHEDULER, "preprocess", thread_pool);
mmdeploy_context_add(ctx, MMDEPLOY_TYPE_SCHEDULER, "crop", thread_pool);
mmdeploy_context_add(ctx, MMDEPLOY_TYPE_SCHEDULER, "net", infer_thread);
mmdeploy_context_add(ctx, MMDEPLOY_TYPE_SCHEDULER, "postprocess", thread_pool);
mmdeploy_pipeline_t pipeline{};
if (auto ec = mmdeploy_pipeline_create_v3((mmdeploy_value_t)&config, ctx, &pipeline)) {
MMDEPLOY_ERROR("failed to create pipeline: {}", ec);
return -1;
}
cv::Mat mat = cv::imread("../demo.jpg");
framework::Mat img(mat.rows, mat.cols, PixelFormat::kBGR, DataType::kINT8, mat.data,
framework::Device(0));
Value input = Value::Array{Value::Array{Value::Object{{"ori_img", img}}}};
mmdeploy_value_t tmp{};
mmdeploy_pipeline_apply(pipeline, (mmdeploy_value_t)&input, &tmp);
auto output = std::move(*(Value*)tmp);
mmdeploy_value_destroy(tmp);
MMDEPLOY_INFO("{}", output);
mmdeploy_pipeline_destroy(pipeline);
mmdeploy_context_destroy(ctx);
mmdeploy_scheduler_destroy(infer_thread);
mmdeploy_scheduler_destroy(thread_pool);
mmdeploy_device_destroy(device);
mmdeploy_profiler_destroy(profiler);
return 0;
}
#include "mmdeploy/archive/json_archive.h"
#include "mmdeploy/core/logger.h"
#include "mmdeploy/core/mat.h"
#include "mmdeploy/core/module.h"
#include "mmdeploy/core/registry.h"
#include "mmdeploy/core/utils/formatter.h"
#include "mmdeploy/core/value.h"
#include "mmdeploy/detector.h"
#include "mmdeploy/experimental/module_adapter.h"
#include "mmdeploy/pipeline.h"
#include "mmdeploy/pose_detector.h"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
const auto config_json = R"(
{
"type": "Pipeline",
"input": "img",
"output": ["human", "keypoints"],
"tasks": [
{
"type": "Inference",
"input": "img",
"output": "dets",
"params": { "model": "TBD" }
},
{
"type": "Task",
"module": "FilterBbox",
"input": "dets",
"output": "human"
},
{
"type": "Pipeline",
"input": ["bboxes=*human", "imgs=+img"],
"tasks": [
{
"type": "Task",
"module": "AddBboxField",
"input": ["imgs", "bboxes"],
"output": "imgs_with_bboxes"
},
{
"type": "Inference",
"input": "imgs_with_bboxes",
"output": "keypoints",
"params": { "model": "TBD" }
}
],
"output": "*keypoints"
}
]
}
)"_json;
using namespace mmdeploy;
class AddBboxField {
public:
Result<Value> operator()(const Value& img, const Value& dets) {
auto _img = img["ori_img"].get<framework::Mat>();
cv::Rect rect(0, 0, _img.width(), _img.height());
if (dets.is_object() && dets.contains("bbox")) {
auto _box = from_value<std::vector<float>>(dets["bbox"]);
rect = cv::Rect(cv::Rect2f(cv::Point2f(_box[0], _box[1]), cv::Point2f(_box[2], _box[3])));
}
return Value{{"ori_img", _img}, {"bbox", {rect.x, rect.y, rect.width, rect.height}}};
}
};
MMDEPLOY_REGISTER_FACTORY_FUNC(Module, (AddBboxField, 0),
[](const Value&) { return CreateTask(AddBboxField{}); });
Result<Value> FilterBbox(const Value& dets) {
Value::Array rets;
for (const auto& det : dets) {
if (det["label_id"].get<int>() == 0 && det["score"].get<float>() >= 0.3) {
rets.push_back(det);
}
}
return rets;
}
MMDEPLOY_REGISTER_FACTORY_FUNC(Module, (FilterBbox, 0),
[](const Value&) { return CreateTask(FilterBbox); });
static std::vector<std::pair<int, int>> skeleton{
{15, 13}, {13, 11}, {16, 14}, {14, 12}, {11, 12}, {5, 11}, {6, 12}, {5, 6}, {5, 7}, {6, 8},
{7, 9}, {8, 10}, {1, 2}, {0, 1}, {0, 2}, {1, 3}, {2, 4}, {3, 5}, {4, 6}};
int main(int argc, char* argv[]) {
if (argc != 5) {
MMDEPLOY_INFO("usage: det_pose device det_model pose_model image");
return 0;
}
const auto device_name = argv[1];
const auto det_model_path = argv[2];
const auto pose_model_path = argv[3];
const auto image_path = argv[4];
auto config = from_json<Value>(config_json);
config["tasks"][0]["params"]["model"] = det_model_path;
config["tasks"][2]["tasks"][1]["params"]["model"] = pose_model_path;
mmdeploy_context_t context{};
mmdeploy_context_create(&context);
auto thread_pool = mmdeploy_executor_create_thread_pool(4);
auto single_thread = mmdeploy_executor_create_thread();
mmdeploy_context_add(context, MMDEPLOY_TYPE_SCHEDULER, "preprocess", thread_pool);
mmdeploy_context_add(context, MMDEPLOY_TYPE_SCHEDULER, "net", single_thread);
mmdeploy_context_add(context, MMDEPLOY_TYPE_SCHEDULER, "postprocess", thread_pool);
mmdeploy_device_t device{};
mmdeploy_device_create(device_name, 0, &device);
mmdeploy_context_add(context, MMDEPLOY_TYPE_DEVICE, nullptr, device);
mmdeploy_pipeline_t pipeline{};
if (auto ec = mmdeploy_pipeline_create_v3((mmdeploy_value_t)&config, context, &pipeline)) {
MMDEPLOY_ERROR("failed to create pipeline: {}", ec);
return -1;
}
cv::Mat mat = cv::imread(image_path);
if (!mat.data) {
MMDEPLOY_ERROR("invalid image path: {}", image_path);
}
framework::Mat img(mat.rows, mat.cols, PixelFormat::kBGR, DataType::kINT8, mat.data,
framework::Device(0));
Value input{{{{"ori_img", img}}}};
mmdeploy_value_t tmp{};
mmdeploy_pipeline_apply(pipeline, (mmdeploy_value_t)&input, &tmp);
mmdeploy_detection_t* dets{};
int* det_count{};
mmdeploy_detector_get_result(tmp, &dets, &det_count);
auto output = std::move(*(Value*)tmp);
mmdeploy_value_destroy(tmp);
// result of second output
auto& pose = output[1];
mmdeploy_pose_detection_t* kps{};
mmdeploy_pose_detector_get_result((mmdeploy_value_t)&pose, &kps);
MMDEPLOY_INFO("{}", *det_count);
for (int i = 0; i < *det_count; ++i) {
if (dets[i].label_id != 0 || dets[i].score < 0.3) {
continue;
}
const auto& bbox = dets[i].bbox;
cv::Point p1(bbox.left, bbox.top);
cv::Point p2(bbox.right, bbox.bottom);
cv::rectangle(mat, p1, p2, cv::Scalar(0, 255, 0));
for (int j = 0; j < kps[i].length; ++j) {
cv::Point p(kps[i].point[j].x, kps[i].point[j].y);
cv::circle(mat, p, 1, cv::Scalar(0, 255, 255), 2, cv::LINE_AA);
}
for (int j = 0; j < skeleton.size(); ++j) {
int u = skeleton[j].first;
cv::Point p_u(kps[i].point[u].x, kps[i].point[u].y);
int v = skeleton[j].second;
cv::Point p_v(kps[i].point[v].x, kps[i].point[v].y);
cv::line(mat, p_u, p_v, cv::Scalar(0, 255, 255), 1, cv::LINE_AA);
}
}
mmdeploy_pose_detector_release_result(kps, pose.size());
cv::imwrite("output_det_pose.jpg", mat);
mmdeploy_pipeline_destroy(pipeline);
mmdeploy_context_destroy(context);
mmdeploy_scheduler_destroy(single_thread);
mmdeploy_scheduler_destroy(thread_pool);
return 0;
}
#include <fstream>
#include <opencv2/imgcodecs/imgcodecs.hpp>
#include <string>
#include "mmdeploy/classifier.h"
int main(int argc, char* argv[]) {
if (argc != 4) {
fprintf(stderr, "usage:\n image_classification device_name dump_model_directory image_path\n");
return 1;
}
auto device_name = argv[1];
auto model_path = argv[2];
auto image_path = argv[3];
cv::Mat img = cv::imread(image_path);
if (!img.data) {
fprintf(stderr, "failed to load image: %s\n", image_path);
return 1;
}
mmdeploy_classifier_t classifier{};
int status{};
status = mmdeploy_classifier_create_by_path(model_path, device_name, 0, &classifier);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to create classifier, code: %d\n", (int)status);
return 1;
}
mmdeploy_mat_t mat{
img.data, img.rows, img.cols, 3, MMDEPLOY_PIXEL_FORMAT_BGR, MMDEPLOY_DATA_TYPE_UINT8};
mmdeploy_classification_t* res{};
int* res_count{};
status = mmdeploy_classifier_apply(classifier, &mat, 1, &res, &res_count);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to apply classifier, code: %d\n", (int)status);
return 1;
}
for (int i = 0; i < res_count[0]; ++i) {
fprintf(stderr, "label: %d, score: %.4f\n", res[i].label_id, res[i].score);
}
mmdeploy_classifier_release_result(res, res_count, 1);
mmdeploy_classifier_destroy(classifier);
return 0;
}
// Copyright (c) OpenMMLab. All rights reserved.
#include <fstream>
#include <opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <string>
#include "mmdeploy/restorer.h"
int main(int argc, char* argv[]) {
if (argc != 4) {
fprintf(stderr, "usage:\n image_restorer device_name model_path image_path\n");
return 1;
}
auto device_name = argv[1];
auto model_path = argv[2];
auto image_path = argv[3];
cv::Mat img = cv::imread(image_path);
if (!img.data) {
fprintf(stderr, "failed to load image: %s\n", image_path);
return 1;
}
mmdeploy_restorer_t restorer{};
int status{};
status = mmdeploy_restorer_create_by_path(model_path, device_name, 0, &restorer);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to create restorer, code: %d\n", (int)status);
return 1;
}
mmdeploy_mat_t mat{
img.data, img.rows, img.cols, 3, MMDEPLOY_PIXEL_FORMAT_BGR, MMDEPLOY_DATA_TYPE_UINT8};
mmdeploy_mat_t* result{};
status = mmdeploy_restorer_apply(restorer, &mat, 1, &result);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to apply restorer, code: %d\n", (int)status);
return 1;
}
cv::Mat sr_img(result->height, result->width, CV_8UC3, result->data);
cv::cvtColor(sr_img, sr_img, cv::COLOR_RGB2BGR);
cv::imwrite("output_restorer.bmp", sr_img);
mmdeploy_restorer_release_result(result, 1);
mmdeploy_restorer_destroy(restorer);
return 0;
}
// Copyright (c) OpenMMLab. All rights reserved.
#include <fstream>
#include <numeric>
#include <opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <random>
#include <string>
#include <vector>
#include "mmdeploy/segmentor.h"
using namespace std;
vector<cv::Vec3b> gen_palette(int num_classes) {
std::mt19937 gen;
std::uniform_int_distribution<ushort> uniform_dist(0, 255);
vector<cv::Vec3b> palette;
palette.reserve(num_classes);
for (auto i = 0; i < num_classes; ++i) {
palette.emplace_back(uniform_dist(gen), uniform_dist(gen), uniform_dist(gen));
}
return palette;
}
int main(int argc, char* argv[]) {
if (argc != 4) {
fprintf(stderr, "usage:\n image_segmentation device_name model_path image_path\n");
return 1;
}
auto device_name = argv[1];
auto model_path = argv[2];
auto image_path = argv[3];
cv::Mat img = cv::imread(image_path);
if (!img.data) {
fprintf(stderr, "failed to load image: %s\n", image_path);
return 1;
}
mmdeploy_segmentor_t segmentor{};
int status{};
status = mmdeploy_segmentor_create_by_path(model_path, device_name, 0, &segmentor);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to create segmentor, code: %d\n", (int)status);
return 1;
}
mmdeploy_mat_t mat{
img.data, img.rows, img.cols, 3, MMDEPLOY_PIXEL_FORMAT_BGR, MMDEPLOY_DATA_TYPE_UINT8};
mmdeploy_segmentation_t* result{};
status = mmdeploy_segmentor_apply(segmentor, &mat, 1, &result);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to apply segmentor, code: %d\n", (int)status);
return 1;
}
auto palette = gen_palette(result->classes + 1);
cv::Mat color_mask = cv::Mat::zeros(result->height, result->width, CV_8UC3);
int pos = 0;
int total = color_mask.rows * color_mask.cols;
std::vector<int> idxs(result->classes);
for (auto iter = color_mask.begin<cv::Vec3b>(); iter != color_mask.end<cv::Vec3b>(); ++iter) {
// output mask
if (result->mask) {
*iter = palette[result->mask[pos++]];
}
// output score
if (result->score) {
std::iota(idxs.begin(), idxs.end(), 0);
auto k =
std::max_element(idxs.begin(), idxs.end(),
[&](int i, int j) {
return result->score[i * total + pos] < result->score[j * total + pos];
}) -
idxs.begin();
*iter = palette[k];
pos += 1;
}
}
img = img * 0.5 + color_mask * 0.5;
cv::imwrite("output_segmentation.png", img);
mmdeploy_segmentor_release_result(result, 1);
mmdeploy_segmentor_destroy(segmentor);
return 0;
}
#include <fstream>
#include <opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <string>
#include "mmdeploy/detector.h"
int main(int argc, char* argv[]) {
if (argc != 4) {
fprintf(stderr, "usage:\n object_detection device_name model_path image_path\n");
return 1;
}
auto device_name = argv[1];
auto model_path = argv[2];
auto image_path = argv[3];
cv::Mat img = cv::imread(image_path);
if (!img.data) {
fprintf(stderr, "failed to load image: %s\n", image_path);
return 1;
}
cv::Size img_size = img.size();
mmdeploy_detector_t detector{};
int status{};
status = mmdeploy_detector_create_by_path(model_path, device_name, 0, &detector);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to create detector, code: %d\n", (int)status);
return 1;
}
mmdeploy_mat_t mat{
img.data, img.rows, img.cols, 3, MMDEPLOY_PIXEL_FORMAT_BGR, MMDEPLOY_DATA_TYPE_UINT8};
mmdeploy_detection_t* bboxes{};
int* res_count{};
status = mmdeploy_detector_apply(detector, &mat, 1, &bboxes, &res_count);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to apply detector, code: %d\n", (int)status);
return 1;
}
fprintf(stdout, "bbox_count=%d\n", *res_count);
for (int i = 0; i < *res_count; ++i) {
const auto& box = bboxes[i].bbox;
const auto& mask = bboxes[i].mask;
fprintf(stdout, "box %d, left=%.2f, top=%.2f, right=%.2f, bottom=%.2f, label=%d, score=%.4f\n",
i, box.left, box.top, box.right, box.bottom, bboxes[i].label_id, bboxes[i].score);
// skip detections with invalid bbox size (bbox height or width < 1)
if ((box.right - box.left) < 1 || (box.bottom - box.top) < 1) {
continue;
}
// skip detections less than specified score threshold
if (bboxes[i].score < 0.3) {
continue;
}
// generate mask overlay if model exports masks
if (mask != nullptr) {
fprintf(stdout, "mask %d, height=%d, width=%d\n", i, mask->height, mask->width);
// split the RGB channels, overlay mask to a specific color channel
cv::Mat ch[3], mask_img;
int col = 0; // int col = i % 3;
split(img, ch);
cv::Mat imgMask(mask->height, mask->width, CV_8UC1, &mask->data[0]);
// rtmdet-inst
if (img_size.height == mask->height && img_size.width == mask->width) {
mask_img = ch[col];
}
else {
auto x0 = std::max(std::floor(box.left) - 1, 0.f);
auto y0 = std::max(std::floor(box.top) - 1, 0.f);
cv::Rect roi((int)x0, (int)y0, mask->width, mask->height);
mask_img = ch[col](roi);
}
cv::bitwise_or(imgMask, mask_img, mask_img);
merge(ch, 3, img);
}
cv::rectangle(img, cv::Point{(int)box.left, (int)box.top},
cv::Point{(int)box.right, (int)box.bottom}, cv::Scalar{0, 255, 0});
}
cv::imwrite("output_detection.png", img);
mmdeploy_detector_release_result(bboxes, res_count, 1);
mmdeploy_detector_destroy(detector);
return 0;
}
#include <fstream>
#include <opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <string>
#include "mmdeploy/text_detector.h"
#include "mmdeploy/text_recognizer.h"
int main(int argc, char* argv[]) {
if (argc != 5) {
fprintf(stderr, "usage:\n ocr device_name det_model_path reg_model_path image_path\n");
return 1;
}
auto device_name = argv[1];
auto det_model_path = argv[2];
auto reg_model_path = argv[3];
auto image_path = argv[4];
cv::Mat img = cv::imread(image_path);
if (!img.data) {
fprintf(stderr, "failed to load image: %s\n", image_path);
return 1;
}
mmdeploy_text_detector_t text_detector{};
int status{};
status = mmdeploy_text_detector_create_by_path(det_model_path, device_name, 0, &text_detector);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to create text_detector, code: %d\n", (int)status);
return 1;
}
mmdeploy_text_recognizer_t text_recognizer{};
status =
mmdeploy_text_recognizer_create_by_path(reg_model_path, device_name, 0, &text_recognizer);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to create text_recognizer, code: %d\n", (int)status);
return 1;
}
mmdeploy_mat_t mat{
img.data, img.rows, img.cols, 3, MMDEPLOY_PIXEL_FORMAT_BGR, MMDEPLOY_DATA_TYPE_UINT8};
mmdeploy_text_detection_t* bboxes{};
int* bbox_count{};
status = mmdeploy_text_detector_apply(text_detector, &mat, 1, &bboxes, &bbox_count);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to apply text_detector, code: %d\n", (int)status);
return 1;
}
fprintf(stdout, "bbox_count=%d\n", *bbox_count);
mmdeploy_text_recognition_t* texts{};
status =
mmdeploy_text_recognizer_apply_bbox(text_recognizer, &mat, 1, bboxes, bbox_count, &texts);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to apply text_recognizer, code: %d\n", (int)status);
return 1;
}
for (int i = 0; i < *bbox_count; ++i) {
fprintf(stdout, "box[%d]: %s\n", i, texts[i].text);
std::vector<cv::Point> poly_points;
for (int j = 0; j < 4; ++j) {
auto const& pt = bboxes[i].bbox[j];
fprintf(stdout, "x: %.2f, y: %.2f, ", pt.x, pt.y);
poly_points.push_back({(int)pt.x, (int)pt.y});
}
fprintf(stdout, "\n");
cv::polylines(img, poly_points, true, cv::Scalar{0, 255, 0});
}
cv::imwrite("output_ocr.png", img);
mmdeploy_text_recognizer_release_result(texts, *bbox_count);
mmdeploy_text_recognizer_destroy(text_recognizer);
mmdeploy_text_detector_release_result(bboxes, bbox_count, 1);
mmdeploy_text_detector_destroy(text_detector);
return 0;
}
#include <fstream>
#include <iostream>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <string>
#include "mmdeploy/pose_detector.h"
int main(int argc, char *argv[]) {
if (argc != 4) {
fprintf(stderr, "usage:\n pose_detection device_name model_path image_path\n");
return 1;
}
auto device_name = argv[1];
auto model_path = argv[2];
auto image_path = argv[3];
cv::Mat img = cv::imread(image_path);
if (!img.data) {
fprintf(stderr, "failed to load image: %s\n", image_path);
return 1;
}
mmdeploy_pose_detector_t pose_detector{};
int status{};
status = mmdeploy_pose_detector_create_by_path(model_path, device_name, 0, &pose_detector);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to create pose_estimator, code: %d\n", (int)status);
return 1;
}
mmdeploy_mat_t mat{
img.data, img.rows, img.cols, 3, MMDEPLOY_PIXEL_FORMAT_BGR, MMDEPLOY_DATA_TYPE_UINT8};
mmdeploy_pose_detection_t *res{};
status = mmdeploy_pose_detector_apply(pose_detector, &mat, 1, &res);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to apply pose estimator, code: %d\n", (int)status);
return 1;
}
for (int i = 0; i < res->length; i++) {
cv::circle(img, {(int)res->point[i].x, (int)res->point[i].y}, 1, {0, 255, 0}, 2);
}
cv::imwrite("output_pose.png", img);
mmdeploy_pose_detector_release_result(res, 1);
mmdeploy_pose_detector_destroy(pose_detector);
return 0;
}
#include <fstream>
#include <iostream>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <string>
#include "mmdeploy/rotated_detector.h"
int main(int argc, char *argv[]) {
if (argc != 4) {
fprintf(stderr, "usage:\n oriented_object_detection device_name model_path image_path\n");
return 1;
}
auto device_name = argv[1];
auto model_path = argv[2];
auto image_path = argv[3];
cv::Mat img = cv::imread(image_path);
if (!img.data) {
fprintf(stderr, "failed to load image: %s\n", image_path);
return 1;
}
mmdeploy_rotated_detector_t detector{};
int status{};
status = mmdeploy_rotated_detector_create_by_path(model_path, device_name, 0, &detector);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to create rotated detector, code: %d\n", (int)status);
return 1;
}
mmdeploy_mat_t mat{
img.data, img.rows, img.cols, 3, MMDEPLOY_PIXEL_FORMAT_BGR, MMDEPLOY_DATA_TYPE_UINT8};
mmdeploy_rotated_detection_t *rbboxes{};
int *res_count{};
status = mmdeploy_rotated_detector_apply(detector, &mat, 1, &rbboxes, &res_count);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to apply rotated detector, code: %d\n", (int)status);
return 1;
}
for (int i = 0; i < *res_count; ++i) {
// skip low score
if (rbboxes[i].score < 0.1) {
continue;
}
const auto &rbbox = rbboxes[i].rbbox;
float xc = rbbox[0];
float yc = rbbox[1];
float w = rbbox[2];
float h = rbbox[3];
float ag = rbbox[4];
float wx = w / 2 * std::cos(ag);
float wy = w / 2 * std::sin(ag);
float hx = -h / 2 * std::sin(ag);
float hy = h / 2 * std::cos(ag);
cv::Point p1 = {int(xc - wx - hx), int(yc - wy - hy)};
cv::Point p2 = {int(xc + wx - hx), int(yc + wy - hy)};
cv::Point p3 = {int(xc + wx + hx), int(yc + wy + hy)};
cv::Point p4 = {int(xc - wx + hx), int(yc - wy + hy)};
cv::drawContours(img, std::vector<std::vector<cv::Point>>{{p1, p2, p3, p4}}, -1, {0, 255, 0},
2);
}
cv::imwrite("output_rotated_detection.png", img);
mmdeploy_rotated_detector_release_result(rbboxes, res_count);
mmdeploy_rotated_detector_destroy(detector);
return 0;
}
#include <fstream>
#include <map>
#include <opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/videoio.hpp>
#include <set>
#include <string>
#include <vector>
#include "mmdeploy/video_recognizer.h"
void SampleFrames(const char* video_path, std::map<int, cv::Mat>& buffer,
std::vector<mmdeploy_mat_t>& clips, int clip_len, int frame_interval = 1,
int num_clips = 1) {
cv::VideoCapture cap = cv::VideoCapture(video_path);
if (!cap.isOpened()) {
fprintf(stderr, "failed to load video: %s\n", video_path);
exit(1);
}
int num_frames = cap.get(cv::CAP_PROP_FRAME_COUNT);
printf("num_frames %d\n", num_frames);
int ori_clip_len = clip_len * frame_interval;
float avg_interval = (num_frames - ori_clip_len + 1.f) / num_clips;
std::vector<int> frame_inds;
for (int i = 0; i < num_clips; i++) {
int clip_offset = i * avg_interval + avg_interval / 2.0;
for (int j = 0; j < clip_len; j++) {
int ind = (j * frame_interval + clip_offset) % num_frames;
if (num_frames <= ori_clip_len - 1) {
ind = j % num_frames;
}
frame_inds.push_back(ind);
}
}
std::vector<int> unique_inds(frame_inds.begin(), frame_inds.end());
std::sort(unique_inds.begin(), unique_inds.end());
auto last = std::unique(unique_inds.begin(), unique_inds.end());
unique_inds.erase(last, unique_inds.end());
int ind = 0;
for (int i = 0; i < unique_inds.size(); i++) {
int tid = unique_inds[i];
cv::Mat frame;
while (ind < tid) {
cap.read(frame);
ind++;
}
cap.read(frame);
buffer[tid] = frame;
ind++;
}
clips.resize(frame_inds.size());
for (int i = 0; i < frame_inds.size(); i++) {
auto& img = buffer[frame_inds[i]];
mmdeploy_mat_t mat{
img.data, img.rows, img.cols, 3, MMDEPLOY_PIXEL_FORMAT_BGR, MMDEPLOY_DATA_TYPE_UINT8};
clips[i] = mat;
}
}
int main(int argc, char* argv[]) {
if (argc != 7) {
fprintf(stderr,
"usage:\n video_recognition device_name dump_model_directory video_path clip_len "
"frame_interval num_clips \n");
return 1;
}
auto device_name = argv[1];
auto model_path = argv[2];
auto video_path = argv[3];
int clip_len = std::stoi(argv[4]);
int frame_interval = std::stoi(argv[5]);
int num_clips = std::stoi(argv[6]);
std::map<int, cv::Mat> buffer;
std::vector<mmdeploy_mat_t> clips;
std::vector<mmdeploy_video_sample_info_t> clip_info;
SampleFrames(video_path, buffer, clips, clip_len, frame_interval, num_clips);
clip_info.push_back({clip_len, num_clips});
mmdeploy_video_recognizer_t recognizer{};
int status{};
status = mmdeploy_video_recognizer_create_by_path(model_path, device_name, 0, &recognizer);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to create recognizer, code: %d\n", (int)status);
return 1;
}
mmdeploy_video_recognition_t* res{};
int* res_count{};
status = mmdeploy_video_recognizer_apply(recognizer, clips.data(), clip_info.data(), 1, &res,
&res_count);
if (status != MMDEPLOY_SUCCESS) {
fprintf(stderr, "failed to apply classifier, code: %d\n", (int)status);
return 1;
}
for (int i = 0; i < res_count[0]; ++i) {
fprintf(stderr, "label: %d, score: %.4f\n", res[i].label_id, res[i].score);
}
mmdeploy_video_recognizer_release_result(res, res_count, 1);
mmdeploy_video_recognizer_destroy(recognizer);
return 0;
}
#include "mmdeploy/classifier.hpp"
#include "opencv2/imgcodecs/imgcodecs.hpp"
#include "utils/argparse.h"
#include "utils/visualize.h"
DEFINE_ARG_string(model, "Model path");
DEFINE_ARG_string(image, "Input image path");
DEFINE_string(device, "cpu", R"(Device name, e.g. "cpu", "cuda")");
DEFINE_string(output, "classifier_output.jpg", "Output image path");
int main(int argc, char* argv[]) {
if (!utils::ParseArguments(argc, argv)) {
return -1;
}
cv::Mat img = cv::imread(ARGS_image);
if (img.empty()) {
fprintf(stderr, "failed to load image: %s\n", ARGS_image.c_str());
return -1;
}
mmdeploy::Profiler profiler("/tmp/profile.bin");
mmdeploy::Context context;
context.Add(mmdeploy::Device(FLAGS_device));
context.Add(profiler);
// construct a classifier instance
mmdeploy::Classifier classifier(mmdeploy::Model{ARGS_model}, context);
// warmup
for (int i = 0; i < 20; ++i) {
classifier.Apply(img);
}
// apply the classifier; the result is an array-like class holding references to
// `mmdeploy_classification_t`, will be released automatically on destruction
mmdeploy::Classifier::Result result = classifier.Apply(img);
// visualize results
utils::Visualize v;
auto sess = v.get_session(img);
int count = 0;
for (const mmdeploy_classification_t& cls : result) {
sess.add_label(cls.label_id, cls.score, count++);
}
if (!FLAGS_output.empty()) {
cv::imwrite(FLAGS_output, sess.get());
}
return 0;
}
// Copyright (c) OpenMMLab. All rights reserved.
#include <iostream>
#include "mmdeploy/detector.hpp"
#include "mmdeploy/pose_detector.hpp"
#include "opencv2/imgcodecs/imgcodecs.hpp"
#include "utils/argparse.h"
#include "utils/visualize.h"
DEFINE_ARG_string(det_model, "Object detection model path");
DEFINE_ARG_string(pose_model, "Pose estimation model path");
DEFINE_ARG_string(image, "Input image path");
DEFINE_string(device, "cpu", R"(Device name, e.g. "cpu", "cuda")");
DEFINE_string(output, "det_pose_output.jpg", "Output image path");
DEFINE_string(skeleton, "coco", R"(Path to skeleton data or name of predefined skeletons: "coco")");
DEFINE_int32(det_label, 0, "Detection label use for pose estimation");
DEFINE_double(det_thr, .5, "Detection score threshold");
DEFINE_double(det_min_bbox_size, -1, "Detection minimum bbox size");
DEFINE_double(pose_thr, 0, "Pose key-point threshold");
int main(int argc, char* argv[]) {
if (!utils::ParseArguments(argc, argv)) {
return -1;
}
cv::Mat img = cv::imread(ARGS_image);
if (img.empty()) {
fprintf(stderr, "failed to load image: %s\n", ARGS_image.c_str());
return -1;
}
mmdeploy::Device device{FLAGS_device};
// create object detector
mmdeploy::Detector detector(mmdeploy::Model(ARGS_det_model), device);
// create pose detector
mmdeploy::PoseDetector pose(mmdeploy::Model(ARGS_pose_model), device);
// apply the detector, the result is an array-like class holding references to
// `mmdeploy_detection_t`, will be released automatically on destruction
mmdeploy::Detector::Result dets = detector.Apply(img);
// filter detections and extract bboxes for pose model
std::vector<mmdeploy_rect_t> bboxes;
for (const mmdeploy_detection_t& det : dets) {
if (det.label_id == FLAGS_det_label && det.score > FLAGS_det_thr) {
bboxes.push_back(det.bbox);
}
}
// apply pose detector, if no bboxes are provided, full image will be used; the result is an
// array-like class holding references to `mmdeploy_pose_detection_t`, will be released
// automatically on destruction
mmdeploy::PoseDetector::Result poses = pose.Apply(img, bboxes);
assert(bboxes.size() == poses.size());
// visualize results
utils::Visualize v;
v.set_skeleton(utils::Skeleton::get(FLAGS_skeleton));
auto sess = v.get_session(img);
for (size_t i = 0; i < bboxes.size(); ++i) {
sess.add_bbox(bboxes[i], -1, -1);
sess.add_pose(poses[i].point, poses[i].score, poses[i].length, FLAGS_pose_thr);
}
if (!FLAGS_output.empty()) {
cv::imwrite(FLAGS_output, sess.get());
}
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment