| RMVL 1.5.2 Robotic Manipulation and Vision Library

载入中...
搜索中...
未找到
samples/detector/hik/sample_hik_armor_collection.cpp

装甲板收集例程 Armor collection demo

#include <filesystem>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include "rmvl/camera/hik_camera.h"
#include "rmvl/core/timer.hpp"
#include "rmvl/detector/armor_detector.h"
namespace fs = std::filesystem;
static inline void draw(cv::Mat src, rm::combo::ptr p_combo)
{
// 角点
const auto &corners = p_combo->corners();
for (int i = 0; i < 4; ++i)
cv::line(src, corners[i], corners[(i + 1) % 4], cv::Scalar(0, 255, 0));
}
const char *keys = "{ ? h help | | 帮助信息 }"
"{ i index |0 | 第一帧图像下标 }"
"{ p prefix |rmvl_data | 不带 \"/\" 后缀的导出路径，可使用递归路径，不存在会自动创建"
"\n\t\t如 \033[33m-p=datasets/0\033[0m 或 \033[33m-p=datasets/1\033[0m }"
"{ n num |1000 | 图片数量 }"
"{ c color |0 | 识别装甲板颜色 '\033[33m0\033[0m': 识别蓝色，"
"'\033[33m1\033[0m': 识别红色 }"
"{ w waitkey |20 | cv::cv::waitKey(?) }";
const char *help = " \033[34;1m使用说明\033[0m\n"
"本程序为装甲板 ROI 收集例程，用于收集装甲板数字部分的 ROI，\n"
"程序终端会显示当前收集并导出的 ROI 图片序号，并且包含 2 个图\n"
"形窗口一个是标记出装甲板的相机捕获的画面，另一个是 ROI 原图\n"
"与便于观察的 ROI 二值图";
int main(int argc, char *argv[])
{
// 命令行参数初始化
cv::CommandLineParser parser(argc, argv, keys);
if (parser.has("help"))
{
parser.printMessage();
printf("%s\n", help);
exit(0);
}
// 获取命令行参数
auto path = parser.get<std::string>("prefix");
auto first_idx = parser.get<int>("index");
auto num = parser.get<int>("num");
auto color = parser.get<int>("color") == 0 ? rm::PixChannel::BLUE : rm::PixChannel::RED;
auto waitkey = parser.get<int>("waitkey");
if (!fs::exists(path))
{
if (fs::create_directories(path))
printf("创建新文件夹 \033[33m\"%s\"\033[0m...\n", path.c_str());
else
{
printf("\033[33m\"%s\"\033[0m 文件夹不存在，重新创建失败...\n", path.c_str());
return -1;
}
}
else
printf("已发现 \033[33m\"%s\"\033[0m 文件夹\n", path.c_str());
// 相机初始化
rm::HikCamera capture(rm::CameraConfig::create(rm::GrabMode::Continuous, rm::RetrieveMode::OpenCV));
if (!capture.isOpened())
{
printf("相机打开失败\n");
return -1;
}
cv::FileStorage camera_param("out_para.yml", cv::FileStorage::READ);
int exposure = 3000;
int gain = 8;
int r_gain = 1500;
int g_gain = 1500;
int b_gain = 1500;
// 设置相机参数
cv::FileStorage fs_mv_set("out_para.yml", cv::FileStorage::READ);
if (fs_mv_set.isOpened())
{
fs_mv_set["exposure"].isNone() ? void(0) : (fs_mv_set["exposure"] >> exposure);
fs_mv_set["gain"].isNone() ? void(0) : (fs_mv_set["gain"] >> gain);
fs_mv_set["r_gain"].isNone() ? void(0) : (fs_mv_set["r_gain"] >> r_gain);
fs_mv_set["g_gain"].isNone() ? void(0) : (fs_mv_set["g_gain"] >> g_gain);
fs_mv_set["b_gain"].isNone() ? void(0) : (fs_mv_set["b_gain"] >> b_gain);
}
capture.set(rm::CAMERA_MANUAL_EXPOSURE);
capture.set(rm::CAMERA_EXPOSURE, exposure);
capture.set(rm::CAMERA_GAIN, gain);
capture.set(rm::CAMERA_MANUAL_WB);
capture.set(rm::CAMERA_WB_RGAIN, r_gain);
capture.set(rm::CAMERA_WB_GGAIN, g_gain);
capture.set(rm::CAMERA_WB_BGAIN, b_gain);
auto p_detector = rm::ArmorDetector::make_detector();
std::vector<rm::group::ptr> groups;
cv::namedWindow("装甲板收集", cv::WINDOW_NORMAL);
cv::resizeWindow("装甲板收集", cv::Size(1000, 800));
cv::namedWindow("ROI 图像", cv::WINDOW_NORMAL);
cv::resizeWindow("ROI 图像", cv::Size(800, 400));
cv::Mat src;
int index = 0;
while (index < num)
{
if (!capture.read(src))
RMVL_Error(RMVL_StsError, "Fail to read the image.");
// 识别
auto info = p_detector->detect(groups, src, color, rm::ImuData(), rm::Timer::now());
const auto &combos = info.combos;
if (combos.size() > 1)
WARNING_("当前识别到多于 1 个装甲板：识别到 %zu 个", combos.size());
// ROI截取图像
cv::Mat roi_img;
if (!combos.empty())
{
roi_img = rm::Armor::getNumberROI(src, rm::Armor::cast(combos.front()));
// 显示效果
draw(src, combos.front());
}
// 保存图像
if (!roi_img.empty())
{
std::string file_name = path + "/" + std::to_string(index + first_idx) + ".png";
INFO_("保存图像至 %s", file_name.c_str());
if (!imwrite(file_name, roi_img))
ERROR_("保存图像失败");
cv::imshow("ROI 图像", roi_img);
index++;
}
cv::imshow("装甲板收集", src);
if (cv::waitKey(waitkey) == 27)
if (cv::waitKey(0) == 27)
exit(0);
}
putText(src, "Collection Over!", cv::Point(100, 200), cv::FONT_HERSHEY_COMPLEX, 2, cv::Scalar(0, 255, 0), 2);
cv::imshow("装甲板收集", src);
PASS_("收集完毕，按任意键以退出程序");
cv::waitKey(0);
return 0;
}
hik_camera.h
Hik Robot 工业相机库
rm::ArmorDetector::make_detector
static std::unique_ptr< ArmorDetector > make_detector()
构建 ArmorDetector
定义 armor_detector.h:58
rm::Armor::getNumberROI
static cv::Mat getNumberROI(cv::Mat src, const_ptr p_armor)
根据图像中指定装甲板的信息，截取仅包含数字的 ROI
rm::HikCamera
海康机器人相机库
定义 hik_camera.h:35
rm::Timer::now
static double now()
返回从构造初期到现在经过的时间（单位：s）
定义 timer.hpp:46
rm::combo::ptr
std::shared_ptr< combo > ptr
定义 combo.h:44
armor_detector.h
装甲板识别派生类头文件
rm::RetrieveMode::OpenCV
@ OpenCV
使用 OpenCV 的 'cvtColor' 进行处理
定义 camutils.hpp:52
rm::CAMERA_WB_BGAIN
@ CAMERA_WB_BGAIN
白平衡蓝色分量
定义 camutils.hpp:107
rm::CAMERA_WB_GGAIN
@ CAMERA_WB_GGAIN
白平衡绿色分量
定义 camutils.hpp:106
rm::CAMERA_MANUAL_EXPOSURE
@ CAMERA_MANUAL_EXPOSURE
手动曝光
定义 camutils.hpp:97
rm::CAMERA_EXPOSURE
@ CAMERA_EXPOSURE
曝光值
定义 camutils.hpp:102
rm::CAMERA_MANUAL_WB
@ CAMERA_MANUAL_WB
手动白平衡
定义 camutils.hpp:100
rm::CAMERA_WB_RGAIN
@ CAMERA_WB_RGAIN
白平衡红色分量
定义 camutils.hpp:105
rm::CAMERA_GAIN
@ CAMERA_GAIN
模拟增益
定义 camutils.hpp:103
rm::GrabMode::Continuous
@ Continuous
连续采样
定义 camutils.hpp:34
rm::RED
@ RED
红色通道
定义 pretreat.hpp:35
rm::BLUE
@ BLUE
蓝色通道
定义 pretreat.hpp:33
INFO_
#define INFO_(...)
定义 util.hpp:57
WARNING_
#define WARNING_(...)
定义 util.hpp:36
ERROR_
#define ERROR_(...)
定义 util.hpp:50
PASS_
#define PASS_(...)
定义 util.hpp:43
RMVL_Error
#define RMVL_Error(code, msg)
调用错误处理程序
定义 util.hpp:208
RMVL_StsError
@ RMVL_StsError
未指定（未知）错误 Unspecified (Unknown) error
定义 util.hpp:83
rm::para::camera_param
CameraParam camera_param
CameraParam 参数模块
定义 camera.h:72
rm
定义 camutils.hpp:17
rm::CameraConfig::create
static CameraConfig create(Args &&...modes)
创建相机初始化配置模式
定义 camutils.hpp:70
rm::ImuData
IMU 数据
定义 dataio.hpp:31
timer.hpp
定时、计时模块