首页 > 其他分享 >基本工具(1) openvslam 读取gnss.txt,然后匹配读取图像路径,保存轨迹到txt

基本工具(1) openvslam 读取gnss.txt,然后匹配读取图像路径,保存轨迹到txt

时间:2024-12-07 20:59:35浏览次数:4  
标签:std include const 读取 img openvslam file path txt

 注意跟丢的数据

 

1 添加编译节点

CMakeLists.txt 

# 自己改的照片模式
add_executable(run_image_slam_mydata run_image_slam_mydata.cc util/image_util.cc)
list(APPEND EXECUTABLE_TARGETS run_image_slam_mydata)

  

 2添加依赖文件

API_File_IO.h

#ifndef MYHEADER_H // 如果 MYHEADER_H 没有被定义
#define MYHEADER_H // 定义 MYHEADER_H

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <opencv2/opencv.hpp>

//#include <yaml-cpp/yaml.h>

#include <iostream>
#include <string>
#include <popl.hpp>// 假设这是popl库的头文件
 

#include <Eigen/Dense>
#include <Eigen/Geometry>


using namespace std;
using namespace cv;
using namespace YAML;


// 读取GNSS数据文件
vector<tuple<string, double, double, double>> readGNSSData(const string& filePath) {
    vector<tuple<string, double, double, double>> data;
    ifstream file(filePath);
    if (!file.is_open()) {
        cerr << "Failed to open file: " << filePath << endl;
        return data;
    }
    string line;
    while (getline(file, line)) {
        stringstream ss(line);
        string imgName;
        double lat, lon, alt;
        if (ss >> imgName >> lat >> lon >> alt) {
            data.emplace_back(imgName, lat, lon, alt);
        }
    }
    file.close();
    return data;
}
 
// 根据图像文件名读取图像
Mat readImage(const string& imageDir, const string& imageName) {
    string filePath = imageDir + "/" + imageName;
    Mat img = imread(filePath);
    if (img.empty()) {
        cerr << "Failed to read image: " << filePath << endl;
    }
    return img;
}



// // 读取YAML配置文件
string readConfig(const string filePath, string DataName) {
    ifstream file(filePath);
    if (!file.is_open()) {
        cerr << "Failed to open config file: " << filePath << endl;
        return "-1";
    }
 
    YAML::Node config_yaml = YAML::Load(file);
    try {
        std::string Data_context = config_yaml[DataName].as<string>();
        return Data_context;
       
    } catch (const BadConversion& e) {
        cerr << "Error parsing config file: " << e.what() << endl;
        return "-1";
    }
 
    
}



std::string Get_ConfigPath(int argc, char* argv[]) {

    popl::OptionParser op( "允许参数");

    // 定义-g选项,它需要一个参数(路径)
    auto configPath = op.add<popl::Value<std::string>>("c", "config", "Path to thedata file");
   
    // 解析选项
    op.parse(argc, argv);

    if(configPath->is_set()){

        std::string configPath_ = configPath->value();
        std::cout << " 配置文件路径  " << configPath_ << std::endl;
        return configPath_;

    }
    else{
        
        std::cout << "读取路径失败" << std::endl;
        return "fail";   
    }
}


/*

./run_image_slam \
-c  data/config.yaml  \

*/




