Compare commits

...
10 Commits
Author SHA1 Message Date
sloray 15be04d1f7 OpenCV4 + XMake 2026-03-15 01:42:59 +08:00
xinyang 7770503779 Update README.md 2021-03-16 20:47:23 +08:00
xinyang 5cf1a30ea0 Update README.md 2020-01-02 17:39:08 +08:00
xinyang 7f6e2f4e6e 添加百度网盘链接:部分比赛时相机录制的视频 2019-12-30 12:05:49 +08:00
xinyang 0b1f5ff47f fix bug 2019-10-24 21:48:53 +08:00
xinyang e1eb8b2590 Update README.md 2019-09-18 18:17:16 +08:00
xinyang b24542e97c update README.md 2019-09-09 23:29:48 +08:00
xinyang de94ff2242 Create LICENSE 2019-09-04 13:22:14 +08:00
xinyang d5df7ce7da Update README.md 2019-08-29 15:21:03 +08:00
xinyang ef257b7df0 Add files via upload 2019-08-29 15:18:34 +08:00
17 changed files with 215 additions and 55 deletions
+4 -1
View File
@@ -1,6 +1,9 @@
cmake-build-debug
build
.idea
.xmake
.vscode/.cache
.vscode/compile_commands.json
Mark
armor_box_photo
tools/TrainCNN/.idea
@@ -9,4 +12,4 @@ tools/TrainCNN/__pycache__
others/include/config/config.h
others/MV-UB31-Group0.config
.DS_Store
video
video
+8
View File
@@ -0,0 +1,8 @@
{
"clangd.arguments": [
"--compile-commands-dir=${workspaceFolder}/.vscode",
"--completion-style=detailed",
"--query-driver=/usr/bin/g++,/usr/bin/gcc,/usr/bin/c++",
"--header-insertion=never"
],
}
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 xinyang
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+11 -1
View File
@@ -13,6 +13,12 @@
**如有BUG或者想交流的朋友欢迎积极联系我们**
**分享部分比赛时摄像头录制的视频:**
链接: https://pan.baidu.com/s/1LwxEpeYYblX3cSzb59MTVg 提取码: 84ju 复制这段内容后打开百度网盘手机App,操作更方便哦
---
运行效果:自瞄帧率120(摄像头最大帧率),识别距离根据环境不同大约8米左右(5mm焦距镜头)。
![front](https://github.com/lloi7/SJTU-RM-CV-2019/blob/master/picture0.png)
@@ -24,6 +30,8 @@
| ---------------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------ | ---------------------------------------------------------- |
| IntelNUC<br />MindVision工业相机×1<br />USB转TTL×1 | Ubuntu18.04<br />Ubuntu16.04<br />Windows10 | OpenCV3.4.5<br />OpenCV_contrib3.4.5<br />Eigen3<br />MindVision相机驱动 | Ubuntu18/16 : cmake3+gcc7+g++7 <br />Win10 : cmake3+VS2019 |
MindVision相机型号:MV-UBS31GC
**关于Windows环境下的运行支持,仅保证程序可以编译运行。对与部分辅助功能,如生成自启动脚本则不支持。**
**实际装载在步兵和哨兵上的运行环境为Ubuntu18.04。**
@@ -60,6 +68,8 @@ sudo ./run
```./run --help```可以查看所有命令行参数及其作用。所有调试选项都集成到了命令行参数中。
**不使用任何参数直接运行将没有任何图像显示。**
需要调参的部分:主要需要根据车辆情况而调参的参数存放在others/include/config/setconfig.h中
### 3.工作条件
@@ -118,7 +128,7 @@ sudo ./run
### 1.自瞄装甲板识别方式
​ 首先对图像进行通道拆分以及二值化操作,再进行开闭运算,通过边缘提取和条件限制得出可能为灯条的部分。再对所有可能的灯条进行两两匹配,根据形状大小特性进行筛选,得出可能为装甲板的候选区。然后把所有候选区交给分类器判断,得出真实的装甲板及其数字id。最后根据优先级选取最终击打目标以及后续处理。
​ ![autoaim](https://github.com/lloi7/SJTU-RM-CV-2019/blob/master/自瞄流程图.png)
### 2.能量机关识别方式
​ 首先对图像进行二值化操作,然后进行一定腐蚀和膨胀,通过边缘提取和条件限制得出待击打叶片(锤子形)。在待击打叶片范围内进一步用类似方法寻找目标装甲板和流动条,在二者连线上寻找中心的“R”。根据目标装甲板坐标和中心坐标计算极坐标系下的目标角度,进而预测待击打点的坐标(小符为装甲板本身,大符需要旋转)。最后将待击打点坐标和图像中心的差值转换为yaw和pitch轴角度,增加一环PID后发送给云台主控板。
+1 -1
View File
@@ -9,7 +9,7 @@
#include <systime.h>
#include <constants.h>
#include <opencv2/core.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/tracking/tracking.hpp>
#include <serial.h>
#include <armor_finder/classifier/classifier.h>
#include <additions.h>
+1 -1
View File
@@ -67,7 +67,7 @@ void ArmorFinder::run(cv::Mat &src) {
if ((target_box.rect & cv::Rect2d(0, 0, 640, 480)) == target_box.rect) { // 判断装甲板区域是否脱离图像区域
if (!classifier) { /* 如果分类器不可用 */
cv::Mat roi = src(target_box.rect).clone(), roi_gray; /* 就使用装甲区域亮点数判断是否跟丢 */
cv::cvtColor(roi, roi_gray, CV_RGB2GRAY);
cv::cvtColor(roi, roi_gray, cv::COLOR_RGB2GRAY);
cv::threshold(roi_gray, roi_gray, 180, 255, cv::THRESH_BINARY);
contour_area = cv::countNonZero(roi_gray);
}
@@ -156,6 +156,7 @@ bool ArmorFinder::findArmorBox(const cv::Mat &src, ArmorBox &box) {
for (auto &one_box : armor_boxes) {
if (one_box.id != 0) {
box = one_box;
break;
}
}
if (save_labelled_boxes) {
@@ -83,11 +83,11 @@ bool ArmorFinder::findLightBlobs(const cv::Mat &src, LightBlobs &light_blobs) {
}else{
light_threshold = 200;
}
cv::threshold(color_channel, src_bin_light, light_threshold, 255, CV_THRESH_BINARY); // 二值化对应通道
cv::threshold(color_channel, src_bin_light, light_threshold, 255, cv::THRESH_BINARY); // 二值化对应通道
if (src_bin_light.empty()) return false;
imagePreProcess(src_bin_light); // 开闭运算
cv::threshold(color_channel, src_bin_dim, 140, 255, CV_THRESH_BINARY); // 二值化对应通道
cv::threshold(color_channel, src_bin_dim, 140, 255, cv::THRESH_BINARY); // 二值化对应通道
if (src_bin_dim.empty()) return false;
imagePreProcess(src_bin_dim); // 开闭运算
@@ -100,8 +100,8 @@ bool ArmorFinder::findLightBlobs(const cv::Mat &src, LightBlobs &light_blobs) {
std::vector<std::vector<cv::Point>> light_contours_light, light_contours_dim;
LightBlobs light_blobs_light, light_blobs_dim;
std::vector<cv::Vec4i> hierarchy_light, hierarchy_dim;
cv::findContours(src_bin_light, light_contours_light, hierarchy_light, CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE);
cv::findContours(src_bin_dim, light_contours_dim, hierarchy_dim, CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE);
cv::findContours(src_bin_light, light_contours_light, hierarchy_light, cv::RETR_CCOMP, cv::CHAIN_APPROX_NONE);
cv::findContours(src_bin_dim, light_contours_dim, hierarchy_dim, cv::RETR_CCOMP, cv::CHAIN_APPROX_NONE);
for (int i = 0; i < light_contours_light.size(); i++) {
if (hierarchy_light[i][2] == -1) {
cv::RotatedRect rect = cv::minAreaRect(light_contours_light[i]);
@@ -8,13 +8,13 @@
#include <show_images/show_images.h>
bool ArmorFinder::stateTrackingTarget(cv::Mat &src) {
auto pos = target_box.rect;
cv::Rect pos(target_box.rect);
if(!tracker->update(src, pos)){ // 使用KCFTracker进行追踪
target_box = ArmorBox();
LOGW("Track fail!");
return false;
}
if((pos & cv::Rect2d(0, 0, 640, 480)) != pos){
if((cv::Rect2d(pos) & cv::Rect2d(0, 0, 640, 480)) != cv::Rect2d(pos)){
target_box = ArmorBox();
LOGW("Track out range!");
return false;
@@ -52,7 +52,7 @@ bool ArmorFinder::stateTrackingTarget(cv::Mat &src) {
}
}else{ // 分类器不可用,使用常规方法判断
cv::Mat roi_gray;
cv::cvtColor(roi, roi_gray, CV_RGB2GRAY);
cv::cvtColor(roi, roi_gray, cv::COLOR_RGB2GRAY);
cv::threshold(roi_gray, roi_gray, 180, 255, cv::THRESH_BINARY);
contour_area = cv::countNonZero(roi_gray);
if(abs(cv::countNonZero(roi_gray) - contour_area) > contour_area * 0.3){
+16 -18
View File
@@ -21,12 +21,12 @@ int Energy::findFans(const cv::Mat &src) {
static Mat src_bin;
src_bin = src.clone();
if (src.type() == CV_8UC3) {
cvtColor(src_bin, src_bin, CV_BGR2GRAY);//若读取三通道视频文件,需转换为单通道
cvtColor(src_bin, src_bin, cv::COLOR_BGR2GRAY);//若读取三通道视频文件,需转换为单通道
}
std::vector<vector<Point> > fan_contours;
FanStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找
if (show_process)imshow("fan struct", src_bin);
findContours(src_bin, fan_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
findContours(src_bin, fan_contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
for (auto &fan_contour : fan_contours) {
if (!isValidFanContour(src_bin, fan_contour)) {
@@ -54,16 +54,16 @@ int Energy::findArmors(const cv::Mat &src) {
static Mat src_bin;
src_bin = src.clone();
if (src.type() == CV_8UC3) {
cvtColor(src_bin, src_bin, CV_BGR2GRAY);//若读取三通道视频文件,需转换为单通道
cvtColor(src_bin, src_bin, cv::COLOR_BGR2GRAY);//若读取三通道视频文件,需转换为单通道
}
std::vector<vector<Point> > armor_contours;
std::vector<vector<Point> > armor_contours_external;//用总轮廓减去外轮廓,只保留内轮廓,除去流动条的影响。
ArmorStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找
findContours(src_bin, armor_contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
findContours(src_bin, armor_contours, cv::RETR_LIST, cv::CHAIN_APPROX_NONE);
if (show_process)imshow("armor struct", src_bin);
findContours(src_bin, armor_contours_external, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
findContours(src_bin, armor_contours_external, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
for (int i = 0; i < armor_contours_external.size(); i++)//去除外轮廓
{
unsigned long external_contour_size = armor_contours_external[i].size();
@@ -103,12 +103,12 @@ bool Energy::findCenterR(const cv::Mat &src) {
static Mat src_bin;
src_bin = src.clone();
if (src.type() == CV_8UC3) {
cvtColor(src_bin, src_bin, CV_BGR2GRAY);
cvtColor(src_bin, src_bin, cv::COLOR_BGR2GRAY);
}
std::vector<vector<Point> > center_R_contours;
CenterRStruct(src_bin);
if (show_process)imshow("R struct", src_bin);
findContours(src_bin, center_R_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
findContours(src_bin, center_R_contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
for (auto &center_R_contour : center_R_contours) {
if (!isValidCenterRContour(center_R_contour)) {
continue;
@@ -139,13 +139,13 @@ bool Energy::findFlowStripFan(const cv::Mat &src) {
src_bin = src.clone();
src_copy = src.clone();
if (src.type() == CV_8UC3) {
cvtColor(src_bin, src_bin, CV_BGR2GRAY);//若读取三通道视频文件,需转换为单通道
cvtColor(src_bin, src_bin, cv::COLOR_BGR2GRAY);//若读取三通道视频文件,需转换为单通道
}
std::vector<vector<Point> > flow_strip_fan_contours;
FlowStripFanStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找
if (show_process)imshow("flow strip fan struct", src_bin);
findContours(src_bin, flow_strip_fan_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
findContours(src_bin, flow_strip_fan_contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
std::vector<cv::RotatedRect> candidate_flow_strip_fans;
for (auto &flow_strip_fan_contour : flow_strip_fan_contours) {
@@ -175,7 +175,7 @@ bool Energy::findFlowStrip(const cv::Mat &src) {
if (src_bin.type() == CV_8UC1) // 黑白图像
{
cvtColor(src_bin, src_bin, COLOR_GRAY2RGB);
cvtColor(src_bin, src_bin, cv::COLOR_GRAY2RGB);
}
std::vector<cv::RotatedRect> candidate_target_armors = target_armors;
@@ -189,13 +189,13 @@ bool Energy::findFlowStrip(const cv::Mat &src) {
}
}
cvtColor(src_bin, src_bin, CV_BGR2GRAY);//若读取三通道视频文件,需转换为单通道
cvtColor(src_bin, src_bin, cv::COLOR_BGR2GRAY);//若读取三通道视频文件,需转换为单通道
FlowStripStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找
if (show_process)imshow("flow strip struct", src_bin);
std::vector<vector<Point> > flow_strip_contours;
findContours(src_bin, flow_strip_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
findContours(src_bin, flow_strip_contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
for (auto candidate_flow_strip_fan: flow_strip_fans) {
for (auto &flow_strip_contour : flow_strip_contours) {
@@ -261,7 +261,7 @@ bool Energy::findFlowStripWeak(const cv::Mat &src) {
if (src_bin.type() == CV_8UC1) // 黑白图像
{
cvtColor(src_bin, src_bin, COLOR_GRAY2RGB);
cvtColor(src_bin, src_bin, cv::COLOR_GRAY2RGB);
}
std::vector<cv::RotatedRect> candidate_armors = armors;
@@ -275,13 +275,13 @@ bool Energy::findFlowStripWeak(const cv::Mat &src) {
}
}
cvtColor(src_bin, src_bin, CV_BGR2GRAY);//若读取三通道视频文件,需转换为单通道
cvtColor(src_bin, src_bin, cv::COLOR_BGR2GRAY);//若读取三通道视频文件,需转换为单通道
FlowStripStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找
if (show_process)imshow("weak struct", src_bin);
std::vector<vector<Point> > flow_strip_contours;
findContours(src_bin, flow_strip_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
findContours(src_bin, flow_strip_contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
for (auto &flow_strip_contour : flow_strip_contours) {
if (!isValidFlowStripContour(flow_strip_contour)) {
@@ -335,6 +335,4 @@ bool Energy::findCenterROI(const cv::Mat &src) {
Size2f(length * 1.7, length * 1.7), -90);
return true;
}
}
+3 -3
View File
@@ -6,7 +6,7 @@
#define _CAMERA_WRAPPER_H_
#include <additions.h>
#include <opencv2/core/core.hpp>
#include <opencv2/core.hpp>
#include <camera/wrapper_head.h>
#ifdef Windows
@@ -33,7 +33,7 @@ private:
tSdkCameraCapbility tCapability;
tSdkFrameHead frame_info;
BYTE *pby_buffer;
IplImage* iplImage;
cv::Mat image_header;
int channel;
RoundQueue<cv::Mat, 2> src_queue;
@@ -52,4 +52,4 @@ public:
};
#endif /* _CAMERA_WRAPPER_H_ */
#endif /* _CAMERA_WRAPPER_H_ */
+1
View File
@@ -32,6 +32,7 @@
#include <stdio.h>
#include <systime.h>
#include <iostream>
/************** Define the control code *************/
#define START_CTR "\033[0"
+13 -21
View File
@@ -17,7 +17,6 @@ CameraWrapper::CameraWrapper(int exposure, int gain, int camera_mode, const std:
mode(camera_mode),
camera_cnts(2),
camera_status(-1),
iplImage(nullptr),
rgb_buffer(nullptr),
channel(3),
gain(gain),
@@ -27,9 +26,11 @@ CameraWrapper::CameraWrapper(int exposure, int gain, int camera_mode, const std:
void cameraCallback(CameraHandle hCamera, BYTE *pFrameBuffer, tSdkFrameHead* pFrameHead,PVOID pContext){
CameraWrapper *c = (CameraWrapper*)pContext;
CameraImageProcess(hCamera, pFrameBuffer, c->rgb_buffer, pFrameHead);
auto iplImage = cvCreateImageHeader(cvSize(pFrameHead->iWidth, pFrameHead->iHeight), IPL_DEPTH_8U, c->channel);
cvSetData(iplImage, c->rgb_buffer, pFrameHead->iWidth * c->channel); //此处只是设置指针,无图像块数据拷贝,不需担心转换效率
c->src_queue.push(cv::cvarrToMat(iplImage).clone());
// 使用 cv::Mat 替代 IplImage
cv::Mat img(pFrameHead->iHeight, pFrameHead->iWidth,
c->channel == 3 ? CV_8UC3 : CV_8UC1,
c->rgb_buffer, pFrameHead->iWidth * c->channel);
c->src_queue.push(img.clone());
}
bool CameraWrapper::init() {
@@ -134,15 +135,9 @@ bool CameraWrapper::read(cv::Mat &src) {
bool CameraWrapper::readRaw(cv::Mat &src) {
if (CameraGetImageBuffer(h_camera, &frame_info, &pby_buffer, 500) == CAMERA_STATUS_SUCCESS) {
if (iplImage) {
cvReleaseImageHeader(&iplImage);
}
iplImage = cvCreateImageHeader(cvSize(frame_info.iWidth, frame_info.iHeight), IPL_DEPTH_8U, 1);
cvSetData(iplImage, pby_buffer, frame_info.iWidth); //此处只是设置指针,无图像块数据拷贝,不需担心转换效率
src = cv::cvarrToMat(iplImage).clone();
// 使用 cv::Mat 替代 IplImage
cv::Mat img(frame_info.iHeight, frame_info.iWidth, CV_8UC1, pby_buffer, frame_info.iWidth);
src = img.clone();
//在成功调用CameraGetImageBuffer后,必须调用CameraReleaseImageBuffer来释放获得的buffer。
//否则再次调用CameraGetImageBuffer时,程序将被挂起一直阻塞,直到其他线程中调用CameraReleaseImageBuffer来释放了buffer
@@ -156,16 +151,13 @@ bool CameraWrapper::readRaw(cv::Mat &src) {
}
bool CameraWrapper::readProcessed(cv::Mat &src) {
// cerr << "Get-1" << endl;
if (CameraGetImageBuffer(h_camera, &frame_info, &pby_buffer, 500) == CAMERA_STATUS_SUCCESS) {
CameraImageProcess(h_camera, pby_buffer, rgb_buffer,
&frame_info); // this function is super slow, better not to use it.
if (iplImage) {
cvReleaseImageHeader(&iplImage);
}
iplImage = cvCreateImageHeader(cvSize(frame_info.iWidth, frame_info.iHeight), IPL_DEPTH_8U, channel);
cvSetData(iplImage, rgb_buffer, frame_info.iWidth * channel); //此处只是设置指针,无图像块数据拷贝,不需担心转换效率
src = cv::cvarrToMat(iplImage).clone();
// 使用 cv::Mat 替代 IplImage
int mat_type = (channel == 3) ? CV_8UC3 : CV_8UC1;
cv::Mat img(frame_info.iHeight, frame_info.iWidth, mat_type, rgb_buffer, frame_info.iWidth * channel);
src = img.clone();
//在成功调用CameraGetImageBuffer后,必须调用CameraReleaseImageBuffer来释放获得的buffer。
//否则再次调用CameraGetImageBuffer时,程序将被挂起一直阻塞,直到其他线程中调用CameraReleaseImageBuffer来释放了buffer
CameraReleaseImageBuffer(h_camera, pby_buffer);
@@ -193,4 +185,4 @@ CameraWrapper::~CameraWrapper() {
//注意,先反初始化后再free
if (rgb_buffer != nullptr)
free(rgb_buffer);
}
}
+3 -2
View File
@@ -6,12 +6,13 @@
#include <log.h>
#include <cstring>
#include <map>
#include <string>
bool show_armor_box = false;
bool show_armor_box = true;
bool show_armor_boxes = false;
bool show_light_blobs = false;
bool show_origin = false;
bool run_with_camera = false;
bool run_with_camera = true;
bool save_video = false;
bool wait_uart = false;
bool save_labelled_boxes = false;
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
sudo touch /etc/udev/rules.d/70-ttyusb.rules
+122
View File
@@ -0,0 +1,122 @@
-- 设置项目信息
set_project("SJTU-RM-CV")
set_version("1.0.0")
set_languages("c++17")
-- 设置构建模式
set_rules("mode.release")
set_optimize("fastest")
--导出构建指令
add_rules("plugin.compile_commands.autoupdate", {outputdir = ".vscode"})
-- 定义宏
add_defines('PATH=\"$(projectdir)\"')
add_defines("Linux")
-- 检查是否存在 config.h
if os.isfile("others/include/config/config.h") or os.isfile("others/include/config.h") then
add_defines("WITH_CONFIG")
print("Found config.h")
end
-- 添加依赖
add_requires("eigen", {system = false})
add_requires("pthread")
--- OpenCV 4.6.0 配置(启用 ffmpeg 和 contrib)
add_requires("opencv", {
system = false,
configs = {
ffmpeg = false,
eigen = true,
png = true,
jpeg = true,
webp = false,
tiff = false,
quirc = false,
opengl = false,
protobuf = false,
bundled = true,
gtk = true
}
})
-- 目标配置
target("run")
set_kind("binary")
-- 添加源文件
add_files("main.cpp")
add_files("others/src/*.cpp")
add_files("others/src/camera/*.cpp")
add_files("energy/src/energy/*.cpp")
add_files("energy/src/energy/*/*.cpp")
add_files("armor/src/armor_finder/*.cpp")
add_files("armor/src/armor_finder/*/*.cpp")
add_files("armor/src/show_images/*.cpp")
-- 添加头文件搜索路径
add_includedirs("others/include")
add_includedirs("others/include/camera")
add_includedirs("others/include/config")
add_includedirs("energy/include")
add_includedirs("energy/include/energy")
add_includedirs("armor/include")
add_includedirs("armor/include/armor_finder")
add_includedirs("armor/include/armor_finder/classifier")
add_includedirs("armor/include/show_images")
-- 添加依赖包
add_packages("pthread", "eigen", "opencv")
-- 添加链接目录
add_linkdirs("others")
-- 根据平台链接相机 SDK
if is_plat("linux") then
add_links("MVSDK")
print("current platform: Linux")
elseif is_plat("windows") then
add_links("MVCAMSDK_X64")
print("current platform: Windows")
elseif is_plat("macosx") then
add_links("mvsdk")
print("current platform: Mac")
else
print("Unsupported platform")
end
-- 设置目标目录
set_targetdir("$(builddir)")
-- 添加编译选项
add_cxxflags("-O3")
-- 自定义任务:create-startup
task("create-startup")
set_category("action")
on_run(function ()
os.exec("$(projectdir)/tools/create-startup.sh $(projectdir) $(builddir)")
end)
set_menu {
usage = "xmake create-startup",
description = "Create startup script",
options = {}
}
-- 自定义任务:train-cnn
task("train-cnn")
set_category("action")
on_run(function ()
if os.host() == "linux" then
os.exec("gnome-terminal -- bash -c \"$(projectdir)/tools/TrainCNN/backward.py\"")
else
print("train-cnn only supported on Linux with gnome-terminal")
end
end)
set_menu {
usage = "xmake train-cnn",
description = "Train CNN model",
options = {}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB