OpenCV4 + XMake

This commit is contained in:
2026-03-15 01:42:59 +08:00
parent 7770503779
commit 15be04d1f7
13 changed files with 182 additions and 54 deletions

5
.gitignore vendored
View File

@@ -1,6 +1,9 @@
cmake-build-debug cmake-build-debug
build build
.idea .idea
.xmake
.vscode/.cache
.vscode/compile_commands.json
Mark Mark
armor_box_photo armor_box_photo
tools/TrainCNN/.idea tools/TrainCNN/.idea
@@ -9,4 +12,4 @@ tools/TrainCNN/__pycache__
others/include/config/config.h others/include/config/config.h
others/MV-UB31-Group0.config others/MV-UB31-Group0.config
.DS_Store .DS_Store
video video

8
.vscode/settings.json vendored Normal file
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"
],
}

View File

@@ -9,7 +9,7 @@
#include <systime.h> #include <systime.h>
#include <constants.h> #include <constants.h>
#include <opencv2/core.hpp> #include <opencv2/core.hpp>
#include <opencv2/tracking.hpp> #include <opencv2/tracking/tracking.hpp>
#include <serial.h> #include <serial.h>
#include <armor_finder/classifier/classifier.h> #include <armor_finder/classifier/classifier.h>
#include <additions.h> #include <additions.h>

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 ((target_box.rect & cv::Rect2d(0, 0, 640, 480)) == target_box.rect) { // 判断装甲板区域是否脱离图像区域
if (!classifier) { /* 如果分类器不可用 */ if (!classifier) { /* 如果分类器不可用 */
cv::Mat roi = src(target_box.rect).clone(), roi_gray; /* 就使用装甲区域亮点数判断是否跟丢 */ 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); cv::threshold(roi_gray, roi_gray, 180, 255, cv::THRESH_BINARY);
contour_area = cv::countNonZero(roi_gray); contour_area = cv::countNonZero(roi_gray);
} }

View File