void main_test(int argc, char* argv[]) {

    // 全局变量声明
    std::string Config_PATH;
    std::string GNSS_PSTH;
    std::string img_dir_path;
    std::string vocab_file_path;
    std::string map_db_path;

    vector<tuple<string, double, double, double>> gnssData;

    std::string config_file_path = Get_ConfigPath(argc, argv);

    // 初始化全局变量
    Config_PATH = readConfig(config_file_path, "Config_PATH");
    GNSS_PSTH = Config_PATH + "/" + readConfig(config_file_path, "GNSS_PSTH");
    img_dir_path = Config_PATH + "/" + readConfig(config_file_path, "Image_PATH");
    vocab_file_path = Config_PATH + "/" + readConfig(config_file_path, "vocab_file_path");
    map_db_path = Config_PATH + "/" + readConfig(config_file_path, "map_db_path");

    
    std::cout<<"===============配置文件信息=============== " <<std::endl;
    std::cout<<"config_file_path : " << config_file_path <<std::endl;

    std::cout<<"数据根目录 : " << Config_PATH <<std::endl;
    std::cout<<"GNSS_PSTH : " << GNSS_PSTH <<std::endl;
    std::cout<<"Image_PATH : " << img_dir_path <<std::endl;
    std::cout<<"vocab_file_path : " << vocab_file_path <<std::endl;
    std::cout<<"map_db_path : " << map_db_path <<std::endl;


    // 读取GNSS数据
    gnssData = readGNSSData(GNSS_PSTH);

    //遍历GNSS数据并读取对应的图像
    for (const auto& [imgName, lat, lon, alt] : gnssData) {
        Mat img = readImage(img_dir_path, imgName);
        if (!img.empty()) {
            // 在这里可以处理图像,例如显示、保存等
            imshow("Image", img);
            waitKey(0);  // 按任意键继续显示下一张图像
        }
    }
     
    // 遍历模式2
    for (unsigned int i = 0; i < gnssData.size(); ++i) {
        std::string imgName = std::get<0>(gnssData[i]);
        double lat = std::get<1>(gnssData[i]);
        double lon = std::get<2>(gnssData[i]);
        double alt = std::get<3>(gnssData[i]);
    }

}


/*
camera_rtk.yaml

#==============#
# 相机参数 #
#==============#
  
Camera.name: "RTK"
Camera.setup: "monocular" # 单目"Monocular", 双目"Stereo", 深度相机"RGBD"
Camera.model: "perspective" #perspective 正常相机  fisheye 鱼眼相机

Config_PATH: "/home/dongdong/2project/0data/RTK/data_1_nwpuUp/data3_1130_13pm/300_map_12pm/"
Image_PATH: "images"
GNSS_PSTH: slam_config/gnss.txt
vocab_file_path: slam_config/orb_vocab.dbow2
map_db_path: slam_config/Map_GNSS.msg


#相机参数
Camera.fps: 30
Camera.cols: 1805
Camera.rows: 1203
  
#内参
Camera.fx: 1193.7076128098686
Camera.fy: 1193.1735265967602
Camera.cx: 910.8785687265895
Camera.cy: 602.174293145834
  
#畸变系数
Camera.k1: 0.0
Camera.k2: 0.0
Camera.p1: 0.0
Camera.p2: 0.0
Camera.k3: 0.0
Camera.k4: 0.0
  
  
Camera.color_order: "RGB" #"Gray", "RGB", "BGR"

Initializer.num_min_triangulated_pts: 20
Initializer.parallax_deg_threshold: 1
Feature.max_num_keypoints: 3000
#===========================#
# 显示参数 #
#===========================#

PangolinViewer.keyframe_size: 0.07
PangolinViewer.keyframe_line_width: 2
PangolinViewer.graph_line_width: 1
PangolinViewer.point_size: 2
PangolinViewer.camera_size: 0.08
PangolinViewer.camera_line_width: 3
PangolinViewer.viewpoint_x: 0
PangolinViewer.viewpoint_y: -0.65
PangolinViewer.viewpoint_z: -1.9
PangolinViewer.viewpoint_f: 400

 */




void Pose_T_to_t_and_q(Eigen::Matrix4d transform , Eigen::Vector3d &t,Eigen::Quaterniond &q){

  // 从变换矩阵中提取旋转矩阵
    Eigen::Matrix3d rotation = transform.block<3, 3>(0, 0);
 
    // 从旋转矩阵计算四元数
    Eigen::Quaterniond quaternion(rotation);
 
    // 从变换矩阵中提取平移向量
    Eigen::Vector3d translation = transform.block<3, 1>(0, 3);

    t = translation;
    q = quaternion;


}


#include <filesystem>
#include <string>

