18
#if defined(USE_NCNN_SIMPLEOCV)
21
#include <opencv2/core/core.hpp>
22
#include <opencv2/highgui/highgui.hpp>
23
#include <opencv2/imgproc/imgproc.hpp>
32
const T& clamp(const T& v, const T& lo, const T& hi)
35
return v < lo ? lo : hi < v ? hi : v;
40
cv::Rect_<float> rect;
45
static int detect_mobilenetv3(const cv::Mat& bgr, std::vector<Object>& objects)
47
ncnn::Net mobilenetv3;
50
mobilenetv3.opt.use_vulkan_compute = true;
54
if (mobilenetv3.load_param("./mobilenetv3_ssdlite_voc.param"))
56
if (mobilenetv3.load_model("./mobilenetv3_ssdlite_voc.bin"))
59
const int target_size = 300;
64
ncnn::Mat in = ncnn::Mat::from_pixels_resize(bgr.data, ncnn::Mat::PIXEL_BGR2RGB, bgr.cols, bgr.rows, target_size, target_size);
66
const float mean_vals[3] = {123.675f, 116.28f, 103.53f};
67
const float norm_vals[3] = {1.0f, 1.0f, 1.0f};
68
in.substract_mean_normalize(mean_vals, norm_vals);
70
ncnn::Extractor ex = mobilenetv3.create_extractor();
72
ex.input("input", in);
75
ex.extract("detection_out", out);
79
for (int i = 0; i < out.h; i++)
81
const float* values = out.row(i);
84
object.label = values[0];
85
object.prob = values[1];
88
float x1 = clamp(values[2] * target_size, 0.f, float(target_size - 1)) / target_size * img_w;
89
float y1 = clamp(values[3] * target_size, 0.f, float(target_size - 1)) / target_size * img_h;
90
float x2 = clamp(values[4] * target_size, 0.f, float(target_size - 1)) / target_size * img_w;
91
float y2 = clamp(values[5] * target_size, 0.f, float(target_size - 1)) / target_size * img_h;
95
object.rect.width = x2 - x1;
96
object.rect.height = y2 - y1;
98
objects.push_back(object);
104
static void draw_objects(const cv::Mat& bgr, const std::vector<Object>& objects)
106
static const char* class_names[] = {"background",
107
"aeroplane", "bicycle", "bird", "boat",
108
"bottle", "bus", "car", "cat", "chair",
109
"cow", "diningtable", "dog", "horse",
110
"motorbike", "person", "pottedplant",
111
"sheep", "sofa", "train", "tvmonitor"
114
cv::Mat image = bgr.clone();
116
for (size_t i = 0; i < objects.size(); i++)
118
if (objects[i].prob > 0.6)
120
const Object& obj = objects[i];
122
fprintf(stderr, "%d = %.5f at %.2f %.2f %.2f x %.2f\n", obj.label, obj.prob,
123
obj.rect.x, obj.rect.y, obj.rect.width, obj.rect.height);
125
cv::rectangle(image, obj.rect, cv::Scalar(255, 0, 0));
128
sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100);
131
cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
134
int y = obj.rect.y - label_size.height - baseLine;
137
if (x + label_size.width > image.cols)
138
x = image.cols - label_size.width;
140
cv::rectangle(image, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)),
141
cv::Scalar(255, 255, 255), -1);
143
cv::putText(image, text, cv::Point(x, y + label_size.height),
144
cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));
148
cv::imshow("image", image);
152
int main(int argc, char** argv)
156
fprintf(stderr, "Usage: %s [imagepath]\n", argv[0]);
160
const char* imagepath = argv[1];
162
cv::Mat m = cv::imread(imagepath, 1);
165
fprintf(stderr, "cv::imread %s failed\n", imagepath);
169
std::vector<Object> objects;
170
detect_mobilenetv3(m, objects);
172
draw_objects(m, objects);