From 4937463f80c49d89a9897961cb543dd96806c06c Mon Sep 17 00:00:00 2001 From: Zhanpeng Yang Date: Fri, 11 Oct 2024 13:21:45 +0800 Subject: [PATCH] =?UTF-8?q?[Changed]=E4=BF=AE=E6=94=B9=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E5=AF=BC=E5=85=A5=E6=96=B9=E5=BC=8F=E4=B8=BA=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 20 ++--- include/utils.h | 20 ++++- run.ps1 | 39 +++++----- src/display.cpp | 57 ++++++++------- src/main.cpp | 115 ++++++++++------------------- src/utils.cpp | 189 +++++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 305 insertions(+), 135 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 243b48e..64b2caf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,13 +4,13 @@ cmake_minimum_required(VERSION 3.20) # 设置指定的C++编译器版本是必须的,如果不设置,或者为OFF,则指定版本不可用时,会使用上一版本。 set(CMAKE_CXX_STANDARD_REQUIRED ON) -# 指定为C++20 版本 -set(CMAKE_CXX_STANDARD 20) +# 指定为C++23 版本 +set(CMAKE_CXX_STANDARD 23) set(PROJ_NAME "SEMS-data-collection") set(PROJ_VERSION_MAJOR 0) set(PROJ_VERSION_MINOR 0) -set(PROJ_VERSION_PATCH 3.20241008_alpha) +set(PROJ_VERSION_PATCH 4.20241011_alpha) #设置项目名字为HelloWorld project(${PROJ_NAME}) @@ -25,28 +25,28 @@ include_directories(${PROJECT_SOURCE_DIR}/include) link_directories (${PROJECT_SOURCE_DIR}/lib) add_library(SpectralCameraLib "${PROJECT_SOURCE_DIR}/src/spectral_camera.cpp") add_library(DisplayLib "${PROJECT_SOURCE_DIR}/src/display.cpp") -add_library(DataPreprocessLib "${PROJECT_SOURCE_DIR}/src/data_preprocess.cpp") -add_library(VisibleLightCameraLIB "${PROJECT_SOURCE_DIR}/src/visible_light_camera.cpp") +# add_library(DataPreprocessLib "${PROJECT_SOURCE_DIR}/src/data_preprocess.cpp") +# add_library(VisibleLightCameraLIB "${PROJECT_SOURCE_DIR}/src/visible_light_camera.cpp") add_library(UtilsLIB "${PROJECT_SOURCE_DIR}/src/utils.cpp") -link_directories (${PROJECT_SOURCE_DIR}/../CompliteEnv/Python37) +# link_directories (${PROJECT_SOURCE_DIR}/../CompliteEnv/Python37) #编译${PROJECT_SOURCE_DIR}/src/main.cpp在这个cpp文件为名为HelloWorld可执行文件 add_executable(${PROJ_NAME} "${PROJECT_SOURCE_DIR}/src/main.cpp") #链接动态链接库 -target_link_libraries(${PROJ_NAME} PUBLIC yaml-cpp) +# target_link_libraries(${PROJ_NAME} PUBLIC yaml-cpp) target_link_libraries(${PROJ_NAME} PUBLIC SpectralCameraLib) target_link_libraries(${PROJ_NAME} PUBLIC SpecSensor) -target_link_libraries(${PROJ_NAME} PUBLIC VisibleLightCameraLIB) +# target_link_libraries(${PROJ_NAME} PUBLIC VisibleLightCameraLIB) target_link_libraries(${PROJ_NAME} PUBLIC DisplayLib) -target_link_libraries(${PROJ_NAME} PUBLIC opencv_core490 opencv_highgui490 opencv_imgproc490 opencv_photo490 opencv_imgcodecs490 opencv_video490 opencv_videoio490) -target_link_libraries(${PROJ_NAME} PUBLIC DataPreprocessLib) +target_link_libraries(${PROJ_NAME} PUBLIC opencv_core490 opencv_highgui490 opencv_imgproc490) +# target_link_libraries(${PROJ_NAME} PUBLIC DataPreprocessLib) target_link_libraries(${PROJ_NAME} PUBLIC UtilsLIB) diff --git a/include/utils.h b/include/utils.h index f6ae15c..5df5a57 100644 --- a/include/utils.h +++ b/include/utils.h @@ -1,4 +1,20 @@ -#ifndef _SPECTRAL_CAMERA_H -#define _SPECTRAL_CAMERA_H +#ifndef _UYILS_H +#define _UYILS_H +struct Configs +{ + bool isEmpty = false; + int SPECTRUM_deviceTypeIndex; + double SPECTRUM_FrameRate; + double SPECTRUM_ExposureTime; + int SPECTRUM_BinningSpatial; + int SPECTRUM_BinningSpectral; + bool SPECTRUM_BinningAverage; + long long SPECTRUM_RingBufferSize; + std::string RAWDATA_Folder; + unsigned long long RAWDATA_MaxSize; +}; + +Configs getConfigFromEnvVar(); +bool AddExePathtoPATH(); #endif \ No newline at end of file diff --git a/run.ps1 b/run.ps1 index 7f894f2..7e13cbb 100644 --- a/run.ps1 +++ b/run.ps1 @@ -1,25 +1,28 @@ Param($cmd) -$Env:PATH="C:\Program Files\Common Files\Pleora\eBUS SDK;" #开发光谱相机所必需的路径 -$Env:PATH+="C:\Program Files\Git\cmd;C:\Windows\System32\OpenSSH;" #开发所需的git/ssh命令的路径 -$Env:PATH+=(Resolve-Path ../CompliteEnv/mingw64/bin).path+";" #g++所在路径 -$Env:PATH+=(Resolve-Path ../CompliteEnv/CMake/bin).path+";" #cmake所在路径 -$Env:PATH+=(Resolve-Path ./lib).path+";" #本项目所需的动态链接库所在路径 +#在 PowerShell 中将字符集修改为 UTF-8: +$OutputEncoding = [System.Console]::OutputEncoding = [System.Console]::InputEncoding = [System.Text.Encoding]::UTF8 + + +$Env:PATH = "C:\Program Files\Common Files\Pleora\eBUS SDK;" #开发光谱相机所必需的路径 +$Env:PATH += "C:\Program Files\Git\cmd;C:\Windows\System32\OpenSSH;" #开发所需的git/ssh命令的路径 +$Env:PATH += (Resolve-Path ../CompliteEnv/mingw64/bin).path + ";" #g++所在路径 +$Env:PATH += (Resolve-Path ../CompliteEnv/CMake/bin).path + ";" #cmake所在路径 +$Env:PATH += (Resolve-Path ./lib).path + ";" #本项目所需的动态链接库所在路径 Write-Host "PATH is set to $Env:PATH" -function Remove-Build-Dir -{ - If(Test-Path "build"){ #如果当前目录下build文件夹存在 +function Remove-Build-Dir { + If (Test-Path "build") { + #如果当前目录下build文件夹存在 Remove-Item -Path "build" -Recurse #递归阐述build文件夹 } } -function ReBuild-Target -{ +function ReBuild-Target { # 编译生成Makefile cmake -B build -G "MinGW Makefiles" # 编译生成可执行程序 @@ -27,14 +30,13 @@ function ReBuild-Target } -function Run-All-Exe -{ - $exeFiles= Get-ChildItem -Path "build" -Filter *.exe +function Run-All-Exe { + $exeFiles = Get-ChildItem -Path "build" -Filter *.exe Write-Host "Exe Files: $exeFiles" - ForEach($exeFile in $exeFiles){ + ForEach ($exeFile in $exeFiles) { Write-Host "Processing file: $($exeFile.FullName)" - Start-Process -Wait -FilePath $exeFile.FullName -PassThru + Start-Process -Wait -FilePath $exeFile.FullName -NoNewWindow -PassThru } } @@ -42,7 +44,7 @@ function Run-All-Exe -If($cmd -eq "b"){ +If ($cmd -eq "b") { Write-Host "Rebuilding all targets..." Remove-Build-Dir @@ -53,12 +55,13 @@ If($cmd -eq "b"){ } -If($cmd -eq "p"){ +If ($cmd -eq "p") { Write-Host "Packing all targets..." cmake --build build --target package } -If([String]::IsNullOrEmpty($cmd)){ #如果没有任何参数就运行所有exe +If ([String]::IsNullOrEmpty($cmd)) { + #如果没有任何参数就运行所有exe Run-All-Exe } diff --git a/src/display.cpp b/src/display.cpp index 4ee31cf..6dd277e 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -10,50 +10,55 @@ #include // #include +int64_t last_t = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - -void display_spectral_image(unsigned char *raw_data, long long width, long long height,std::string window_name) +void display_spectral_image(unsigned char *raw_data, long long width, long long height, std::string window_name) { - cv::Mat img = cv::Mat(height, width,CV_16U, raw_data); + cv::Mat img = cv::Mat(height, width, CV_16U, raw_data); img.convertTo(img, CV_16F); img = img / 4095 * 255; img.convertTo(img, CV_8U); cv::applyColorMap(img, img, cv::COLORMAP_TURBO); cv::namedWindow("Spectral Image", 0); - cv::resizeWindow("Spectral Image", width , height ); - + cv::resizeWindow("Spectral Image", width, height); - uint16_t *p = (uint16_t *)raw_data; + uint16_t *p = (uint16_t *)raw_data; - cv::Vec3b white= img.at(0, 0); - white[0]=0; - white[1]=0; - white[2]=0; + cv::Vec3b white = img.at(0, 0); + white[0] = 0; + white[1] = 0; + white[2] = 0; - int over_exposure_num=0; - int max_intensity=0; - for(int i=0;i(j,i)=white; - over_exposure_num++; - } - if (*(p+(j*width+i))>max_intensity){ - max_intensity=*(p+(j*width+i)); - } + int over_exposure_num = 0; + int max_intensity = 0; + for (int i = 0; i < width; i++) + { + for (int j = 0; j < height; j++) + { + if (*(p + (j * width + i)) == 4095) + { + img.at(j, i) = white; + over_exposure_num++; + } + if (*(p + (j * width + i)) > max_intensity) + { + max_intensity = *(p + (j * width + i)); + } } - } - std::string add_text=std::string("Over Exposure:")+std::to_string(over_exposure_num)+std::string(" Max Intensity:")+std::to_string(max_intensity); - cv::putText(img,add_text.c_str(),cv::Point(30,400),cv::FONT_HERSHEY_SIMPLEX,1,CV_RGB(255,255,255),1,8); + } + + int64_t t = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + + std::string add_text = std::string("Over Exposure:") + std::to_string(over_exposure_num) + std::string(" Max Intensity:") + std::to_string(max_intensity) + " FPS:" + std::to_string(1000 / (double)(t - last_t)); + last_t = t; + cv::putText(img, add_text.c_str(), cv::Point(10, 20), cv::FONT_HERSHEY_SIMPLEX, 0.5, CV_RGB(255, 255, 255), 1, 2); cv::imshow(window_name, img); cv::waitKey(1); } - void display_img(cv::Mat img, std::string window_name) { cv::imshow(window_name, img); cv::waitKey(1); // Wait for a keystroke in the window } - diff --git a/src/main.cpp b/src/main.cpp index ca5a777..3243e37 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,27 +1,31 @@ -#include #include -#include +#include +#include + +// #include + +// #include #include #include "spectral_camera.h" -#include "yaml-cpp/yaml.h" +// #include "yaml-cpp/yaml.h" #include "display.h" -#include "data_preprocess.h" +// #include "data_preprocess.h" -#include -#include -#include -#include +// #include +// #include +// #include +// #include #include -#include "visible_light_camera.h" -#include +// #include "visible_light_camera.h" +// #include #include extern unsigned long long int last_file_time = 0; extern unsigned long long int frame_num = 0; -int check_update_file_handle(std::string save_dir, std::ofstream &h_raw_spectal_file, std::ofstream &h_header_file, unsigned long long max_file_size, std::ofstream &h_visible_light_file, bool enable_visible_light_camera) +int check_update_file_handle(std::string save_dir, std::ofstream &h_raw_spectal_file, std::ofstream &h_header_file, unsigned long long max_file_size) { if (h_raw_spectal_file.is_open()) { @@ -34,23 +38,13 @@ int check_update_file_handle(std::string save_dir, std::ofstream &h_raw_spectal_ h_raw_spectal_file.open((raw_data_file_name + std::string(".bin").data()), std::ios::out | std::ios::binary | std::ios::app); h_header_file.open((raw_data_file_name + std::string(".csv").data()), std::ios::out | std::ios::app); - if (enable_visible_light_camera) - { - if (h_visible_light_file.is_open()) - { - h_visible_light_file.close(); - } - - h_visible_light_file.open((raw_data_file_name + std::string(".img").data()), std::ios::out | std::ios::binary | std::ios::app); - } - unsigned long long int now = (unsigned long long int)now_t; if (last_file_time != 0) { float t = (float)(now - last_file_time) / 1000; // std::cout<listDevices(); - spec_camera->init(configs["spectral_camera_configs"]["deviceTypeIndex"].as(), - configs["spectral_camera_configs"]["FrameRate"].as(), - configs["spectral_camera_configs"]["ExposureTime"].as(), - configs["spectral_camera_configs"]["BinningSpatial"].as(), - configs["spectral_camera_configs"]["BinningSpectral"].as(), - configs["spectral_camera_configs"]["BinningAverage"].as(), - configs["spectral_camera_configs"]["RingBufferSize"].as()); + spec_camera->init(configs.SPECTRUM_deviceTypeIndex, + configs.SPECTRUM_FrameRate, + configs.SPECTRUM_ExposureTime, + configs.SPECTRUM_BinningSpatial, + configs.SPECTRUM_BinningSpectral, + configs.SPECTRUM_BinningAverage, + configs.SPECTRUM_RingBufferSize); - bool enable_visible_light_camera = configs["visible_light_camera_configs"]["enable"].as(); - std::string save_dir = configs["save_configs"]["save_dir"].as(); - unsigned long long max_file_size = configs["save_configs"]["max_file_size"].as(); - - VisibleLightCamera *visible_light_camera = NULL; - if (enable_visible_light_camera) - { - visible_light_camera = new VisibleLightCamera(); - visible_light_camera->init(configs["visible_light_camera_configs"]["video_capture_index"].as()); - } - - std::ofstream h_raw_spectal_file, h_header_file, h_visible_light_file; - check_update_file_handle(save_dir, h_raw_spectal_file, h_header_file, max_file_size, h_visible_light_file, enable_visible_light_camera); + std::ofstream h_raw_spectal_file, h_header_file; + check_update_file_handle(configs.RAWDATA_Folder, h_raw_spectal_file, h_header_file, configs.RAWDATA_MaxSize); bool flag_run = true; while (flag_run) { @@ -119,19 +91,11 @@ int main() display_spectral_image(spec_camera->pFrameBuffer, spec_camera->nWidth, spec_camera->nHeight, "Spectral Image"); - // 如果启动了可见光相机 - if (enable_visible_light_camera) - { - visible_light_camera->read(); - visible_light_camera->save(h_visible_light_file, h_header_file); - display_img(visible_light_camera->image_frame, "Camera"); - } - h_header_file << std::endl; - if (h_raw_spectal_file.tellp() > max_file_size) + if (h_raw_spectal_file.tellp() > configs.RAWDATA_MaxSize) { - check_update_file_handle(save_dir, h_raw_spectal_file, h_header_file, max_file_size, h_visible_light_file, enable_visible_light_camera); + check_update_file_handle(configs.RAWDATA_Folder, h_raw_spectal_file, h_header_file, configs.RAWDATA_MaxSize); } if (_kbhit()) @@ -154,8 +118,5 @@ int main() { h_header_file.close(); } - if (h_visible_light_file.is_open()) - { - h_visible_light_file.close(); - } + return 0; } diff --git a/src/utils.cpp b/src/utils.cpp index 0f08571..46b6a31 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -1,3 +1,188 @@ -#include +// #include -const auto t = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); \ No newline at end of file +// const auto t = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + +#include +#include + +#include + +bool AddExePathtoPATH() +{ + /*将当前可执行文件所在的路径添加到环境变量中*/ + wchar_t szPath[512] = {0}; + if (GetModuleFileNameW(NULL, szPath, sizeof(szPath) - 1) == 0) + { + std::cerr << "获取exe文件路径失败." << std::endl; + return false; + } + + std::wstring exe_dir(szPath); + size_t lastSlashIndex = exe_dir.find_last_of('\\'); + if (lastSlashIndex == std::wstring::npos) + { + std::cerr << "获取exe文件路径中的反斜杠失败." << std::endl; + return false; + } + exe_dir = exe_dir.substr(0, lastSlashIndex); + + wchar_t currentPath[32767]; + if (GetEnvironmentVariableW(L"PATH", currentPath, 32767) == 0) + { + std::cerr << "获取当前环境变量PATH失败" << std::endl; + return false; + } + + std::wstring newPath = exe_dir + L";" + std::wstring(currentPath); + if (SetEnvironmentVariableW(L"PATH", newPath.c_str()) == 0) + { + std::cerr << "添加当前路径到环境变量PATH失败" << std::endl; + return false; + } + + return true; +} + +Configs getConfigFromEnvVar() + +{ + /*检查*/ + + Configs configs; + + std::cout << "***********正在检查此程序所需的环境变量************" << std::endl; + + // char buffer[1024]; + // DWORD ret = GetEnvironmentVariableW(L"TEST", buffer, 1024); + wchar_t buffer[32767]; + DWORD result; + try + { + + result = GetEnvironmentVariableW(L"SPECTRUM_deviceTypeIndex", buffer, 32767); + if (result > 0 && result < 32767) + { + configs.SPECTRUM_deviceTypeIndex = std::stoi(std::wstring(buffer)); + std::cout << "光谱相机设备型号索引(SPECTRUM_deviceTypeIndex)为\t" << configs.SPECTRUM_deviceTypeIndex << std::endl; + } + else + { + std::cout << "未获取到光谱相机设备型号索引(SPECTRUM_deviceTypeIndex)" << std::endl; + configs.isEmpty = true; + } + + result = GetEnvironmentVariableW(L"SPECTRUM_FrameRate", buffer, 32767); + if (result > 0 && result < 32767) + { + configs.SPECTRUM_FrameRate = std::stod(std::wstring(buffer)); + std::cout << "光谱相机帧率(SPECTRUM_FrameRate)为\t" << configs.SPECTRUM_FrameRate << std::endl; + } + else + { + std::cout << "未获取到光谱相机帧率(SPECTRUM_FrameRate)" << std::endl; + configs.isEmpty = true; + } + + result = GetEnvironmentVariableW(L"SPECTRUM_ExposureTime", buffer, 32767); + if (result > 0 && result < 32767) + { + configs.SPECTRUM_ExposureTime = std::stod(std::wstring(buffer)); + std::cout << "光谱相机曝光时间(SPECTRUM_ExposureTime)为\t" << configs.SPECTRUM_ExposureTime << std::endl; + } + else + { + std::cout << "未获取到光谱相机曝光时间(SPECTRUM_ExposureTime)" << std::endl; + configs.isEmpty = true; + } + + result = GetEnvironmentVariableW(L"SPECTRUM_BinningSpatial", buffer, 32767); + if (result > 0 && result < 32767) + { + configs.SPECTRUM_BinningSpatial = std::stoi(std::wstring(buffer)); + std::cout << "光谱相机空间像素组合(SPECTRUM_BinningSpatial)为\t" << configs.SPECTRUM_BinningSpatial << std::endl; + } + else + { + std::cout << "未获取到光谱相机空间像素组合(SPECTRUM_BinningSpatial)" << std::endl; + configs.isEmpty = true; + } + + result = GetEnvironmentVariableW(L"SPECTRUM_BinningSpectral", buffer, 32767); + if (result > 0 && result < 32767) + { + configs.SPECTRUM_BinningSpectral = std::stoi(std::wstring(buffer)); + std::cout << "光谱相机光谱像素组合(SPECTRUM_BinningSpectral)为\t" << configs.SPECTRUM_BinningSpectral << std::endl; + } + else + { + std::cout << "未获取到光谱相机光谱像素组合(SPECTRUM_BinningSpectral)" << std::endl; + configs.isEmpty = true; + } + + result = GetEnvironmentVariableW(L"SPECTRUM_BinningAverage", buffer, 32767); + if (result > 0 && result < 32767) + { + + int tmp = std::stoi(std::wstring(buffer)); + configs.SPECTRUM_BinningAverage = tmp; + std::cout << "光谱相机是否组合平均(SPECTRUM_BinningAverage)为\t" << configs.SPECTRUM_BinningAverage << std::endl; + } + else + { + std::cout << "未获取到光谱相机是否组合平均(SPECTRUM_BinningAverage)" << std::endl; + configs.isEmpty = true; + } + + result = GetEnvironmentVariableW(L"SPECTRUM_RingBufferSize", buffer, 32767); + if (result > 0 && result < 32767) + { + configs.SPECTRUM_RingBufferSize = std::stoll(std::wstring(buffer)); + std::cout << "光谱相机循环缓存大小(SPECTRUM_RingBufferSize)为\t" << configs.SPECTRUM_RingBufferSize << std::endl; + } + else + { + std::cout << "未获取到光谱相机循环缓存大小(SPECTRUM_RingBufferSize)" << std::endl; + configs.isEmpty = true; + } + + result = GetEnvironmentVariableW(L"RAWDATA_Folder", buffer, 32767); + if (result > 0 && result < 32767) + { + std::wstring tmp = std::wstring(buffer); + + configs.RAWDATA_Folder = std::string(tmp.begin(), tmp.end()); + // wstring转成string + + std::cout << "原始光谱数据保存路径(RAWDATA_Folder)为\t" << configs.RAWDATA_Folder << std::endl; + } + else + { + std::cout << "未获取到原始数据保存路径(RAWDATA_Folder)" << std::endl; + configs.isEmpty = true; + } + + result = GetEnvironmentVariableW(L"RAWDATA_MaxSize", buffer, 32767); + if (result > 0 && result < 32767) + { + configs.RAWDATA_MaxSize = std::stoull(std::wstring(buffer)); + std::cout << "原始数据文件最大大小(RAWDATA_MaxSize)为\t" << configs.RAWDATA_MaxSize << " Byte" << std::endl; + } + else + { + std::cout << "未获取到原始数据文件最大大小(RAWDATA_MaxSize)" << std::endl; + configs.isEmpty = true; + } + } + catch (const std::invalid_argument &e) + { + std::cerr << "Invalid argument: " << e.what() << std::endl; + configs.isEmpty = true; + } + catch (const std::out_of_range &e) + { + std::cerr << "Out of range: " << e.what() << std::endl; + configs.isEmpty = true; + } + + return configs; +}