void WritePosetoTxtFile(string save_txtname,std::vector<std::tuple<Eigen::Matrix4d, std::string>> poses_names){
    


    // 打开文件以写入 覆盖
    std::ofstream file(save_txtname);
    if (!file.is_open()) {
        std::cerr << "无法打开文件以写入" << std::endl;
       
    }

    for (const auto& pose_name : poses_names) {

        std::string name = std::get<1>(pose_name);
        Eigen::Matrix4d transform = std::get<0>(pose_name);

        //poses_names.emplace_back(matrix, name);

        // 从旋转矩阵计算四元数
        Eigen::Quaterniond q;
        // 从变换矩阵中提取平移向量
        Eigen::Vector3d t;
        Pose_T_to_t_and_q(transform,t,q);

        std::cout << "Name: " << std::get<1>(pose_name) << std::endl;
       
    // 写入名字、平移向量和四元数到文件
        file << name << " ";
        file << t[0] << " "; // 转置是为了以行向量的形式写入
        file << t[1] << " ";
        file << t[2] << " ";
        file << q.w() << " " << q.x() << " " << q.y() << " " << q.z() << std::endl;
    }
    // 关闭文件
    file.close();
}



#endif // 结束包含保护

  3主文件添加增加的文件读写函数

 关键修改

1添加头文件和全局变量

// 包含的文件
#include "API_File_IO.h"

// 全局变量声明
std::string Config_PATH;
std::string GNSS_PSTH;
std::string img_dir_path;
std::string vocab_file_path;
std::string map_db_path;

// 读取GNSS数据
vector<tuple<string, double, double, double>> gnssData ;
// 保存预测位姿
vector<tuple<Eigen::Matrix4d,std::string>> poses_names;

  

2 输入路径读取参数

开启命令参考

./run_image_slam \
-c  /home/dongdong/2project/1salm/1openvsalm/openvslam/data/camera_rtk.yaml  \

  代码获取路径

    //main_test(argc, argv);
    std::string config_file_path = Get_ConfigPath(argc, argv);

    // 初始化全局变量
    Config_PATH = readConfig(config_file_path, "Config_PATH");
    GNSS_PSTH = Config_PATH + "/" + readConfig(config_file_path, "GNSS_PSTH");
    img_dir_path = Config_PATH + "/" + readConfig(config_file_path, "Image_PATH");
    vocab_file_path = Config_PATH + "/" + readConfig(config_file_path, "vocab_file_path");
    map_db_path = Config_PATH + "/" + readConfig(config_file_path, "map_db_path");

    std::cout<<"===============配置文件信息=============== " <<std::endl;

    std::cout<<"config_file_path : " << config_file_path <<std::endl;

    std::cout<<"数据根目录 : " << Config_PATH <<std::endl;
    std::cout<<"GNSS_PSTH : " << GNSS_PSTH <<std::endl;
    std::cout<<"Image_PATH : " << img_dir_path <<std::endl;
    std::cout<<"vocab_file_path : " << vocab_file_path <<std::endl;
    std::cout<<"map_db_path : " << map_db_path <<std::endl;


    // 读取GNSS数据
    gnssData = readGNSSData(GNSS_PSTH);

    // 遍历GNSS数据并读取对应的图像
    // for (const auto& [imgName, lat, lon, alt] : gnssData) {
    //     Mat img = readImage(Image_PATH, imgName);
    //     if (!img.empty()) {
    //         // 在这里可以处理图像,例如显示、保存等
    //         imshow("Image", img);
    //         waitKey(0);  // 按任意键继续显示下一张图像
    //     }
    // }

3 循环读取图像送入跟踪

