yolov5 - 生成动态库
·
作为刚学习动态库的新手抑或是c++还未入门的菜狗(Me)来说,Linux编写动态库入门简单,无需复杂操作,因为Linux下gcc编译的执行文件默认是ELF格式,无需初始化入口,也无需对函数做特别声明,编写方便。
话不多说,直接上示例:
c++上机代码
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/dnn/dnn.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <vector>
std::vector<std::string> CLASSES = { "occlusion" };
std::vector<int> nms(cv::Mat& dets, float thresh) {
...
return keep;
}
cv::Mat xywh2xyxy(cv::Mat x) {
...
return y;
}
cv::Mat filter_box(cv::Mat org_box, float conf_thres, float iou_thres) {
...
return output;
}
void draw(cv::Mat& image, cv::Mat& box_data) {
for (int i = 0; i < box_data.rows; i++) {
int left = box_data.at<float>(i, 0);
int top = box_data.at<float>(i, 1);
int right = box_data.at<float>(i, 2);
int bottom = box_data.at<float>(i, 3);
float score = box_data.at<float>(i, 4);
int cls = static_cast<int>(box_data.at<float>(i, 5));
std::cout << "class: " << CLASSES[cls] << ", score: " << score << std::endl;
std::cout << "box coordinate left,top,right,down: [" << left << ", " << top << ", " << right << ", " << bottom << "]" << std::endl;
cv::rectangle(image, cv::Point(left, top), cv::Point(right, bottom), cv::Scalar(255, 0, 0), 2);
cv::putText(image, CLASSES[cls] + " " + std::to_string(score), cv::Point(left, top - 10), cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(0, 0, 255), 2);
}
}
int main() {
cv::dnn::Net net = cv::dnn::readNetFromONNX("/home/fortune/program_csj/idcard/best.onnx");
cv::Mat img = cv::imread("/home/fortune/program_csj/idcard/1.bmp");
cv::resize(img, img, cv::Size(640, 640));
cv::Mat blob = cv::dnn::blobFromImage(img, 1 / 255.0, cv::Size(640, 640), cv::Scalar(0, 0, 0), true, false);
net.setInput(blob);
cv::Mat detection = net.forward();
cv::Mat filtered_boxes = filter_box(detection, 0.25, 0.45);
draw(img, filtered_boxes);
cv::imshow("Detection Result", img);
cv::waitKey(0);
return 0;
}
由于我的代码由函数组成,所以为了创建动态库,首先创建一个新的类来封装这些函数。在类中定义这些函数作为类的成员函数。
将原本的全局变量转换为类的成员变量,如果有多个函数共享某个变量,将其定义为私有成员变量,并通过公有成员函数来访问和修改。
将原本的函数调用转换为类内部的函数调用,确保函数之间的逻辑关系正常。
如果有全局函数,可以将其转换为静态成员函数或者非成员函数,以便在类外直接调用。
封装后的代码:
#pragma once
#include "/home/fortune/program_csj/Encapsulation/pch.h"
ObjectDetector::ObjectDetector(const std::string& modelPath) {
net_ = cv::dnn::readNetFromONNX(modelPath);
classes_ = { "occlusion" };
}
void ObjectDetector::detectObjects(cv::Mat& image, float confThres, float iouThres) {
cv::Mat blob = cv::dnn::blobFromImage(image, 1 / 255.0, cv::Size(640, 640), cv::Scalar(0, 0, 0), true, false);
net_.setInput(blob);
cv::Mat detection = net_.forward();
cv::Mat filteredBoxes = filterBox(detection, confThres, iouThres);
drawBoxes(image, filteredBoxes);
}
cv::dnn::Net net_;
std::vector<std::string> classes_;
std::vector<int> nms(cv::Mat& dets, float thresh) {
...
return keep;
}
cv::Mat xywh2xyxy(cv::Mat x) {
...
return y;
}
cv::Mat filterBox(cv::Mat orgBox, float confThres, float iouThres) {
...
}
return output;
}
void drawBoxes(cv::Mat& image, cv::Mat& box_data)
{
for (int i = 0; i < box_data.rows; i++)
{
int left = box_data.at<float>(i, 0);
int top = box_data.at<float>(i, 1);
int right = box_data.at<float>(i, 2);
int bottom = box_data.at<float>(i, 3);
float score = box_data.at<float>(i, 4);
int cls = static_cast<int>(box_data.at<float>(i, 5));
std::cout << "class: " << classes_[cls] << ", score: " << score << std::endl;
std::cout << "box coordinate left,top,right,down: [" << left << ", " << top << ", " << right << ", " << bottom << "]" << std::endl;
cv::rectangle(image, cv::Point(left, top), cv::Point(right, bottom), cv::Scalar(255, 0, 0), 2);
cv::putText(image, classes_[cls] + " " + std::to_string(score), cv::Point(left, top - 10), cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar(0, 0, 255), 2);
}
}
int main() {
ObjectDetector detector("/home/fortune/program_csj/encapsulation/best.onnx");
cv::Mat img = cv::imread("/home/fortune/program_csj/encapsulation/1.bmp");
cv::resize(img, img, cv::Size(640, 640));
detector.detectObjects(img, 0.25, 0.45);
cv::imshow("Detection Result", img);
cv::waitKey(0);
return 0;
}
生成动态库
首先,生成目标文件
- g++ -fPIC -C pch.cpp
-fPIC 创建与地址无关的编译程序,以实现在多个应用程序中共享。
然后生成动态库,此时要加上链接器选项-shared
-
g++ -shared -o libpch.so pch.o
-shared 指定生成动态链接库 g++: 是 GNU 编译器集合中的 C++ 编译器。 -shared: 表示生成一个共享库。 -o libpch.so: 指定生成的共享库的名称为 libpch.so, 注意名称以lib开头。 pch.o: 是需要链接的目标文件,这里是指定了一个名为 pch.o 的目标文件。
上述两个命令亦可合并为;
- g++ -fPIC -shared -o libpch.so pch.cpp
至此,动态库生成完毕。
更多推荐


所有评论(0)