@@ -83,11 +83,11 @@ bool ArmorFinder::findLightBlobs(const cv::Mat &src, LightBlobs &light_blobs) {
}else{ }else{
light_threshold = 200; 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; if (src_bin_light.empty()) return false;
imagePreProcess(src_bin_light); // 开闭运算 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; if (src_bin_dim.empty()) return false;
imagePreProcess(src_bin_dim); // 开闭运算 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; std::vector<std::vector<cv::Point>> light_contours_light, light_contours_dim;
LightBlobs light_blobs_light, light_blobs_dim; LightBlobs light_blobs_light, light_blobs_dim;
std::vector<cv::Vec4i> hierarchy_light, hierarchy_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_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_dim, light_contours_dim, hierarchy_dim, cv::RETR_CCOMP, cv::CHAIN_APPROX_NONE);
for (int i = 0; i < light_contours_light.size(); i++) { for (int i = 0; i < light_contours_light.size(); i++) {
if (hierarchy_light[i][2] == -1) { if (hierarchy_light[i][2] == -1) {
cv::RotatedRect rect = cv::minAreaRect(light_contours_light[i]); cv::RotatedRect rect = cv::minAreaRect(light_contours_light[i]);

View File

@@ -8,13 +8,13 @@
#include <show_images/show_images.h> #include <show_images/show_images.h>
bool ArmorFinder::stateTrackingTarget(cv::Mat &src) { bool ArmorFinder::stateTrackingTarget(cv::Mat &src) {
auto pos = target_box.rect; cv::Rect pos(target_box.rect);
if(!tracker->update(src, pos)){ // 使用KCFTracker进行追踪 if(!tracker->update(src, pos)){ // 使用KCFTracker进行追踪
target_box = ArmorBox(); target_box = ArmorBox();
LOGW("Track fail!"); LOGW("Track fail!");
return false; 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(); target_box = ArmorBox();
LOGW("Track out range!"); LOGW("Track out range!");
return false; return false;
@@ -52,7 +52,7 @@ bool ArmorFinder::stateTrackingTarget(cv::Mat &src) {
} }
}else{ // 分类器不可用,使用常规方法判断 }else{ // 分类器不可用,使用常规方法判断
cv::Mat roi_gray; 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); cv::threshold(roi_gray, roi_gray, 180, 255, cv::THRESH_BINARY);
contour_area = cv::countNonZero(roi_gray); contour_area = cv::countNonZero(roi_gray);
if(abs(cv::countNonZero(roi_gray) - contour_area) > contour_area * 0.3){ if(abs(cv::countNonZero(roi_gray) - contour_area) > contour_area * 0.3){

View File

@@ -21,12 +21,12 @@ int Energy::findFans(const cv::Mat &src) {
static Mat src_bin; static Mat src_bin;
src_bin = src.clone(); src_bin = src.clone();
if (src.type() == CV_8UC3) { 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; std::vector<vector<Point> > fan_contours;
FanStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找 FanStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找
if (show_process)imshow("fan struct", 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) { for (auto &fan_contour : fan_contours) {
if (!isValidFanContour(src_bin, fan_contour)) { if (!isValidFanContour(src_bin, fan_contour)) {
@@ -54,16 +54,16 @@ int Energy::findArmors(const cv::Mat &src) {
static Mat src_bin; static Mat src_bin;
src_bin = src.clone(); src_bin = src.clone();
if (src.type() == CV_8UC3) { 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;
std::vector<vector<Point> > armor_contours_external;//用总轮廓减去外轮廓,只保留内轮廓,除去流动条的影响。 std::vector<vector<Point> > armor_contours_external;//用总轮廓减去外轮廓,只保留内轮廓,除去流动条的影响。
ArmorStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找 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); 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++)//去除外轮廓 for (int i = 0; i < armor_contours_external.size(); i++)//去除外轮廓
{ {
unsigned long external_contour_size = armor_contours_external[i].size(); 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; static Mat src_bin;
src_bin = src.clone(); src_bin = src.clone();
if (src.type() == CV_8UC3) { 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; std::vector<vector<Point> > center_R_contours;
CenterRStruct(src_bin); CenterRStruct(src_bin);
if (show_process)imshow("R struct", 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) { for (auto &center_R_contour : center_R_contours) {
if (!isValidCenterRContour(center_R_contour)) { if (!isValidCenterRContour(center_R_contour)) {
continue; continue;
@@ -139,13 +139,13 @@ bool Energy::findFlowStripFan(const cv::Mat &src) {
src_bin = src.clone(); src_bin = src.clone();
src_copy = src.clone(); src_copy = src.clone();
if (src.type() == CV_8UC3) { 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; std::vector<vector<Point> > flow_strip_fan_contours;
FlowStripFanStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找 FlowStripFanStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找
if (show_process)imshow("flow strip fan struct", 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; std::vector<cv::RotatedRect> candidate_flow_strip_fans;
for (auto &flow_strip_fan_contour : flow_strip_fan_contours) { 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) // 黑白图像 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; 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);//图像膨胀,防止图像断开并更方便寻找 FlowStripStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找
if (show_process)imshow("flow strip struct", src_bin); if (show_process)imshow("flow strip struct", src_bin);
std::vector<vector<Point> > flow_strip_contours; 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 candidate_flow_strip_fan: flow_strip_fans) {
for (auto &flow_strip_contour : flow_strip_contours) { 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) // 黑白图像 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; 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);//图像膨胀,防止图像断开并更方便寻找 FlowStripStruct(src_bin);//图像膨胀,防止图像断开并更方便寻找
if (show_process)imshow("weak struct", src_bin); if (show_process)imshow("weak struct", src_bin);
std::vector<vector<Point> > flow_strip_contours; 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) { for (auto &flow_strip_contour : flow_strip_contours) {
if (!isValidFlowStripContour(flow_strip_contour)) { if (!isValidFlowStripContour(flow_strip_contour)) {
@@ -335,6 +335,4 @@ bool Energy::findCenterROI(const cv::Mat &src) {
Size2f(length * 1.7, length * 1.7), -90); Size2f(length * 1.7, length * 1.7), -90);
return true; return true;
} }

View File

@@ -6,7 +6,7 @@
#define _CAMERA_WRAPPER_H_ #define _CAMERA_WRAPPER_H_
#include <additions.h> #include <additions.h>
#include <opencv2/core/core.hpp> #include <opencv2/core.hpp>
#include <camera/wrapper_head.h> #include <camera/wrapper_head.h>
#ifdef Windows #ifdef Windows
@@ -33,7 +33,7 @@ private:
tSdkCameraCapbility tCapability; tSdkCameraCapbility tCapability;
tSdkFrameHead frame_info; tSdkFrameHead frame_info;
BYTE *pby_buffer; BYTE *pby_buffer;
IplImage* iplImage; cv::Mat image_header;
int channel; int channel;
RoundQueue<cv::Mat, 2> src_queue; RoundQueue<cv::Mat, 2> src_queue;
@@ -52,4 +52,4 @@ public:
}; };
#endif /* _CAMERA_WRAPPER_H_ */ #endif /* _CAMERA_WRAPPER_H_ */

View File

@@ -32,6 +32,7 @@
#include <stdio.h> #include <stdio.h>
#include <systime.h> #include <systime.h>
#include <iostream>
/************** Define the control code *************/ /************** Define the control code *************/
#define START_CTR "\033[0" #define START_CTR "\033[0"

View File

@@ -17,7 +17,6 @@ CameraWrapper::CameraWrapper(int exposure, int gain, int camera_mode, const std:
mode(camera_mode), mode(camera_mode),
camera_cnts(2), camera_cnts(2),
camera_status(-1), camera_status(-1),
iplImage(nullptr),
rgb_buffer(nullptr), rgb_buffer(nullptr),
channel(3), channel(3),
gain(gain), 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){ void cameraCallback(CameraHandle hCamera, BYTE *pFrameBuffer, tSdkFrameHead* pFrameHead,PVOID pContext){
CameraWrapper *c = (CameraWrapper*)pContext; CameraWrapper *c = (CameraWrapper*)pContext;
CameraImageProcess(hCamera, pFrameBuffer, c->rgb_buffer, pFrameHead); CameraImageProcess(hCamera, pFrameBuffer, c->rgb_buffer, pFrameHead);
auto iplImage = cvCreateImageHeader(cvSize(pFrameHead->iWidth, pFrameHead->iHeight), IPL_DEPTH_8U, c->channel); // 使用 cv::Mat 替代 IplImage
cvSetData(iplImage, c->rgb_buffer, pFrameHead->iWidth * c->channel); //此处只是设置指针,无图像块数据拷贝,不需担心转换效率 cv::Mat img(pFrameHead->iHeight, pFrameHead->iWidth,
c->src_queue.push(cv::cvarrToMat(iplImage).clone()); c->channel == 3 ? CV_8UC3 : CV_8UC1,
c->rgb_buffer, pFrameHead->iWidth * c->channel);
c->src_queue.push(img.clone());
} }
bool CameraWrapper::init() { bool CameraWrapper::init() {
@@ -134,15 +135,9 @@ bool CameraWrapper::read(cv::Mat &src) {
bool CameraWrapper::readRaw(cv::Mat &src) { bool CameraWrapper::readRaw(cv::Mat &src) {
if (CameraGetImageBuffer(h_camera, &frame_info, &pby_buffer, 500) == CAMERA_STATUS_SUCCESS) { if (CameraGetImageBuffer(h_camera, &frame_info, &pby_buffer, 500) == CAMERA_STATUS_SUCCESS) {
if (iplImage) { // 使用 cv::Mat 替代 IplImage
cvReleaseImageHeader(&iplImage); cv::Mat img(frame_info.iHeight, frame_info.iWidth, CV_8UC1, pby_buffer, frame_info.iWidth);
} src = img.clone();
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();
//在成功调用CameraGetImageBuffer后必须调用CameraReleaseImageBuffer来释放获得的buffer。 //在成功调用CameraGetImageBuffer后必须调用CameraReleaseImageBuffer来释放获得的buffer。
//否则再次调用CameraGetImageBuffer时程序将被挂起一直阻塞直到其他线程中调用CameraReleaseImageBuffer来释放了buffer //否则再次调用CameraGetImageBuffer时程序将被挂起一直阻塞直到其他线程中调用CameraReleaseImageBuffer来释放了buffer
@@ -156,16 +151,13 @@ bool CameraWrapper::readRaw(cv::Mat &src) {
} }
bool CameraWrapper::readProcessed(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) { if (CameraGetImageBuffer(h_camera, &frame_info, &pby_buffer, 500) == CAMERA_STATUS_SUCCESS) {
CameraImageProcess(h_camera, pby_buffer, rgb_buffer, CameraImageProcess(h_camera, pby_buffer, rgb_buffer,
&frame_info); // this function is super slow, better not to use it. &frame_info); // this function is super slow, better not to use it.
if (iplImage) { // 使用 cv::Mat 替代 IplImage
cvReleaseImageHeader(&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);
iplImage = cvCreateImageHeader(cvSize(frame_info.iWidth, frame_info.iHeight), IPL_DEPTH_8U, channel); src = img.clone();
cvSetData(iplImage, rgb_buffer, frame_info.iWidth * channel); //此处只是设置指针,无图像块数据拷贝,不需担心转换效率
src = cv::cvarrToMat(iplImage).clone();
//在成功调用CameraGetImageBuffer后必须调用CameraReleaseImageBuffer来释放获得的buffer。 //在成功调用CameraGetImageBuffer后必须调用CameraReleaseImageBuffer来释放获得的buffer。
//否则再次调用CameraGetImageBuffer时程序将被挂起一直阻塞直到其他线程中调用CameraReleaseImageBuffer来释放了buffer //否则再次调用CameraGetImageBuffer时程序将被挂起一直阻塞直到其他线程中调用CameraReleaseImageBuffer来释放了buffer
CameraReleaseImageBuffer(h_camera, pby_buffer); CameraReleaseImageBuffer(h_camera, pby_buffer);
@@ -193,4 +185,4 @@ CameraWrapper::~CameraWrapper() {
//注意先反初始化后再free //注意先反初始化后再free
if (rgb_buffer != nullptr) if (rgb_buffer != nullptr)
free(rgb_buffer); free(rgb_buffer);
} }

View File

@@ -6,12 +6,13 @@
#include <log.h> #include <log.h>
#include <cstring> #include <cstring>
#include <map> #include <map>
#include <string>
bool show_armor_box = false; bool show_armor_box = true;
bool show_armor_boxes = false; bool show_armor_boxes = false;
bool show_light_blobs = false; bool show_light_blobs = false;
bool show_origin = false; bool show_origin = false;
bool run_with_camera = false; bool run_with_camera = true;
bool save_video = false; bool save_video = false;
bool wait_uart = false; bool wait_uart = false;
bool save_labelled_boxes = false; bool save_labelled_boxes = false;

3
tools/tty-permission.sh Normal file
View File

@@ -0,0 +1,3 @@
#!/bin/sh
sudo touch /etc/udev/rules.d/70-ttyusb.rules

122
xmake.lua Normal file
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 = {}
}