时间戳

  for (unsigned int i = 0; i < gnssData.size(); ++i) {


            std::string imgName = std::get<0>(gnssData[i]);
            double lat = std::get<1>(gnssData[i]);
            double lon = std::get<2>(gnssData[i]);
            double alt = std::get<3>(gnssData[i]);


            const auto  img = readImage(img_dir_path, imgName);

            double timestamp_ =  i*2.0;

  

4 每次跟踪结果保存队列

            if (!img.empty() && (i % frame_skip == 0)) {
                // input the current frame and estimate the camera pose
                Eigen::Matrix4d curent_pose = SLAM.feed_monocular_frame(img, timestamp_, mask);
                poses_names.emplace_back(curent_pose, imgName);
   
            }

  

5 保存结果轨迹

        WritePosetoTxtFile("1_1_frame_slam_enu.txt",poses_names);

 

  

 

 

  

 

完整代码

#include "util/image_util.h"

#ifdef USE_PANGOLIN_VIEWER
#include "pangolin_viewer/viewer.h"
#elif USE_SOCKET_PUBLISHER
#include "socket_publisher/publisher.h"
#endif

#include "openvslam/system.h"
#include "openvslam/config.h"

#include <iostream>
#include <chrono>
#include <numeric>

#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <spdlog/spdlog.h>
#include <popl.hpp>

#ifdef USE_STACK_TRACE_LOGGER
#include <glog/logging.h>
#endif

#ifdef USE_GOOGLE_PERFTOOLS
#include <gperftools/profiler.h>
#endif


// 包含的文件
#include "API_File_IO.h"

// 全局变量声明
std::string Config_PATH;
std::string GNSS_PSTH;
std::string img_dir_path;
std::string vocab_file_path;
std::string map_db_path;

// 读取GNSS数据
vector<tuple<string, double, double, double>> gnssData ;
// 保存预测位姿
vector<tuple<Eigen::Matrix4d,std::string>> poses_names;




void mono_tracking(const std::shared_ptr<openvslam::config>& cfg,
                   const std::string& vocab_file_path, const std::string& image_dir_path, const std::string& mask_img_path,
                   const unsigned int frame_skip, const bool no_sleep, const bool auto_term,
                   const bool eval_log, const std::string& map_db_path) {
    // load the mask image
    const cv::Mat mask = mask_img_path.empty() ? cv::Mat{} : cv::imread(mask_img_path, cv::IMREAD_GRAYSCALE);

    const image_sequence sequence(image_dir_path, cfg->camera_->fps_);
    const auto frames = sequence.get_frames();

    // build a SLAM system
    openvslam::system SLAM(cfg, vocab_file_path);
    // startup the SLAM process
    SLAM.startup();

#ifdef USE_PANGOLIN_VIEWER
    pangolin_viewer::viewer viewer(cfg, &SLAM, SLAM.get_frame_publisher(), SLAM.get_map_publisher());
#elif USE_SOCKET_PUBLISHER
    socket_publisher::publisher publisher(cfg, &SLAM, SLAM.get_frame_publisher(), SLAM.get_map_publisher());
#endif

    std::vector<double> track_times;
    track_times.reserve(frames.size());

    // run the SLAM in another thread
    std::thread thread([&]() {




       


        //for (const auto& [imgName, lat, lon, alt] : gnssData) {
            //     Mat img = readImage(Image_PATH, imgName);

        for (unsigned int i = 0; i < gnssData.size(); ++i) {


            std::string imgName = std::get<0>(gnssData[i]);
            double lat = std::get<1>(gnssData[i]);
            double lon = std::get<2>(gnssData[i]);
            double alt = std::get<3>(gnssData[i]);


            const auto  img = readImage(img_dir_path, imgName);

            double timestamp_ =  i*2.0;

            //const auto img = cv::imread(frame.img_path_, cv::IMREAD_UNCHANGED);

            const auto tp_1 = std::chrono::steady_clock::now();

            if (!img.empty() && (i % frame_skip == 0)) {
                // input the current frame and estimate the camera pose
                Eigen::Matrix4d curent_pose = SLAM.feed_monocular_frame(img, timestamp_, mask);
                poses_names.emplace_back(curent_pose, imgName);
   
            }

            const auto tp_2 = std::chrono::steady_clock::now();

            const auto track_time = std::chrono::duration_cast<std::chrono::duration<double>>(tp_2 - tp_1).count();
            if (i % frame_skip == 0) {
                track_times.push_back(track_time);
            }

            // wait until the timestamp of the next frame
            if (!no_sleep && i < frames.size() - 1) {
                const auto wait_time = frames.at(i + 1).timestamp_ - (timestamp_ + track_time);
                if (0.0 < wait_time) {
                    std::this_thread::sleep_for(std::chrono::microseconds(static_cast<unsigned int>(wait_time * 1e6)));
                }
            }

            // check if the termination of SLAM system is requested or not
            if (SLAM.terminate_is_requested()) {
                break;
            }
        }


        WritePosetoTxtFile("1_1_frame_slam_enu.txt",poses_names);

        // wait until the loop BA is finished
        while (SLAM.loop_BA_is_running()) {
            std::this_thread::sleep_for(std::chrono::microseconds(5000));
        }

        // automatically close the viewer
#ifdef USE_PANGOLIN_VIEWER
        if (auto_term) {
            viewer.request_terminate();
        }
#elif USE_SOCKET_PUBLISHER
        if (auto_term) {
            publisher.request_terminate();
        }
#endif
    });

    // run the viewer in the current thread
#ifdef USE_PANGOLIN_VIEWER
    viewer.run();
#elif USE_SOCKET_PUBLISHER
    publisher.run();
#endif

    thread.join();

    // shutdown the SLAM process
    SLAM.shutdown();

    if (eval_log) {
        // output the trajectories for evaluation
        SLAM.save_frame_trajectory("frame_trajectory.txt", "TUM");
        SLAM.save_keyframe_trajectory("keyframe_trajectory.txt", "TUM");
        // output the tracking times for evaluation
        std::ofstream ofs("track_times.txt", std::ios::out);
        if (ofs.is_open()) {
            for (const auto track_time : track_times) {
                ofs << track_time << std::endl;
            }
            ofs.close();
        }
    }

    if (!map_db_path.empty()) {
        // output the map database
        SLAM.save_map_database(map_db_path);
    }

    std::sort(track_times.begin(), track_times.end());
    const auto total_track_time = std::accumulate(track_times.begin(), track_times.end(), 0.0);
    std::cout << "median tracking time: " << track_times.at(track_times.size() / 2) << "[s]" << std::endl;
    std::cout << "mean tracking time: " << total_track_time / track_times.size() << "[s]" << std::endl;
}


/*

./run_image_slam \
-c  /home/dongdong/2project/1salm/1openvsalm/openvslam/data/camera_rtk.yaml  \


*/



int main(int argc, char* argv[]) {
#ifdef USE_STACK_TRACE_LOGGER
    google::InitGoogleLogging(argv[0]);
    google::InstallFailureSignalHandler();
#endif

    //main_test(argc, argv);
    std::string config_file_path = Get_ConfigPath(argc, argv);

    // 初始化全局变量
    Config_PATH = readConfig(config_file_path, "Config_PATH");
    GNSS_PSTH = Config_PATH + "/" + readConfig(config_file_path, "GNSS_PSTH");
    img_dir_path = Config_PATH + "/" + readConfig(config_file_path, "Image_PATH");
    vocab_file_path = Config_PATH + "/" + readConfig(config_file_path, "vocab_file_path");
    map_db_path = Config_PATH + "/" + readConfig(config_file_path, "map_db_path");

    std::cout<<"===============配置文件信息=============== " <<std::endl;

    std::cout<<"config_file_path : " << config_file_path <<std::endl;

    std::cout<<"数据根目录 : " << Config_PATH <<std::endl;
    std::cout<<"GNSS_PSTH : " << GNSS_PSTH <<std::endl;
    std::cout<<"Image_PATH : " << img_dir_path <<std::endl;
    std::cout<<"vocab_file_path : " << vocab_file_path <<std::endl;
    std::cout<<"map_db_path : " << map_db_path <<std::endl;


    // 读取GNSS数据
    gnssData = readGNSSData(GNSS_PSTH);

    // 遍历GNSS数据并读取对应的图像
    // for (const auto& [imgName, lat, lon, alt] : gnssData) {
    //     Mat img = readImage(Image_PATH, imgName);
    //     if (!img.empty()) {
    //         // 在这里可以处理图像,例如显示、保存等
    //         imshow("Image", img);
    //         waitKey(0);  // 按任意键继续显示下一张图像
    //     }
    // }



    // create options
    popl::OptionParser op("Allowed options");
    auto help = op.add<popl::Switch>("h", "help", "produce help message");
    //auto vocab_file_path = op.add<popl::Value<std::string>>("v", "vocab", "vocabulary file path");
    //auto img_dir_path = op.add<popl::Value<std::string>>("i", "img_dir", "directory path which contains images");
    //auto config_file_path = op.add<popl::Value<std::string>>("c", "config", "config file path");
    auto mask_img_path = op.add<popl::Value<std::string>>("", "mask", "mask image path", "");
    auto frame_skip = op.add<popl::Value<unsigned int>>("", "frame-skip", "interval of frame skip", 1);
    auto no_sleep = op.add<popl::Switch>("", "no-sleep", "not wait for next frame in real time");
    auto auto_term = op.add<popl::Switch>("", "auto-term", "automatically terminate the viewer");
    auto debug_mode = op.add<popl::Switch>("", "debug", "debug mode");
    auto eval_log = op.add<popl::Switch>("", "eval-log", "store trajectory and tracking times for evaluation");
    //auto map_db_path = op.add<popl::Value<std::string>>("p", "map-db", "store a map database at this path after SLAM", "");
    try {
        op.parse(argc, argv);
    }
    catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
        std::cerr << std::endl;
        std::cerr << op << std::endl;
        return EXIT_FAILURE;
    }

    // check validness of options
    if (help->is_set()) {
        std::cerr << op << std::endl;
        return EXIT_FAILURE;
    }
    // if (!vocab_file_path->is_set() || !img_dir_path->is_set() || !config_file_path->is_set()) {
    //     std::cerr << "invalid arguments" << std::endl;
    //     std::cerr << std::endl;
    //     std::cerr << op << std::endl;
    //     return EXIT_FAILURE;
    // }
    if (vocab_file_path=="-1" || img_dir_path=="-1" || config_file_path=="-1") {
        std::cerr << "invalid arguments" << std::endl;
        std::cerr << std::endl;
        std::cerr << op << std::endl;
        return EXIT_FAILURE;
    }
    // setup logger
    spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%e] %^[%L] %v%$");
    if (debug_mode->is_set()) {
        spdlog::set_level(spdlog::level::debug);
    }
    else {
        spdlog::set_level(spdlog::level::info);
    }

    // load configuration
    std::shared_ptr<openvslam::config> cfg;
    try {
        cfg = std::make_shared<openvslam::config>(config_file_path);
    }
    catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
        return EXIT_FAILURE;
    }

#ifdef USE_GOOGLE_PERFTOOLS
    ProfilerStart("slam.prof");
#endif

    // run tracking
    // if (cfg->camera_->setup_type_ == openvslam::camera::setup_type_t::Monocular) {
    //     mono_tracking(cfg, vocab_file_path->value(), img_dir_path->value(), mask_img_path->value(),
    //                   frame_skip->value(), no_sleep->is_set(), auto_term->is_set(),
    //                   eval_log->is_set(), map_db_path->value());

    if (cfg->camera_->setup_type_ == openvslam::camera::setup_type_t::Monocular) {
    mono_tracking(cfg, vocab_file_path, img_dir_path, mask_img_path->value(),
                    frame_skip->value(), no_sleep->is_set(), auto_term->is_set(),
                    eval_log->is_set(), map_db_path);
    }
    else {
        throw std::runtime_error("Invalid setup type: " + cfg->camera_->get_setup_type_string());
    }

#ifdef USE_GOOGLE_PERFTOOLS
    ProfilerStop();
#endif

    return EXIT_SUCCESS;
}

  

标签:std,include,const,读取,img,openvslam,file,path,txt
From: https://www.cnblogs.com/gooutlook/p/18592658

相关文章

  • CMakeTutorial_Step1_CMakeLists.txt
    #TODO1:SettheminimumrequiredversionofCMaketobe3.10cmake_minimum_required(VERSION3.10)#TODO2:CreateaprojectnamedTutorialproject(TutorialVERSION1.0)#TODO7:Settheprojectversionnumberas1.0intheaboveprojectcommand#Wh......
  • Mitel MiCollab 企业协作平台 任意文件读取漏洞复现(CVE-2024-41713)
    0x01产品简介MitelMiCollab是加拿大Mitel(敏迪)公司推出的一款企业级协作平台,旨在为企业提供统一、高效、安全的通信与协作解决方案。通过该平台,员工可以在任何时间、任何地点,使用任何设备,实现即时通信、语音通话、视频会议、文件共享等功能,从而提升工作效率和团队协作能力。......
  • C# 与 13.56MHz 射频卡:突破技术瓶颈,实现精准数据读取与处理
    在现代信息化社会中,射频识别(RFID)技术凭借其高效、非接触式的数据传输特性,广泛应用于各种领域,尤其是在物联网(IoT)、智能交通、门禁系统等场景中。13.56MHz射频卡作为一种常见的RFID卡片类型,因其高安全性、较强的抗干扰能力和较大的数据存储能力,成为许多应用的首选。为了更好......
  • python学opencv|读取图像(二)保存彩色图像
    【1】引言前序学习过程中,已经掌握了读取图像的基本操作,对三个函数的功能有了基本了解:cv.imread()、cv.imshow()、cv.imwrite()学习文章链接为:python学opencv|读取图像-CSDN博客不过这篇文章里,我们获得的图像是灰度图。如果需要彩色图,那又如何处理,这就是本次课程的目的。......
  • CMakeLists.txt自动添加cpp文件
    问题描述使用Clion编译器写C++时,一整个项目内仅只能包含一个main函数。当我们只是想练习C++语言时,想在在同一个项目里写多个样例,这时需要我们手动去配置CmakeLists.txt。每次都去配置会比较麻烦,因此希望有自动化脚本。当我们在同一个项目中添加新的源文件时,自动在CmakeLists.txt......
  • 读取excel某表的sheet1的前5行,写入的第二个表的sheet1的前5行
     报错了提示缺少xlwt库#从goods_list.xlsx的sheet1表中获取前5行的数据将数据写入到3.xlsx的sheet1表的前5行#从goods_list.xlsx的sheet1表中获取前5行的数据将数据写入到3.xlsx的sheet1表的前5行importpandasaspd#正确读取文件,确保文件名后缀与实际格式一致data......
  • 关于串口通信读取BL0942芯片电压电流的使用
    概述: 通过串口通信来获取BL0942芯片采集到的电压电流,采用的芯片为10引脚类型,电压采样为电阻采样,电流采样为互感器采样。芯片功能特点:两路独立的Sigma-DeltaADC,一路电流和一路电压。电流有效值范围(10mA~35A)@1mohm有功电能(1w~7700w)@1mohm可测量电流电压有效值,快速电......
  • Sitecore CMS 未经身份验证任意文件读取漏洞复现(CVE-2024-46938)
    0x01产品描述:        SitecoreExperiencePlatform™(XP)是一款基于.NETWebForm技术构建的内容管理系统,可以将客户数据、分析、人工智能与营销自动化功能相结合,在任何渠道上实时提供个性化的内容,从而在客户旅程中与客户建立良好的关系。0x02漏洞描述:     ......
  • 【漏洞复现】Bazaar 任意文件读取漏洞(CVE-2024-40348)
    免责声明请勿使用本文中提到的技术进行非法测试或行为。使用本文中提供的信息或工具所造成的任何后果和损失由使用者自行承担,所产生的一切不良后果与文章作者无关。该文章仅供学习用途使用。一、简介Bazaar是一个强大的分布式版本控制系统,旨在帮助开发者记录项目的历史......
  • Spring Boot读取外部配置文件失败,原因绝对出乎你意料
    开心一刻今天和相亲对象见面,特意打扮了一番见完面回到家后我给她发微信我:我今天的形象怎么样她:挺白净亮眼的我:头发不油吧她:反光,没看清我:???知识回顾在我们的实际开发工程中,打包的jar通常会包含配置文件(例如:application.yml)来作为默认配置文件,然后在不同的环境用外部配置......