diff --git a/CMakeLists.txt b/CMakeLists.txt index 299634d..389c023 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,29 +37,45 @@ include_directories(E:/QTexamble/matrox/Include) link_directories(E:/QTexamble/matrox/LIB) file(GLOB MIL_LIBS E:/QTexamble/matrox/LIB/*.lib) -# 添加可执行文件 cotton_color -add_executable(cotton_color cotton_color.cpp) + +# 添加子目录 +add_subdirectory(src) +add_subdirectory(tests) + +## 添加可执行文件 cotton_color +#add_executable(cotton_color cotton_color.cpp) +## 链接 OpenCV 和 Qt 库 +#target_link_libraries(cotton_color Qt6::Widgets ${OpenCV_LIBS} comdlg32) +# +## 添加可执行文件 cotton_color +#add_executable(cotton_range src/Matrox/color_range.cpp +# src/Matrox/color_range.h src/Matrox/utils.h src/Matrox/utils.cpp) +## 链接 OpenCV 和 Qt 库 +#target_link_libraries(cotton_range Qt6::Widgets ${OpenCV_LIBS} ${MIL_LIBS}) +# +## 添加可执行文件 cotton_color2 +#add_executable(cotton_color2 cotton_color2.cpp) +## 链接 OpenCV 和 Qt 库 +#target_link_libraries(cotton_color2 Qt6::Widgets ${OpenCV_LIBS} ${MIL_LIBS}) +# +#add_executable(template_matching src/Matrox/template_matching.cpp +# src/Matrox/color_range.cpp src/Matrox/color_range.h +# src/Matrox/utils.cpp src/Matrox/utils.h) +#target_link_libraries(template_matching Qt6::Widgets ${OpenCV_LIBS} ${MIL_LIBS}) +# +# +#add_executable(ui src/Matrox/ui.cpp) +#target_link_libraries(ui Qt6::Widgets) +# +# +#add_executable(onnx src/Matrox/onnx_running.cpp) +#target_link_libraries(onnx Qt6::Widgets ${MIL_LIBS}) +# +add_executable(opencv_onnx opencv_onnx.cpp) # 链接 OpenCV 和 Qt 库 -target_link_libraries(cotton_color Qt6::Widgets ${OpenCV_LIBS} comdlg32) - -# 添加可执行文件 cotton_color -add_executable(cotton_range Matrox/color_range.cpp) -# 链接 OpenCV 和 Qt 库 -target_link_libraries(cotton_range Qt6::Widgets ${OpenCV_LIBS} ${MIL_LIBS}) - -# 添加可执行文件 cotton_color2 -add_executable(cotton_color2 cotton_color2.cpp) -# 链接 OpenCV 和 Qt 库 -target_link_libraries(cotton_color2 Qt6::Widgets ${OpenCV_LIBS} ${MIL_LIBS}) - -add_executable(color_matching Matrox/template_matching.cpp) -target_link_libraries(color_matching Qt6::Widgets ${OpenCV_LIBS} ${MIL_LIBS}) - - - -add_executable(ui Matrox/ui.cpp) -target_link_libraries(ui Qt6::Widgets) - - -add_executable(onnx Matrox/onnx_running.cpp) -target_link_libraries(onnx Qt6::Widgets ${MIL_LIBS}) \ No newline at end of file +target_link_libraries(opencv_onnx Qt6::Widgets ${OpenCV_LIBS} comdlg32) +# +# +#add_executable(create_mask src/Matrox/mask.cpp) +#target_link_libraries(create_mask Qt6::Widgets ${OpenCV_LIBS} ${MIL_LIBS}) +#add_executable(test_color_range tests/test_color_range.cpp) diff --git a/Matrox/README.md b/Matrox/README.md deleted file mode 100644 index 0932f19..0000000 --- a/Matrox/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# MIL库环境配置 - -include_directories(E:/QTexamble/matrox/Include) -将路径修改为你的安装目录 .../Matrox Imaging/MIL/Include -# 添加 MIL 库的库文件路径 -link_directories(E:/QTexamble/matrox/LIB) -file(GLOB MIL_LIBS E:/QTexamble/matrox/LIB/*.lib) -同理 将E:/QTexamble/matrox/LIB部分替换为安装目录下的.../Matrox Imaging/MIL/LIB 即可 \ No newline at end of file diff --git a/Matrox/color_range.cpp b/Matrox/color_range.cpp deleted file mode 100644 index e4d93ef..0000000 --- a/Matrox/color_range.cpp +++ /dev/null @@ -1,204 +0,0 @@ -// -// Created by zjc on 24-11-12. -// - -#include -#include -#include -#define IMAGE_PATH MIL_TEXT("C:\\Users\\zjc\\Desktop\\cotton2.bmp") - -// 全局变量,方便在各个函数中使用 -MIL_ID MilApplication = M_NULL, MilSystem = M_NULL, MilDisplay = M_NULL; - - -// 时间测量模板函数 -template -void measureExecutionTime(Func func) { - // 获取当前时间作为起点 - auto start = std::chrono::high_resolution_clock::now(); - - // 执行传入的函数 - func(); - - // 获取当前时间作为结束点 - auto end = std::chrono::high_resolution_clock::now(); - - // 计算时间差并转换为毫秒 - auto duration = std::chrono::duration_cast(end - start); - - std::cout << "Function execution time: " << duration.count() << " milliseconds" << std::endl; -} - -// LabProcess 函数,支持通过参数控制阈值范围,提供默认值 -void LabProcess(MIL_ID& inputImage, MIL_ID& outputImageLab, - MIL_DOUBLE lowerL = 101.0, MIL_DOUBLE upperL = 135.0, - MIL_DOUBLE lowerA = 101.0, MIL_DOUBLE upperA = 120.0, - MIL_DOUBLE lowerB = 95.0, MIL_DOUBLE upperB = 134.0) -{ - MIL_ID MilLabImage = M_NULL, MilLChannel = M_NULL, MilAChannel = M_NULL, MilBChannel = M_NULL; - MIL_ID MilBinaryL = M_NULL, MilBinaryA = M_NULL, MilBinaryB = M_NULL; - - // 检查输入图像的通道数 - MIL_INT NumBands = 0; - MbufInquire(inputImage, M_SIZE_BAND, &NumBands); - if (NumBands != 3) - { - printf("输入图像不是 3 通道图像,请提供彩色图像。\n"); - return; - } - - // 分配用于存储 Lab 图像的缓冲区 - MbufAllocColor(MbufInquire(inputImage, M_OWNER_SYSTEM, M_NULL), 3, - MbufInquire(inputImage, M_SIZE_X, M_NULL), - MbufInquire(inputImage, M_SIZE_Y, M_NULL), - 8 + M_UNSIGNED, - M_IMAGE + M_PROC + M_DISP, - &MilLabImage); - - // 将图像从 sRGB 转换到 Lab - MimConvert(inputImage, MilLabImage, M_SRGB_TO_LAB); - - // 创建 Lab 通道的子缓冲区 - MbufChildColor(MilLabImage, 0, &MilLChannel); - MbufChildColor(MilLabImage, 1, &MilAChannel); - MbufChildColor(MilLabImage, 2, &MilBChannel); - - // 分配二值图像缓冲区 - MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL), - MbufInquire(inputImage, M_SIZE_Y, M_NULL), 8 + M_UNSIGNED, - M_IMAGE + M_PROC + M_DISP, &MilBinaryL); - MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL), - MbufInquire(inputImage, M_SIZE_Y, M_NULL), 8 + M_UNSIGNED, - M_IMAGE + M_PROC + M_DISP, &MilBinaryA); - MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL), - MbufInquire(inputImage, M_SIZE_Y, M_NULL), 8 + M_UNSIGNED, - M_IMAGE + M_PROC + M_DISP, &MilBinaryB); - - // 对每个通道进行阈值分割 - MimBinarize(MilLChannel, MilBinaryL, M_IN_RANGE, lowerL, upperL); - MimBinarize(MilAChannel, MilBinaryA, M_IN_RANGE, lowerA, upperA); - MimBinarize(MilBChannel, MilBinaryB, M_IN_RANGE, lowerB, upperB); - - // 分配输出图像缓冲区 - MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL), - MbufInquire(inputImage, M_SIZE_Y, M_NULL), 8 + M_UNSIGNED, - M_IMAGE + M_PROC + M_DISP, &outputImageLab); - - // 将结果合并 - MimArith(MilBinaryL, MilBinaryA, outputImageLab, M_AND); - MimArith(outputImageLab, MilBinaryB, outputImageLab, M_AND); - - // 释放资源 - MbufFree(MilBinaryL); - MbufFree(MilBinaryA); - MbufFree(MilBinaryB); - MbufFree(MilLChannel); - MbufFree(MilAChannel); - MbufFree(MilBChannel); - MbufFree(MilLabImage); -} - -// HSVProcess 函数,支持通过参数控制饱和度阈值,提供默认值 -void HSVProcess(MIL_ID& inputImage, MIL_ID& outputImageHSV, MIL_DOUBLE saturationThreshold = 120.0) -{ - MIL_ID MilHSVImage = M_NULL, MilHChannel = M_NULL, MilSChannel = M_NULL, MilVChannel = M_NULL; - - // 检查输入图像的通道数 - MIL_INT NumBands = 0; - MbufInquire(inputImage, M_SIZE_BAND, &NumBands); - if (NumBands != 3) - { - printf("输入图像不是 3 通道图像,请提供彩色图像。\n"); - return; - } - - // 分配用于存储 HSV 图像的缓冲区 - MbufAllocColor(MbufInquire(inputImage, M_OWNER_SYSTEM, M_NULL), 3, - MbufInquire(inputImage, M_SIZE_X, M_NULL), - MbufInquire(inputImage, M_SIZE_Y, M_NULL), - 8 + M_UNSIGNED, - M_IMAGE + M_PROC + M_DISP, - &MilHSVImage); - - // 将图像从 sRGB 转换到 HSV - MimConvert(inputImage, MilHSVImage, M_RGB_TO_HSV); - - // 创建 HSV 通道的子缓冲区 - MbufChildColor(MilHSVImage, 0, &MilHChannel); - MbufChildColor(MilHSVImage, 1, &MilSChannel); - MbufChildColor(MilHSVImage, 2, &MilVChannel); - - // 分配输出图像缓冲区 - MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL), - MbufInquire(inputImage, M_SIZE_Y, M_NULL), 8 + M_UNSIGNED, - M_IMAGE + M_PROC + M_DISP, &outputImageHSV); - - // 对 S 通道进行阈值分割 - MimBinarize(MilSChannel, outputImageHSV, M_GREATER, saturationThreshold, M_NULL); - - // 释放资源 - MbufFree(MilHChannel); - MbufFree(MilSChannel); - MbufFree(MilVChannel); - MbufFree(MilHSVImage); -} - -// 综合测试函数,调用 LabProcess 和 HSVProcess 并合并结果 -void test_hsv(MIL_ID& inputImage, - MIL_DOUBLE lowerL = 101.0, MIL_DOUBLE upperL = 135.0, - MIL_DOUBLE lowerA = 101.0, MIL_DOUBLE upperA = 120.0, - MIL_DOUBLE lowerB = 95.0, MIL_DOUBLE upperB = 134.0, - MIL_DOUBLE saturationThreshold = 120.0) -{ - MIL_ID MilResultLab = M_NULL, MilResultHSV = M_NULL, MilCombinedResult = M_NULL; - - // 调用 LabProcess - LabProcess(inputImage, MilResultLab, lowerL, upperL, lowerA, upperA, lowerB, upperB); - - // 调用 HSVProcess - HSVProcess(inputImage, MilResultHSV, saturationThreshold); - - // 分配合并结果的缓冲区 - MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL), - MbufInquire(inputImage, M_SIZE_Y, M_NULL), 8 + M_UNSIGNED, - M_IMAGE + M_PROC + M_DISP, &MilCombinedResult); - - // 合并 Lab 和 HSV 的结果(取“或”运算) - MimArith(MilResultLab, MilResultHSV, MilCombinedResult, M_OR); - - //// 显示合并后的结果图像 - MdispSelect(MilDisplay, MilCombinedResult); - - //// 等待用户查看处理后的图像 - printf("图像已处理并合并,按下 退出程序。\n"); - getchar(); - - // 释放资源 - MbufFree(MilResultLab); - MbufFree(MilResultHSV); - MbufFree(MilCombinedResult); -} - - -int main() -{ - MIL_ID MilImage = M_NULL; - - // 初始化 MIL 应用程序 - MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, &MilDisplay, M_NULL, M_NULL); - - // 加载输入图像 - MbufRestore(IMAGE_PATH, MilSystem, &MilImage); - - // 使用 lambda 表达式测量 test_hsv() 的执行时间 - measureExecutionTime([&]() { - test_hsv(MilImage); - }); - - - // 释放资源 - MbufFree(MilImage); - MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL); - - return 0; -} \ No newline at end of file diff --git a/Matrox/color_range.h b/Matrox/color_range.h deleted file mode 100644 index 8a567e9..0000000 --- a/Matrox/color_range.h +++ /dev/null @@ -1,8 +0,0 @@ -// -// Created by zjc on 24-11-12. -// - -#ifndef COLOR_RANGE_H -#define COLOR_RANGE_H - -#endif //COLOR_RANGE_H diff --git a/Matrox/template_matching.cpp b/Matrox/template_matching.cpp deleted file mode 100644 index ededb56..0000000 --- a/Matrox/template_matching.cpp +++ /dev/null @@ -1,222 +0,0 @@ - - -#include -//#include // 添加此行 -#include - -/* Example functions declarations. */ -void SingleModelExample(MIL_ID MilSystem, MIL_ID MilDisplay); - -/*****************************************************************************/ -/* Main. -******************************************************************************/ -int MosMain(void) -{ - MIL_ID MilApplication, /* Application identifier. */ - MilSystem, /* System Identifier. */ - MilDisplay; /* Display identifier. */ - - /* Allocate defaults. */ - MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, &MilDisplay, M_NULL, M_NULL); - - /* Run single model example. */ - SingleModelExample(MilSystem, MilDisplay); - - /* Free defaults. */ - MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL); - - return 0; -} - -/*****************************************************************************/ -/* Single model example. */ - -/* Source MIL image file specifications. */ -#define SINGLE_MODEL_IMAGE MIL_TEXT("C:\\Users\\zjc\\Desktop\\diguandai2.png") // 替换为您的模板RGB图像文件路径 - -/* Target MIL image file specifications. */ -#define SINGLE_MODEL_TARGET_IMAGE MIL_TEXT ("C:\\Users\\zjc\\Desktop\\diguandai.png") // 替换为您的待检测RGB图像文件路径 - -/* Search speed: M_VERY_HIGH for faster search, M_MEDIUM for precision and robustness. */ -#define SINGLE_MODEL_SEARCH_SPEED M_LOW - -/* Model specifications. */ -#define MODEL_OFFSETX 3200L // 根据您的模板图像调整 -#define MODEL_OFFSETY 550L // 根据您的模板图像调整 -#define MODEL_SIZEX 200L // 根据您的模板图像调整 -#define MODEL_SIZEY 200L // 根据您的模板图像调整 -#define MODEL_MAX_OCCURRENCES 6L - -void SingleModelExample(MIL_ID MilSystem, MIL_ID MilDisplay) -{ - clock_t start_time = clock(); - - MIL_ID MilColorImage, /* 彩色图像缓冲区标识符。*/ - MilImage, /* 灰度图像缓冲区标识符。*/ - GraphicList; /* 图形列表标识符。*/ - MIL_ID MilSearchContext, /* 搜索上下文。*/ - MilResult; /* 结果标识符。*/ - MIL_DOUBLE ModelDrawColor = M_COLOR_RED; /* 模板绘制颜色。*/ - MIL_INT Model[MODEL_MAX_OCCURRENCES], /* 模板索引。*/ - NumResults = 0L; /* 找到的结果数量。*/ - MIL_DOUBLE Score[MODEL_MAX_OCCURRENCES], /* 模板匹配得分。*/ - XPosition[MODEL_MAX_OCCURRENCES], /* 模板X位置。*/ - YPosition[MODEL_MAX_OCCURRENCES], /* 模板Y位置。*/ - Angle[MODEL_MAX_OCCURRENCES], /* 模板角度。*/ - Scale[MODEL_MAX_OCCURRENCES], /* 模板缩放。*/ - Time = 0.0; /* 计时变量。*/ - int i; /* 循环变量。*/ - - - /* 加载RGB模板图像。 */ - MbufRestore(SINGLE_MODEL_IMAGE, MilSystem, &MilColorImage); - - /* 获取图像尺寸。 */ - MIL_INT Width = MbufInquire(MilColorImage, M_SIZE_X, M_NULL); - MIL_INT Height = MbufInquire(MilColorImage, M_SIZE_Y, M_NULL); - - /* 分配灰度图像缓冲区。 */ - MbufAlloc2d(MilSystem, Width, Height, 8 + M_UNSIGNED, M_IMAGE + M_PROC + M_DISP, &MilImage); - - /* 将RGB图像转换为灰度图像。 */ - MimConvert(MilColorImage, MilImage, M_RGB_TO_L); - - /* 选择灰度图像进行显示。 */ - MdispSelect(MilDisplay, MilImage); - - /* 释放彩色图像缓冲区。 */ - MbufFree(MilColorImage); - - /* Allocate a graphic list to hold the subpixel annotations to draw. */ - MgraAllocList(MilSystem, M_DEFAULT, &GraphicList); - - /* Associate the graphic list to the display for annotations. */ - MdispControl(MilDisplay, M_ASSOCIATED_GRAPHIC_LIST_ID, GraphicList); - - /* Allocate a Geometric Model Finder context. */ - MmodAlloc(MilSystem, M_GEOMETRIC, M_DEFAULT, &MilSearchContext); - - /* Allocate a result buffer. */ - MmodAllocResult(MilSystem, M_DEFAULT, &MilResult); - - /* Define the model. */ - MmodDefine(MilSearchContext, M_IMAGE, MilImage, - MODEL_OFFSETX, MODEL_OFFSETY, MODEL_SIZEX, MODEL_SIZEY); - - /* Set the search speed. */ - MmodControl(MilSearchContext, M_CONTEXT, M_SPEED, SINGLE_MODEL_SEARCH_SPEED); - - /* Preprocess the search context. */ - MmodPreprocess(MilSearchContext, M_DEFAULT); - - /* Draw box and position it in the source image to show the model. */ - MgraColor(M_DEFAULT, ModelDrawColor); - MmodDraw(M_DEFAULT, MilSearchContext, GraphicList, - M_DRAW_BOX + M_DRAW_POSITION, 0, M_ORIGINAL); - clock_t end_time = clock(); - std::cout << "The run time is: " << (double)(end_time - start_time) / CLOCKS_PER_SEC << "s"; - /* Pause to show the model. */ - MosPrintf(MIL_TEXT("\nGEOMETRIC MODEL FINDER:\n")); - MosPrintf(MIL_TEXT("-----------------------\n\n")); - MosPrintf(MIL_TEXT("A model context was defined with ")); - MosPrintf(MIL_TEXT("the model in the displayed image.\n")); - MosPrintf(MIL_TEXT("Press to continue.\n\n")); - MosGetch(); - - /* Clear annotations. */ - MgraClear(M_DEFAULT, GraphicList); - - /* 加载RGB待检测图像。 */ - MbufRestore(SINGLE_MODEL_TARGET_IMAGE, MilSystem, &MilColorImage); - - /* 确保待检测图像的尺寸与模板图像一致。 */ - MIL_INT TargetWidth = MbufInquire(MilColorImage, M_SIZE_X, M_NULL); - MIL_INT TargetHeight = MbufInquire(MilColorImage, M_SIZE_Y, M_NULL); - - /* 如果尺寸不同,需要重新分配灰度图像缓冲区。 */ - if (TargetWidth != Width || TargetHeight != Height) - { - /* 释放之前的灰度图像缓冲区。 */ - MbufFree(MilImage); - - /* 分配新的灰度图像缓冲区。 */ - MbufAlloc2d(MilSystem, TargetWidth, TargetHeight, 8 + M_UNSIGNED, M_IMAGE + M_PROC + M_DISP, &MilImage); - - /* 更新宽度和高度。 */ - Width = TargetWidth; - Height = TargetHeight; - } - - /* 将RGB待检测图像转换为灰度图像。 */ - MimConvert(MilColorImage, MilImage, M_RGB_TO_L); - - /* 释放彩色图像缓冲区。 */ - MbufFree(MilColorImage); - - /* 显示灰度待检测图像。 */ - MdispSelect(MilDisplay, MilImage); - - /* Dummy first call for bench measure purpose only (bench stabilization, - cache effect, etc...). This first call is NOT required by the application. */ - MmodFind(MilSearchContext, MilImage, MilResult); - - /* Reset the timer. */ - MappTimer(M_DEFAULT, M_TIMER_RESET + M_SYNCHRONOUS, M_NULL); - - /* Find the model. */ - MmodFind(MilSearchContext, MilImage, MilResult); - - /* Read the find time. */ - MappTimer(M_DEFAULT, M_TIMER_READ + M_SYNCHRONOUS, &Time); - - /* Get the number of models found. */ - MmodGetResult(MilResult, M_DEFAULT, M_NUMBER + M_TYPE_MIL_INT, &NumResults); - - /* If a model was found above the acceptance threshold. */ - if ((NumResults >= 1) && (NumResults <= MODEL_MAX_OCCURRENCES)) - { - /* Get the results of the single model. */ - MmodGetResult(MilResult, M_DEFAULT, M_INDEX + M_TYPE_MIL_INT, Model); - MmodGetResult(MilResult, M_DEFAULT, M_POSITION_X, XPosition); - MmodGetResult(MilResult, M_DEFAULT, M_POSITION_Y, YPosition); - MmodGetResult(MilResult, M_DEFAULT, M_ANGLE, Angle); - MmodGetResult(MilResult, M_DEFAULT, M_SCALE, Scale); - MmodGetResult(MilResult, M_DEFAULT, M_SCORE, Score); - - /* Print the results for each model found. */ - MosPrintf(MIL_TEXT("The model was found in the target image:\n\n")); - MosPrintf(MIL_TEXT("Result Model X Position Y Position ") - MIL_TEXT("Angle Scale Score\n\n")); - for (i = 0; i < NumResults; i++) - { - MosPrintf(MIL_TEXT("%-9d%-8d%-13.2f%-13.2f%-8.2f%-8.2f%-5.2f%%\n"), - i, (int)Model[i], XPosition[i], YPosition[i], - Angle[i], Scale[i], Score[i]); - } - MosPrintf(MIL_TEXT("\nThe search time is %.1f ms\n\n"), Time * 1000.0); - - /* Draw edges, position and box over the occurrences that were found. */ - for (i = 0; i < NumResults; i++) - { - MgraColor(M_DEFAULT, ModelDrawColor); - MmodDraw(M_DEFAULT, MilResult, GraphicList, - M_DRAW_EDGES + M_DRAW_BOX + M_DRAW_POSITION, i, M_DEFAULT); - } - } - else - { - MosPrintf(MIL_TEXT("The model was not found or the number of models ") - MIL_TEXT("found is greater than\n")); - MosPrintf(MIL_TEXT("the specified maximum number of occurrence !\n\n")); - } - - /* Wait for a key to be pressed. */ - MosPrintf(MIL_TEXT("Press to continue.\n\n")); - MosGetch(); - - /* Free MIL objects. */ - MgraFree(GraphicList); - MbufFree(MilImage); - MmodFree(MilSearchContext); - MmodFree(MilResult); -} \ No newline at end of file diff --git a/Matrox/template_matching.h b/Matrox/template_matching.h deleted file mode 100644 index bcbca12..0000000 --- a/Matrox/template_matching.h +++ /dev/null @@ -1,8 +0,0 @@ -// -// Created by zjc on 24-11-12. -// - -#ifndef TEMPLATE_MATCHING_H -#define TEMPLATE_MATCHING_H - -#endif //TEMPLATE_MATCHING_H diff --git a/opencv_onnx.cpp b/opencv_onnx.cpp new file mode 100644 index 0000000..fd7769c --- /dev/null +++ b/opencv_onnx.cpp @@ -0,0 +1,232 @@ +// +// Created by zjc on 24-11-19. +// +#include +#include +#include + +// 参数 +const float CONFIDENCE_THRESHOLD = 0.2; // 置信度阈值 +const float NMS_THRESHOLD = 0.2; // 非极大值抑制阈值 +const int INPUT_WIDTH = 640; // 模型输入宽度 +const int INPUT_HEIGHT = 640; // 模型输入高度 + +// 检测结构体 +struct Detection { + cv::Rect box; + float confidence; +}; +class Timer { +public: + Timer() : start_time(std::chrono::high_resolution_clock::now()) {} + + // 重新启动定时器 + void restart() { + start_time = std::chrono::high_resolution_clock::now(); + } + + // 获取并打印从上次启动到当前的时间差 + void printElapsedTime(const std::string& message) { + auto end_time = std::chrono::high_resolution_clock::now(); + std::chrono::duration elapsed = end_time - start_time; + std::cout << message << ": " << elapsed.count() << " seconds" << std::endl; + // 重新启动定时器以供下次测量 + start_time = end_time; + } + +private: + std::chrono::high_resolution_clock::time_point start_time; +}; + + +// 在图像上绘制检测框 +void drawDetections(cv::Mat& inputImage, const std::vector& detections) { + for (const auto& detection : detections) { + cv::rectangle(inputImage, detection.box, cv::Scalar(0, 255, 0), 2); + std::string label = "Object: " + cv::format("%.2f", detection.confidence); + int baseLine; + cv::Size labelSize = cv::getTextSize(label, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); + cv::rectangle(inputImage, cv::Point(detection.box.x, detection.box.y - labelSize.height - baseLine), + cv::Point(detection.box.x + labelSize.width, detection.box.y), cv::Scalar(0, 255, 0), cv::FILLED); + cv::putText(inputImage, label, cv::Point(detection.box.x, detection.box.y - baseLine), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0), 1); + } +} +cv::Mat resizeAndPad(const cv::Mat& image, int targetWidth, int targetHeight, int& padTop, int& padLeft, float& scale, const cv::Scalar& padColor) { + int originalWidth = image.cols; + int originalHeight = image.rows; + + // 计算缩放比例 + scale = std::min((float)targetWidth / originalWidth, (float)targetHeight / originalHeight); + + // 缩放后的新尺寸 + int newWidth = static_cast(originalWidth * scale); + int newHeight = static_cast(originalHeight * scale); + + // 缩放图像 + cv::Mat resizedImage; + cv::resize(image, resizedImage, cv::Size(newWidth, newHeight)); + + // 计算填充值 + padTop = (targetHeight - newHeight) / 2; + int padBottom = targetHeight - newHeight - padTop; + padLeft = (targetWidth - newWidth) / 2; + int padRight = targetWidth - newWidth - padLeft; + + // 在图像周围添加填充,使用灰色 (128, 128, 128) 填充 + cv::Mat paddedImage; + cv::copyMakeBorder(resizedImage, paddedImage, padTop, padBottom, padLeft, padRight, cv::BORDER_CONSTANT, padColor); + + return paddedImage; +} +int main() { + // 模型路径和图片路径 + std::string modelPath = "C:\\Users\\zjc\\Desktop\\dimo_11.14.onnx"; + std::string imagePath = "C:\\Users\\zjc\\Desktop\\dimo.bmp"; + Timer timer1; + // 加载模型 + cv::dnn::Net net = cv::dnn::readNetFromONNX(modelPath); + net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA); // 设置为使用 CUDA 后端 + net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA); // 设置为在 GPU 上运行 + timer1.printElapsedTime("Time to load the model"); + // 读取输入图像 + + timer1.restart(); + cv::Mat image = cv::imread(imagePath); + if (image.empty()) { + std::cerr << "Could not read the image: " << imagePath << std::endl; + return -1; + } + // 设置填充颜色为灰色 + cv::Scalar padColor(128, 128, 128); + + // 预处理图像并添加填充 + int padTop, padLeft; + float scale; + cv::Mat inputImage = resizeAndPad(image, INPUT_WIDTH, INPUT_HEIGHT, padTop, padLeft, scale, padColor); + + // 显示调整和填充后的图像 + // cv::imshow("Resized and Padded Image", inputImage); + // 预处理图像 + cv::Mat blob = cv::dnn::blobFromImage(inputImage, 1 / 255.0, cv::Size(INPUT_WIDTH, INPUT_HEIGHT), cv::Scalar(0, 0, 0), true, false); + net.setInput(blob); + + timer1.printElapsedTime("Time to preprocessing"); + timer1.restart(); + for(int j = 0; j <1; j++) { + // 推理模型 + cv::Mat output = net.forward(); + + // 处理输出数据 + std::vector detections; + float* data = (float*)output.data; + for (int i = 0; i < 25200; ++i) { + float confidence = data[i * 6 + 4]; // 置信度 + if (confidence >= CONFIDENCE_THRESHOLD) { + // 获取检测框并映射到图像坐标 + // Remove the unnecessary multiplication + float cx = data[i * 6]; + float cy = data[i * 6 + 1]; + float w = data[i * 6 + 2]; + float h = data[i * 6 + 3]; + + // If needed, adjust for differences between input image size and model input size + // Since they are the same in your case, this step can be omitted or kept as is + cx = cx * inputImage.cols / INPUT_WIDTH; + cy = cy * inputImage.rows / INPUT_HEIGHT; + w = w * inputImage.cols / INPUT_WIDTH; + h = h * inputImage.rows / INPUT_HEIGHT; + + // Proceed with the rest of your code + int left = static_cast(cx - w / 2); + int top = static_cast(cy - h / 2); + int width = static_cast(w); + int height = static_cast(h); + + // Ensure coordinates are within image bounds + left = std::max(0, std::min(left, inputImage.cols - 1)); + top = std::max(0, std::min(top, inputImage.rows - 1)); + width = std::min(width, inputImage.cols - left); + height = std::min(height, inputImage.rows - top); + + // Add detection + detections.push_back({cv::Rect(left, top, width, height), confidence}); + + } + } + // 非极大值抑制 + std::vector indices; + std::vector boxes; + std::vector scores; + for (const auto& detection : detections) { + boxes.push_back(detection.box); + + scores.push_back(detection.confidence); + } + cv::dnn::NMSBoxes(boxes, scores, CONFIDENCE_THRESHOLD, NMS_THRESHOLD, indices); + std::cout << "Number of detections after NMS: " << indices.size() << std::endl; + if (indices.empty()) { + std::cout << "No boxes passed NMS." << std::endl; + } + for (int idx : indices) { + Detection detection = detections[idx]; + std::cout << "Drawing box at: (" << detection.box.x << ", " << detection.box.y + << "), width: " << detection.box.width << ", height: " << detection.box.height << std::endl; + drawDetections(inputImage, {detection}); + } + + std::vector finalDetections; + for (int idx : indices) { + finalDetections.push_back(detections[idx]); + } + for (int i = 0; i < 25200; ++i) { + float confidence = data[i * 6 + 4]; + if (confidence >= CONFIDENCE_THRESHOLD) { + // std::cout << "Detection " << i << ": confidence=" << confidence << std::endl; + } + } + + // 绘制检测框并显示图像 + drawDetections(image, finalDetections); + timer1.printElapsedTime("Time to run inference"); + } + int depth = inputImage.depth(); // 图像数据类型 + int channels = inputImage.channels(); // 通道数 + + // 判断图像深度和通道数,打印类型 + std::string depthStr; + switch (depth) { + case CV_8U: + depthStr = "8-bit unsigned integer"; + break; + case CV_8S: + depthStr = "8-bit signed integer"; + break; + case CV_16U: + depthStr = "16-bit unsigned integer"; + break; + case CV_16S: + depthStr = "16-bit signed integer"; + break; + case CV_32S: + depthStr = "32-bit signed integer"; + break; + case CV_32F: + depthStr = "32-bit floating point"; + break; + case CV_64F: + depthStr = "64-bit floating point"; + break; + default: + depthStr = "Unknown depth"; + break; + } + + std::cout << "Image Depth: " << depthStr << std::endl; + std::cout << "Number of Channels: " << channels << std::endl; + + cv::imshow("Detections", inputImage); + cv::waitKey(0); + + return 0; +} +// \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..1d252e6 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,13 @@ +# 定义 Matrox 模块的库 +add_library(Matrox + Matrox/color_range.cpp + Matrox/utils.cpp + Matrox/template_matching.cpp + Matrox/mask.cpp +) + +# 头文件路径 +target_include_directories(Matrox PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +# 链接依赖库 +target_link_libraries(Matrox PUBLIC Qt6::Widgets ${OpenCV_LIBS} ${MIL_LIBS}) diff --git a/src/CVDL/OnnxRunner.cpp b/src/CVDL/OnnxRunner.cpp new file mode 100644 index 0000000..fa89f0f --- /dev/null +++ b/src/CVDL/OnnxRunner.cpp @@ -0,0 +1,5 @@ +// +// Created by zjc on 24-11-26. +// + +#include "OnnxRunner.h" diff --git a/src/CVDL/OnnxRunner.h b/src/CVDL/OnnxRunner.h new file mode 100644 index 0000000..57b2534 --- /dev/null +++ b/src/CVDL/OnnxRunner.h @@ -0,0 +1,16 @@ +// +// Created by zjc on 24-11-26. +// + +#ifndef ONNXRUNNER_H +#define ONNXRUNNER_H + + + +class OnnxRunner { + +}; + + + +#endif //ONNXRUNNER_H diff --git a/src/Matrox/README.md b/src/Matrox/README.md new file mode 100644 index 0000000..c45ed5d --- /dev/null +++ b/src/Matrox/README.md @@ -0,0 +1,93 @@ +# MIL库环境配置 + +include_directories(E:/QTexamble/matrox/Include) +将路径修改为你的安装目录 .../Matrox Imaging/MIL/Include +# 添加 MIL 库的库文件路径 +link_directories(E:/QTexamble/matrox/LIB) +file(GLOB MIL_LIBS E:/QTexamble/matrox/LIB/*.lib) +同理 将E:/QTexamble/matrox/LIB部分替换为安装目录下的.../Matrox Imaging/MIL/LIB 即可 + + +## 鲜艳色彩检测功能 + +对应函数: + +```c++ +void lab_process(const MIL_ID& inputImage, MIL_ID& outputImageLab, const std::map& params); +// 用法 +// std::map params; +// params["saturation_threshold"] = 150; +// params["saturation_denoising"] = 2; + +void hsv_process(const MIL_ID& inputImage, MIL_ID& outputImageHSV, const std::map& params); +// std::map params; +// params["green_L_min"] = 68; +// params["green_L_max"] = 125; +// params["green_a_min"] = 101; +// params["green_a_max"] = 120; +// params["green_b_min"] = 130; +// params["green_b_max"] = 140; +// +// params["blue_L_min"] = 45; +// params["blue_L_max"] = 66; +// params["blue_a_min"] = 130; +// params["blue_a_max"] = 145; +// params["blue_b_min"] = 95; +// params["blue_b_max"] = 105; +// +// params["orange_L_min"] = 166; +// params["orange_L_max"] = 191; +// params["orange_a_min"] = 135; +// params["orange_a_max"] = 142; +// params["orange_b_min"] = 160; +// params["orange_b_max"] = 174; +// +// params["black_L_min"] = 0; +// params["black_L_max"] = 21; +// params["black_a_min"] = 127; +// params["black_a_max"] = 133; +// params["black_b_min"] = 126; +// params["black_b_max"] = 134; +// +// params["red_L_min"] = 71; +// params["red_L_max"] = 97; +// params["red_a_min"] = 143; +// params["red_a_max"] = 153; +// params["red_b_min"] = 33; +// params["red_b_max"] = 154; +// +// params["purple_L_min"] = 171; +// params["purple_L_max"] = 197; +// params["purple_a_min"] = 131; +// params["purple_a_max"] = 141; +// params["purple_b_min"] = 108; +// params["purple_b_max"] = 123; +// params["lab_denoising"] = 1; + +``` + +| | hsv_denoising = 0 | hsv_denoising = 1 | hsv_denoising = 2 | +| ----------------- | ----------------- | ----------------- | ------------------------------------------- | +| lab_denoising = 0 | | | | +| lab_denoising = 1 | | | ![diguandai](./README.assets/diguandai.png) | +| lab_denoising = 2 | | | | + + +这些是经过实验后的推荐参数: + +| | L_min | L_max | a_min | a_max | b_min | b_max | +| ------ | ----- | ----- | ----- | ----- | ----- | ----- | +| green | 27 | 49 | -27 | -8 | 2 | 12 | +| blue | 18 | 26 | 2 | 17 | -33 | -23 | +| orange | 65 | 75 | 7 | 14 | 32 | 46 | +| black | 0 | 8 | -1 | 5 | -2 | 6 | +| red | 28 | 38 | 15 | 25 | -95 | 26 | +| purple | 67 | 77 | 3 | 13 | -20 | -5 | + + +### utils模块包含的工具函数 +1.模型图片路径格式转换 +2.uint1转uint8图片函数 +3.ps和opencv阈值相互转换函数 +4.读取配置文件函数 + diff --git a/src/Matrox/color_range.cpp b/src/Matrox/color_range.cpp new file mode 100644 index 0000000..10674cd --- /dev/null +++ b/src/Matrox/color_range.cpp @@ -0,0 +1,202 @@ +#include +#include +#include +#include +#include "utils.h" + + +// Optimized LabProcess function +void lab_process_raw(const MIL_ID& inputImage, MIL_ID& outputImageLab, const std::map& params, + const std::vector& color_vector) +{ + MIL_ID MilLabImage = M_NULL, MilLChannel = M_NULL, MilAChannel = M_NULL, MilBChannel = M_NULL; + MIL_ID lab_result=M_NULL; + + int denoising = params.at("lab_denoising"); + + + // Check number of bands + MIL_INT NumBands = 0; + MbufInquire(inputImage, M_SIZE_BAND, &NumBands); + if (NumBands != 3) + { + printf("输入图像不是 3 通道图像,请提供彩色图像。\n"); + return; + } + + // Inquire image properties once + MIL_ID MilSystem = MbufInquire(inputImage, M_OWNER_SYSTEM, M_NULL); + MIL_INT SizeX = MbufInquire(inputImage, M_SIZE_X, M_NULL); + MIL_INT SizeY = MbufInquire(inputImage, M_SIZE_Y, M_NULL); + + // Allocate buffer for Lab image + MbufAllocColor(MilSystem, 3, SizeX, SizeY, 8 + M_UNSIGNED, M_IMAGE + M_PROC, &MilLabImage); + + // Convert image from sRGB to Lab + MimConvert(inputImage, MilLabImage, M_SRGB_TO_LAB); + + // Create child buffers for L, a, b channels + MbufChildColor(MilLabImage, 0, &MilLChannel); + MbufChildColor(MilLabImage, 1, &MilAChannel); + MbufChildColor(MilLabImage, 2, &MilBChannel); + + // Allocate output image as 1-bit image + MbufAlloc2d(MilSystem, SizeX, SizeY, 1 + M_UNSIGNED, M_IMAGE + M_PROC, &outputImageLab); + MbufClear(outputImageLab, 0); // Initialize to 0 + + // Pre-allocate binary buffers as 1-bit images + MIL_ID MilBinaryL = M_NULL, MilBinaryA = M_NULL, MilBinaryB = M_NULL, MilResultLab = M_NULL; + MbufAlloc2d(MilSystem, SizeX, SizeY, 1 + M_UNSIGNED, M_IMAGE + M_PROC, &MilBinaryL); + MbufAlloc2d(MilSystem, SizeX, SizeY, 1 + M_UNSIGNED, M_IMAGE + M_PROC, &MilBinaryA); + MbufAlloc2d(MilSystem, SizeX, SizeY, 1 + M_UNSIGNED, M_IMAGE + M_PROC, &MilBinaryB); + MbufAlloc2d(MilSystem, SizeX, SizeY, 1 + M_UNSIGNED, M_IMAGE + M_PROC, &MilResultLab); + MbufAlloc2d(MilSystem, SizeX, SizeY, 1 + M_UNSIGNED, M_IMAGE + M_PROC, &lab_result); + + + // Iterate over colors + // 遍历颜色 + for (const auto& color : color_vector) { + // 构建参数键 + std::string L_min_key = color + "_L_min"; + std::string L_max_key = color + "_L_max"; + std::string a_min_key = color + "_a_min"; + std::string a_max_key = color + "_a_max"; + std::string b_min_key = color + "_b_min"; + std::string b_max_key = color + "_b_max"; + + // 获取参数值 + int L_min = params.at(L_min_key); + int L_max = params.at(L_max_key); + int a_min = params.at(a_min_key); + int a_max = params.at(a_max_key); + int b_min = params.at(b_min_key); + int b_max = params.at(b_max_key); + std::vector lab_min_ps = {L_min, a_min, b_min}; + std::vector lab_max_ps = {L_max, a_max, b_max}; + + std::vector lab_min_cv = psLabToOpenCVLab(lab_min_ps); + std::vector lab_max_cv = psLabToOpenCVLab(lab_max_ps); + + L_min = lab_min_cv[0]; + L_max = lab_max_cv[0]; + a_min = lab_min_cv[1]; + a_max = lab_max_cv[1]; + b_min = lab_min_cv[2]; + b_max = lab_max_cv[2]; + + // 对每个通道进行二值化 + MimBinarize(MilLChannel, MilBinaryL, M_IN_RANGE, L_min, L_max); + MimBinarize(MilAChannel, MilBinaryA, M_IN_RANGE, a_min, a_max); + MimBinarize(MilBChannel, MilBinaryB, M_IN_RANGE, b_min, b_max); + + // 合并阈值结果 + MimArith(MilBinaryL, MilBinaryA, MilResultLab, M_AND); + MimArith(MilResultLab, MilBinaryB, MilResultLab, M_AND); + + // 与输出图像合并 + MimArith(lab_result, MilResultLab, lab_result, M_OR); + + } + MimClose(lab_result, MilResultLab, denoising, M_BINARY); + MimOpen(MilResultLab, outputImageLab, denoising, M_BINARY); + + // Free binary buffers + MbufFree(MilBinaryL); + MbufFree(MilBinaryA); + MbufFree(MilBinaryB); + MbufFree(MilResultLab); + + // Free resources + MbufFree(MilLChannel); + MbufFree(MilAChannel); + MbufFree(MilBChannel); + MbufFree(MilLabImage); + MbufFree(lab_result); +} + + +void lab_process(const MIL_ID& inputImage, MIL_ID& outputImageLab, const std::map& params) { + const std::vector colors = {"green", "blue", "orange", "black", "red", "purple"}; + lab_process_raw(inputImage, outputImageLab, params, colors); +} + + +void hsv_process(const MIL_ID& inputImage, MIL_ID& outputImageHSV, const std::map& params) +{ + MIL_ID MilHSVImage = M_NULL, MilHChannel = M_NULL, MilSChannel = M_NULL, MilVChannel = M_NULL; + MIL_ID hsv_result = M_NULL; + MIL_ID hsv_denoising = M_NULL; + int saturationThreshold = params.at("saturation_threshold"); + int denoising = params.at("saturation_denoising"); + + // 检查输入图像的通道数 + MIL_INT NumBands = 0; + MbufInquire(inputImage, M_SIZE_BAND, &NumBands); + if (NumBands != 3) + { + printf("输入图像不是 3 通道图像,请提供彩色图像。\n"); + return; + } + + // 分配用于存储 HSV 图像的缓冲区 + MbufAllocColor(MbufInquire(inputImage, M_OWNER_SYSTEM, M_NULL), 3, + MbufInquire(inputImage, M_SIZE_X, M_NULL), + MbufInquire(inputImage, M_SIZE_Y, M_NULL), + 8 + M_UNSIGNED, + M_IMAGE + M_PROC + M_DISP, + &MilHSVImage); + + // 将图像从 sRGB 转换到 HSV + MimConvert(inputImage, MilHSVImage, M_RGB_TO_HSV); + + // 创建 HSV 通道的子缓冲区 + MbufChildColor(MilHSVImage, 0, &MilHChannel); + MbufChildColor(MilHSVImage, 1, &MilSChannel); + MbufChildColor(MilHSVImage, 2, &MilVChannel); + + // 分配输出图像缓冲区 + MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL), + MbufInquire(inputImage, M_SIZE_Y, M_NULL), 1 + M_UNSIGNED, + M_IMAGE + M_PROC + M_DISP, &hsv_result); + MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL), + MbufInquire(inputImage, M_SIZE_Y, M_NULL), 1 + M_UNSIGNED, + M_IMAGE + M_PROC + M_DISP, &hsv_denoising); + MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL), + MbufInquire(inputImage, M_SIZE_Y, M_NULL), 1 + M_UNSIGNED, + M_IMAGE + M_PROC + M_DISP, &outputImageHSV); + + // 对 S 通道进行阈值分割 + MimBinarize(MilSChannel, hsv_result, M_GREATER, + saturationThreshold, M_NULL); + + MimClose(hsv_result, hsv_denoising, denoising, M_BINARY); + MimOpen(hsv_denoising, outputImageHSV, denoising, M_BINARY); + + // 释放资源 + MbufFree(MilHChannel); + MbufFree(MilSChannel); + MbufFree(MilVChannel); + MbufFree(MilHSVImage); + MbufFree(hsv_result); + MbufFree(hsv_denoising); +} + + +void high_sat_detect(const MIL_ID& inputImage, MIL_ID& outputImage, const std::map& params) { + MIL_ID output_hsv=M_NULL, output_lab=M_NULL; + + hsv_process(inputImage, output_hsv, params); + lab_process(inputImage, output_lab, params); + + MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL), + MbufInquire(inputImage, M_SIZE_Y, M_NULL), 1 + M_UNSIGNED, + M_IMAGE + M_PROC, &outputImage); + + // 合并 Lab 和 HSV 的结果(取“或”运算) + MimArith(output_hsv, output_lab, outputImage, M_OR); + + MbufFree(output_lab); + MbufFree(output_hsv); +} + + diff --git a/src/Matrox/color_range.h b/src/Matrox/color_range.h new file mode 100644 index 0000000..d959163 --- /dev/null +++ b/src/Matrox/color_range.h @@ -0,0 +1,69 @@ +// +// Created by zjc on 24-11-12. +// + +#ifndef COLOR_RANGE_H +#define COLOR_RANGE_H + +#include +#include +#include + +void lab_process(const MIL_ID& inputImage, MIL_ID& outputImageLab, const std::map& params); +// 用法 +// std::map params; +// params["saturation_threshold"] = 150; + +void hsv_process(const MIL_ID& inputImage, MIL_ID& outputImageHSV, const std::map& params); +// 用法 +// std::map params; +// params["green_L_min"] = 68; +// params["green_L_max"] = 125; +// params["green_a_min"] = 101; +// params["green_a_max"] = 120; +// params["green_b_min"] = 130; +// params["green_b_max"] = 140; +// +// params["blue_L_min"] = 45; +// params["blue_L_max"] = 66; +// params["blue_a_min"] = 130; +// params["blue_a_max"] = 145; +// params["blue_b_min"] = 95; +// params["blue_b_max"] = 105; +// +// params["orange_L_min"] = 166; +// params["orange_L_max"] = 191; +// params["orange_a_min"] = 135; +// params["orange_a_max"] = 142; +// params["orange_b_min"] = 160; +// params["orange_b_max"] = 174; +// +// params["black_L_min"] = 0; +// params["black_L_max"] = 21; +// params["black_a_min"] = 127; +// params["black_a_max"] = 133; +// params["black_b_min"] = 126; +// params["black_b_max"] = 134; +// +// params["red_L_min"] = 71; +// params["red_L_max"] = 97; +// params["red_a_min"] = 143; +// params["red_a_max"] = 153; +// params["red_b_min"] = 33; +// params["red_b_max"] = 154; +// +// params["purple_L_min"] = 171; +// params["purple_L_max"] = 197; +// params["purple_a_min"] = 131; +// params["purple_a_max"] = 141; +// params["purple_b_min"] = 108; +// params["purple_b_max"] = 123; +// + +void lab_process_raw(const MIL_ID& inputImage, MIL_ID& outputImageLab, const std::map& params, + const std::vector& color_vector); +// 新增了可自定义的色彩矩阵 + +void high_sat_detect(const MIL_ID& inputImage, MIL_ID& outputImage, const std::map& params); + +#endif //COLOR_RANGE_H diff --git a/src/Matrox/mask.cpp b/src/Matrox/mask.cpp new file mode 100644 index 0000000..e564bfa --- /dev/null +++ b/src/Matrox/mask.cpp @@ -0,0 +1,53 @@ + +#include "mask.h" +// 读取二值化的单通道一位图片并生成掩膜 +std::vector> generateMaskFromImage(const std::string& imagePath, int widthBlocks, int heightBlocks, int threshold = 10) { + // 读取图像 + cv::Mat image = cv::imread(imagePath, cv::IMREAD_GRAYSCALE); + + // 检查图像是否成功读取 + if (image.empty()) { + std::cerr << "无法加载图像,请检查路径是否正确: " << imagePath << std::endl; + exit(EXIT_FAILURE); + } + + // 确保图像是二值化的 + cv::threshold(image, image, 128, 255, cv::THRESH_BINARY); + + // 获取图像的宽度和高度 + int imageWidth = image.cols; + int imageHeight = image.rows; + + // 计算每个块的宽度和高度 + int blockWidth = imageWidth / widthBlocks; + int blockHeight = imageHeight / heightBlocks; + + // 创建掩膜矩阵 + std::vector> mask(heightBlocks, std::vector(widthBlocks, false)); + + // 遍历每个块并统计白色像素点的数量 + for (int i = 0; i < heightBlocks; ++i) { + for (int j = 0; j < widthBlocks; ++j) { + // 计算块的起始和结束位置 + int x_start = j * blockWidth; + int y_start = i * blockHeight; + int x_end = (j == widthBlocks - 1) ? imageWidth : (j + 1) * blockWidth; + int y_end = (i == heightBlocks - 1) ? imageHeight : (i + 1) * blockHeight; + + // 提取当前块 + cv::Mat block = image(cv::Rect(x_start, y_start, x_end - x_start, y_end - y_start)); + + // 统计块中白色像素的数量 + int whitePixelCount = cv::countNonZero(block); + + // 如果白色像素数大于阈值,将该块标记为 true + if (whitePixelCount > threshold) { + mask[i][j] = true; + } + } + } + + return mask; +} + + diff --git a/src/Matrox/mask.h b/src/Matrox/mask.h new file mode 100644 index 0000000..fee2b3e --- /dev/null +++ b/src/Matrox/mask.h @@ -0,0 +1,16 @@ +// +// Created by zjc on 24-11-26. +// + + +#ifndef MASK_H +#define MASK_H + +#include +#include +#include + +std::vector> generateMaskFromImage(const std::string& imagePath, int widthBlocks, int heightBlocks, int threshold); + + +#endif //MASK_H diff --git a/Matrox/onnx_running.cpp b/src/Matrox/onnx_running.cpp similarity index 82% rename from Matrox/onnx_running.cpp rename to src/Matrox/onnx_running.cpp index c5e6892..bbcee7a 100644 --- a/Matrox/onnx_running.cpp +++ b/src/Matrox/onnx_running.cpp @@ -13,9 +13,9 @@ #include // Path definitions. -#define EXAMPLE_ONNX_MODEL_PATH MIL_TEXT("C:\\Users\\zjc\\source\\repos\\cotton_color\\Matrox\\models\\2024_11_12_imgsz640_batch1.onnx") -#define TARGET_IMAGE_DIR_PATH MIL_TEXT("C:\\Users\\zjc\\Desktop\\dimo2.mim") -#define IMAGE_FILE MIL_TEXT("C:\\Users\\zjc\\Desktop\\dimo2.bmp") +#define EXAMPLE_ONNX_MODEL_PATH MIL_TEXT("C:\\Users\\zjc\\Desktop\\WeChat Files\\wxid_ipl8u0ctajtn22\\FileStorage\\File\\2024-11\\2024_11_12_imgsz640_batch1(1).onnx") +#define TARGET_IMAGE_DIR_PATH MIL_TEXT("C:\\Users\\zjc\\Desktop\\dimo4.mim") + int MosMain(void) { @@ -31,14 +31,6 @@ int MosMain(void) MsysAlloc(M_DEFAULT, M_SYSTEM_DEFAULT, M_DEFAULT, M_DEFAULT, &MilSystem); MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_DEFAULT, &MilDisplay); - MIL_UNIQUE_BUF_ID dimo2; - MbufImport(IMAGE_FILE, M_DEFAULT, M_RESTORE+M_NO_GRAB+M_NO_COMPRESS, MilSystem, &dimo2); - //MIL_UNIQUE_BUF_ID MimArithdestination = MbufClone(dimo2, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_UNIQUE_ID); - MIL_UNIQUE_BUF_ID MimArithDestination = MbufAllocColor(MilSystem, 3, 640, 640, 32 + M_FLOAT, M_IMAGE + M_PROC, M_UNIQUE_ID); - // Post-Alloc Block for MimArith's destination - MbufClear(MimArithDestination, M_COLOR_BLACK); - - MimArith(dimo2, 255.0, MimArithDestination, M_DIV_CONST); // Load the image into memory. if (MbufRestore(TARGET_IMAGE_DIR_PATH, MilSystem, &MilImage) != M_NULL) @@ -51,7 +43,6 @@ int MosMain(void) return 1; // Exit if the image loading failed } - MdispSelect(MilDisplay, MimArithDestination); // MbufInquire(MilImage, , NULL); @@ -70,7 +61,7 @@ int MosMain(void) // Perform object detection on the image using MclassPredict. - MclassPredict(DetectCtx, MimArithDestination, DetectRes, M_DEFAULT); + MclassPredict(DetectCtx, MilImage, DetectRes, M_DEFAULT); MosPrintf(MIL_TEXT("Object detection completed.\n")); diff --git a/Matrox/onnx_running.h b/src/Matrox/onnx_running.h similarity index 100% rename from Matrox/onnx_running.h rename to src/Matrox/onnx_running.h diff --git a/src/Matrox/template_matching.cpp b/src/Matrox/template_matching.cpp new file mode 100644 index 0000000..bf6132b --- /dev/null +++ b/src/Matrox/template_matching.cpp @@ -0,0 +1,283 @@ +#include +#include +#include +#include "color_range.h" +#include "utils.h" +#include"template_matching.h" +using namespace std; + +void pre_process(const MIL_ID& inputImage, MIL_ID& outputImageSuspect, const map& params) { + // 异色检测, 检测出不同与棉花颜色的物体作为模板匹配的对象 + const vector colors = {"cotton", "background"}; + map param_temp = params; + param_temp["lab_denoising"] = param_temp["cotton_denoising"]; + param_temp["saturation_threshold"] = param_temp["cotton_saturation_threshold"]; + param_temp["saturation_denoising"] = param_temp["cotton_saturation_denoising"]; + lab_process_raw(inputImage, outputImageSuspect, param_temp, colors); + MimArith(outputImageSuspect, M_NULL, outputImageSuspect, M_NOT); +} + +TemplateMatcher::TemplateMatcher(MIL_ID system, MIL_ID display, std::map& param) + : MilSystem(system), MilDisplay(display), isInitialized(false), param(param) +{ +} + +// Destructor +TemplateMatcher::~TemplateMatcher() +{ + if (isInitialized) { + MgraFree(GraphicList); + MmodFree(MilSearchContext); + MmodFree(MilResult); + } +} + +// Load template models +void TemplateMatcher::loadTemplates(const std::vector& template_paths, + const std::vector& offsetX, + const std::vector& offsetY, + const std::vector& sizeX, + const std::vector& sizeY, + const std::vector& drawColor) +{ + if (isInitialized) { + std::cerr << "Templates are already loaded. Skipping reloading.\n"; + return; + } + + ModelsOffsetX = offsetX; + ModelsOffsetY = offsetY; + ModelsSizeX = sizeX; + ModelsSizeY = sizeY; + ModelsDrawColor = drawColor; + ModelImgPaths = template_paths; + + // Allocate search context and result buffers + MmodAlloc(MilSystem, M_GEOMETRIC, M_DEFAULT, &MilSearchContext); + MmodAllocResult(MilSystem, M_DEFAULT, &MilResult); + + // Allocate a graphic list to hold the annotations + MgraAllocList(MilSystem, M_DEFAULT, &GraphicList); + MdispControl(MilDisplay, M_ASSOCIATED_GRAPHIC_LIST_ID, GraphicList); + + // Define templates + for (size_t i = 0; i < template_paths.size(); ++i) { + MIL_ID template_temporary; + MgraClear(M_DEFAULT, GraphicList); + MbufRestore(convert_to_wstring(ModelImgPaths[i]).c_str(), MilSystem, &template_temporary); + MIL_ID template_temporary_uint8 = convert_to_uint8(template_temporary); + if (this->param["isdisplay"] == 1) + { + MdispSelect(MilDisplay, template_temporary_uint8); + } + + MmodDefine(MilSearchContext, M_IMAGE, template_temporary_uint8, + static_cast(ModelsOffsetX[i]), + static_cast(ModelsOffsetY[i]), + static_cast(ModelsSizeX[i]), + static_cast(ModelsSizeY[i])); + + MgraColor(M_DEFAULT, ModelsDrawColor[i]); + MmodDraw(M_DEFAULT, MilSearchContext, GraphicList, + M_DRAW_BOX + M_DRAW_POSITION, i, M_ORIGINAL); + + if (this->param["isdisplay"] == 1) + { + MosGetch(); + } + MbufFree(template_temporary); + MbufFree(template_temporary_uint8); + } + + // Set parameters + MmodControl(MilSearchContext, M_CONTEXT, M_SPEED, M_VERY_HIGH); + MmodControl(MilSearchContext, M_CONTEXT, M_SMOOTHNESS, 75); + MmodControl(MilSearchContext, M_DEFAULT, M_ACCEPTANCE, 40); + MmodControl(MilSearchContext, M_DEFAULT, M_CERTAINTY, 60); + MmodControl(MilSearchContext, M_DEFAULT, M_NUMBER, 2); + + // Preprocess templates + MmodPreprocess(MilSearchContext, M_DEFAULT); + + isInitialized = true; + std::cout << "Templates loaded and preprocessed successfully.\n"; + + // Pause to show the models + MosPrintf(MIL_TEXT("A model context was defined with the ") + MIL_TEXT("models in the displayed image.\n")); + MosPrintf(MIL_TEXT("Press to continue.\n\n")); + if (this->param["debug_mode"] == 1) { + MosGetch(); + } +} + +// Search for models in the input image +void TemplateMatcher::findModels(const MIL_ID& inputImage,MIL_ID& outputImage) +{ + if (!isInitialized) { + std::cerr << "Templates are not loaded. Please load templates before searching.\n"; + return; + } + MIL_ID input_image_uint8 = convert_to_uint8(inputImage); + + MdispSelect(MilDisplay, input_image_uint8); + + // Clear previous annotations + MgraClear(M_DEFAULT, GraphicList); + + // Find models + MIL_DOUBLE Time = 0.0; + MappTimer(M_DEFAULT, M_TIMER_RESET + M_SYNCHRONOUS, M_NULL); + MmodFind(MilSearchContext, input_image_uint8, MilResult); + MappTimer(M_DEFAULT, M_TIMER_READ + M_SYNCHRONOUS, &Time); + + // Get results + MIL_INT NumResults = 0; + MmodGetResult(MilResult, M_DEFAULT, M_NUMBER + M_TYPE_MIL_INT, &NumResults); + + if (NumResults >= 1) { + std::vector Models(NumResults); + std::vector XPosition(NumResults), YPosition(NumResults), Angle(NumResults), + Scale(NumResults), Score(NumResults); + + MmodGetResult(MilResult, M_DEFAULT, M_INDEX + M_TYPE_MIL_INT, Models.data()); + MmodGetResult(MilResult, M_DEFAULT, M_POSITION_X, XPosition.data()); + MmodGetResult(MilResult, M_DEFAULT, M_POSITION_Y, YPosition.data()); + MmodGetResult(MilResult, M_DEFAULT, M_ANGLE, Angle.data()); + MmodGetResult(MilResult, M_DEFAULT, M_SCALE, Scale.data()); + MmodGetResult(MilResult, M_DEFAULT, M_SCORE, Score.data()); + + // Create a binary image buffer + MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL), + MbufInquire(inputImage, M_SIZE_Y, M_NULL), 1 + M_UNSIGNED, + M_IMAGE + M_PROC, &outputImage); + // Initialize the binary image to black + MbufClear(outputImage, 0); + + // Display results + std::cout << "Found " << NumResults << " model(s) in " << Time * 1000.0 << " ms:\n"; + std::cout << "Result Model X Position Y Position Angle Scale Score\n"; + for (MIL_INT i = 0; i < NumResults; ++i) { + std::cout << i << " " << Models[i] << " " << XPosition[i] << " " + << YPosition[i] << " " << Angle[i] << " " << Scale[i] + << " " << Score[i] << "%\n"; + + // Draw results onto the binary image + MgraColor(M_DEFAULT, 255); // White color for binary image + MmodDraw(M_DEFAULT, MilResult, outputImage, M_DRAW_EDGES + M_DRAW_POSITION, i, M_DEFAULT); + + // Draw results on the graphical list for display + MgraColor(M_DEFAULT, ModelsDrawColor[Models[i]]); + MmodDraw(M_DEFAULT, MilResult, GraphicList, + M_DRAW_EDGES + M_DRAW_POSITION, i, M_DEFAULT); + } + + // Display or save the binary image + + MbufSave(SAVE_PATH2, outputImage); + + } else { + std::cout << "No models found.\n"; + } + MosPrintf(MIL_TEXT("Press to EXIT.\n\n")); + MosGetch(); + MbufFree(input_image_uint8); +} + +std::vector splitString(const std::string& str, char delimiter) { + std::vector tokens; + std::stringstream ss(str); + std::string item; + while (std::getline(ss, item, delimiter)) { + tokens.push_back(item); + } + return tokens; +} + +void TemplateMatcher::loadConfig(const std::string& filename, + std::vector& template_paths, + std::vector& offsetX, + std::vector& offsetY, + std::vector& sizeX, + std::vector& sizeY, + std::vector& drawColor) { + std::ifstream file(filename); + if (!file.is_open()) { + std::cerr << "Unable to open configuration file: " << filename << std::endl; + return; + } + + std::string line; + while (std::getline(file, line)) { + auto pos = line.find('='); + if (pos == std::string::npos) continue; + + std::string key = line.substr(0, pos); + std::string value = line.substr(pos + 1); + auto values = splitString(value, ','); + + if (key == "template_paths") { + template_paths = values; + } else if (key == "offsetX") { + for (const auto& v : values) offsetX.push_back(std::stoi(v)); + } else if (key == "offsetY") { + for (const auto& v : values) offsetY.push_back(std::stoi(v)); + } else if (key == "sizeX") { + for (const auto& v : values) sizeX.push_back(std::stoi(v)); + } else if (key == "sizeY") { + for (const auto& v : values) sizeY.push_back(std::stoi(v)); + } else if (key == "drawColor") { + for (const auto& v : values) { + if (v == "M_COLOR_RED") drawColor.push_back(M_COLOR_RED); + else if (v == "M_COLOR_GREEN") drawColor.push_back(M_COLOR_GREEN); + else if (v == "M_COLOR_BLUE") drawColor.push_back(M_COLOR_BLUE); + } + } + } + file.close(); +} + +void TemplateMatcher::LoadTemplate(std::map& params) +{ + std::vector template_paths; + std::vector offsetX, offsetY, sizeX, sizeY; + std::vector drawColor; + + // 调用 loadConfig 并加载配置 + loadConfig("C:\\Users\\zjc\\Desktop\\config\\template_config.txt", + template_paths, offsetX, offsetY, sizeX, sizeY, drawColor); + + // 调用 matcher 的 loadTemplates 方法 + this->loadTemplates(template_paths, offsetX, offsetY, sizeX, sizeY, drawColor); +} + + +void TemplateMatcher::FindTemplates( const MIL_ID& inputImage, MIL_ID& outputImage,const std::map ¶ms) +{ + // Perform template matching + this -> findModels(inputImage,outputImage); + + // Notify user that matching is complete + cout << "Template matching completed.\n"; +} + + + + +// TODO: Opencv ONNX runner, +// 1. 构建相应的模型加载和模型运行函数 +// 2. 在src里头添加另一个cvdl库,专用于视觉深度学习 +// 3. 添加一个类OnnxRunner + +// TODO: 完善config文件,确保能够读取mask转换的相关参数 + +// TODO: Opencv和matrox图像的转换函数,添加到Matrox/utils.cpp + +// TODO:构建统一的图像检测器类,可以一键加载,一键开启多进程快速预测 + +// TODO:计算统一预测框架的预测时间 + +// TODO: 完善模板和参数,添加陈棉模块,陈棉模块可通过配置进行启用和关闭。 + +//TODO: 完善相应部分的手册 已 + diff --git a/src/Matrox/template_matching.h b/src/Matrox/template_matching.h new file mode 100644 index 0000000..00f8e88 --- /dev/null +++ b/src/Matrox/template_matching.h @@ -0,0 +1,70 @@ +// +// Created by zjc on 24-11-12. +// + +#ifndef TEMPLATE_MATCHING_H +#define TEMPLATE_MATCHING_H + + +void pre_process(const MIL_ID& inputImage, MIL_ID& outputImageSuspect, const std::map& params); +// void LoadTemplate(const MIL_ID &inputImage, MIL_ID &outputImage, std::map ¶ms); + +extern std::vector template_paths; +extern std::vector offsetX, offsetY, sizeX, sizeY; +extern std::vector drawColor; + + +class TemplateMatcher { +private: + MIL_ID MilSystem; + MIL_ID MilDisplay; + MIL_ID MilSearchContext; + MIL_ID MilResult; + MIL_ID GraphicList; +#define SAVE_PATH2 MIL_TEXT("C:\\Users\\zjc\\Desktop\\detection.png") + + std::vector ModelImgPaths; + std::vector ModelsOffsetX; + std::vector ModelsOffsetY; + std::vector ModelsSizeX; + std::vector ModelsSizeY; + std::vector ModelsDrawColor; + + bool isInitialized; + + std::map param; + +public: + // Constructor + TemplateMatcher(MIL_ID system, MIL_ID display, std::map& param); + + + + // Load template models + void loadTemplates(const std::vector& template_paths, + const std::vector& offsetX, const std::vector& offsetY, + const std::vector& sizeX, const std::vector& sizeY, + const std::vector& drawColor); + + // Search for models in the input image + void findModels(const MIL_ID& inputImage,MIL_ID& outputImage); + + void LoadTemplate(std::map ¶ms); + + void FindTemplates(const MIL_ID &inputImage, MIL_ID &outputImage,const std::map ¶ms); + + void loadConfig(const std::string& filename, + std::vector& template_paths, + std::vector& offsetX, + std::vector& offsetY, + std::vector& sizeX, + std::vector& sizeY, + std::vector& drawColor); + // Destructor + ~TemplateMatcher(); + +}; +// void FindTemplates( const MIL_ID& inputImage,const MIL_ID& outputImage,TemplateMatcher& matcher); +// void LoadTemplate(TemplateMatcher& matcher, std::map ¶ms); + +#endif //TEMPLATE_MATCHING_H diff --git a/Matrox/ui.cpp b/src/Matrox/ui.cpp similarity index 100% rename from Matrox/ui.cpp rename to src/Matrox/ui.cpp diff --git a/Matrox/ui.h b/src/Matrox/ui.h similarity index 100% rename from Matrox/ui.h rename to src/Matrox/ui.h diff --git a/src/Matrox/utils.cpp b/src/Matrox/utils.cpp new file mode 100644 index 0000000..fdde47a --- /dev/null +++ b/src/Matrox/utils.cpp @@ -0,0 +1,124 @@ +// +// Created by zjc on 24-11-18. +// + +#include "utils.h" + + +#include +#include +#include +#include + +using namespace std; + +/** + * Convert Lab values from Photoshop range to OpenCV range. + * + * @param lab_ps A vector of Lab values in Photoshop range [L (0-100), a (-128 to 127), b (-128 to 127)]. + * @return A vector of Lab values in OpenCV range [L (0-255), a (0-255), b (0-255)]. + */ +vector psLabToOpenCVLab(const vector& lab_ps) { + int l_ps = lab_ps[0]; + int a_ps = lab_ps[1]; + int b_ps = lab_ps[2]; + + // Conversion formulas + int l_cv = round((l_ps / 100.0) * 255.0); // Scale L from 0-100 to 0-255 + int a_cv = round(((a_ps + 128.0) / 255.0) * 255.0); // Shift and scale a + int b_cv = round(((b_ps + 128.0) / 255.0) * 255.0); // Shift and scale b + + return {l_cv, a_cv, b_cv}; +} + +/** + * Convert Lab values from OpenCV range to Photoshop range. + * + * @param lab_cv A vector of Lab values in OpenCV range [L (0-255), a (0-255), b (0-255)]. + * @return A vector of Lab values in Photoshop range [L (0-100), a (-128 to 127), b (-128 to 127)]. + */ +vector opencvLabToPsLab(const vector& lab_cv) { + int l_cv = lab_cv[0]; + int a_cv = lab_cv[1]; + int b_cv = lab_cv[2]; + + // Conversion formulas + int l_ps = round((l_cv / 255.0) * 100.0); // Scale L from 0-255 to 0-100 + int a_ps = round((a_cv / 255.0) * 255.0 - 128.0); // Scale and shift a + int b_ps = round((b_cv / 255.0) * 255.0 - 128.0); // Scale and shift b + + return {l_ps, a_ps, b_ps}; +} + +MIL_ID convert_to_uint8(MIL_ID input_img) { + MIL_ID output_img; + MIL_ID MilSystem = MbufInquire(input_img, M_OWNER_SYSTEM, M_NULL); + MIL_INT size_x = MbufInquire(input_img, M_SIZE_X, M_NULL); + MIL_INT size_y = MbufInquire(input_img, M_SIZE_Y, M_NULL); + MIL_INT channel_num = MbufInquire(input_img, M_SIZE_BAND, M_NULL); + + MbufAlloc2d(MilSystem, size_x, size_y, 8 + M_UNSIGNED, M_IMAGE + M_PROC + M_DISP, &output_img); + if(channel_num == 1) { + MimArith(output_img, input_img, output_img, M_ADD); + MimArith(output_img, 255.0, output_img, M_MULT_CONST); + } else if(channel_num == 3) { + MimConvert(input_img, output_img, M_RGB_TO_L); + MimArith(output_img, M_NULL, output_img, M_NOT); + } else { + cout << "Unsupported channel number!" << endl; + } + return output_img; +} + + +wstring convert_to_wstring(const string& str) { + return wstring(str.begin(), str.end()); +} + + + +void read_params_from_file(const std::string& filename, std::map& params) { + std::ifstream infile(filename); + if (!infile) { + std::cerr << "无法打开文件: " << filename << std::endl; + return; + } + + std::string line; + while (std::getline(infile, line)) { + // 去除行首和行尾的空白字符 + line.erase(0, line.find_first_not_of(" \t\r\n")); + line.erase(line.find_last_not_of(" \t\r\n") + 1); + + // 跳过空行和注释行 + if (line.empty() || line[0] == '#') + continue; + + // 查找等号的位置 + size_t pos = line.find('='); + if (pos == std::string::npos) + continue; // 如果没有等号,跳过该行 + + // 分割键和值,并去除空白字符 + std::string key = line.substr(0, pos); + std::string value_str = line.substr(pos + 1); + key.erase(0, key.find_first_not_of(" \t")); + key.erase(key.find_last_not_of(" \t") + 1); + value_str.erase(0, value_str.find_first_not_of(" \t")); + value_str.erase(value_str.find_last_not_of(" \t") + 1); + + // 将字符串转换为整数 + int value; + std::istringstream iss(value_str); + if (!(iss >> value)) { + std::cerr << "键 " << key << " 的值无效: " << value_str << std::endl; + continue; + } + + // 将键值对添加到参数映射中 + params[key] = value; + } +} + +// 图片转换函数,输入4096*1024*3的图片,输出为(4096 / n_valves) * (1024 / n_merge_vertical) * 1 +// Mat Mil2cvImage(MIL_ID &input_image,Mat) {} \ No newline at end of file diff --git a/src/Matrox/utils.h b/src/Matrox/utils.h new file mode 100644 index 0000000..08f505e --- /dev/null +++ b/src/Matrox/utils.h @@ -0,0 +1,42 @@ +// +// Created by zjc on 24-11-18. +// + +#ifndef UTILS_H +#define UTILS_H + +#include +#include +#include +#include +#include +#include +#include +#include + +// 声明全局变量(注意:这里只是声明,不是定义) +extern __int64 MilApplication; +extern __int64 MilSystem; +extern __int64 MilDisplay; + +template +// Time measurement function +void measure_execution_time(Func func) { + std::chrono::time_point start; + start = std::chrono::steady_clock::now(); + func(); + auto end = std::chrono::steady_clock::now(); + auto duration = std::chrono::duration_cast(end - start); + std::cout << "Function execution time: " << duration.count() << " milliseconds" << std::endl; +} + +std::vector psLabToOpenCVLab(const std::vector& lab_ps); + +std::vector opencvLabToPsLab(const std::vector& lab_cv); + +MIL_ID convert_to_uint8(MIL_ID input_img); + +std::wstring convert_to_wstring(const std::string& str); +void read_params_from_file(const std::string& filename, std::map& params) ; + +#endif //UTILS_H diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..986f60d --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,24 @@ + +# 测试用例 1: template_color_range +add_executable(test_color_range + ${CMAKE_CURRENT_SOURCE_DIR}/test_color_range.cpp +) + +# 链接 Matrox 模块和依赖库 +target_link_libraries(test_color_range Matrox ${OpenCV_LIBS} ${MIL_LIBS}) + +# 测试用例 2: template_template_matching +add_executable(test_template_matching + ${CMAKE_CURRENT_SOURCE_DIR}/test_template_matching.cpp +) + +# 链接 Matrox 模块和依赖库 +target_link_libraries(test_template_matching Matrox ${OpenCV_LIBS} ${MIL_LIBS}) + + +add_executable(test_mask + ${CMAKE_CURRENT_SOURCE_DIR}/test_mask.cpp +) + +# 链接 Matrox 模块和依赖库 +target_link_libraries(test_mask Matrox ${OpenCV_LIBS} ${MIL_LIBS}) \ No newline at end of file diff --git a/tests/test_color_range.cpp b/tests/test_color_range.cpp new file mode 100644 index 0000000..c57a590 --- /dev/null +++ b/tests/test_color_range.cpp @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include "Matrox/utils.h" +#include "Matrox/color_range.h" + +#define IMAGE_PATH MIL_TEXT("C:\\Users\\zjc\\Desktop\\cotton_image\\174.bmp") +#define SAVE_PATH MIL_TEXT("C:\\Users\\zjc\\Desktop\\diguandai.png") + +// Global variables +MIL_ID MilApplication = M_NULL, MilSystem = M_NULL, MilDisplay = M_NULL; + +int main() +{ + // Initialize MIL application + MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, &MilDisplay, M_NULL, + M_NULL); + + // Load input image + MIL_ID MilImage = M_NULL; + MbufRestore(IMAGE_PATH, MilSystem, &MilImage); + + // Define color ranges + std::map params; + read_params_from_file("C:\\Users\\zjc\\Desktop\\config\\color_range_config.txt", params); + + // Initialize combined result + MIL_ID detection_result = M_NULL; + + // Measure execution time + measure_execution_time([&]() { + high_sat_detect(MilImage, detection_result, params); + }); + MbufSave(SAVE_PATH, detection_result); + // Display result + + std::cout << "所有颜色检测已完成并合并。按 退出。" << std::endl; + getchar(); + + // Free resources + MbufFree(detection_result); + MbufFree(MilImage); + MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL); + + return 0; +} \ No newline at end of file diff --git a/tests/test_mask.cpp b/tests/test_mask.cpp new file mode 100644 index 0000000..76f6396 --- /dev/null +++ b/tests/test_mask.cpp @@ -0,0 +1,30 @@ +// +// Created by zjc on 24-11-26. +// +#include "vector" +#include"iostream" +#include"string" +#include"Matrox/mask.h" +int main() { + // 指定图像路径 + std::string imagePath = "C:\\Users\\zjc\\Desktop\\diguandai.png"; + + // 设置分块数量和白色像素点阈值 + int widthBlocks = 24; + int heightBlocks = 24; + int threshold = 20; + + // 生成掩膜 + std::vector> mask = generateMaskFromImage(imagePath, widthBlocks, heightBlocks, threshold); + + // 打印掩膜结果 + for (int i = 0; i < heightBlocks; ++i) { + for (int j = 0; j < widthBlocks; ++j) + { + std::cout << (mask[i][j] ? "1 " : "0 "); + } + std::cout << std::endl; + } + + return 0; +} \ No newline at end of file diff --git a/tests/test_template_matching.cpp b/tests/test_template_matching.cpp new file mode 100644 index 0000000..fb2e568 --- /dev/null +++ b/tests/test_template_matching.cpp @@ -0,0 +1,66 @@ +// +// Created by zjc on 24-11-20. +// +#include +#include +#include +#include +#include "Matrox/utils.h" +#include "Matrox/template_matching.h" + +#define IMAGE_PATH MIL_TEXT("C:\\Users\\zjc\\Desktop\\cotton_image_new\\357.bmp") +#define SAVE_PATH MIL_TEXT("C:\\Users\\zjc\\Desktop\\suspect.png") + + +// Global variables +MIL_ID MilApplication = M_NULL, MilSystem = M_NULL, MilDisplay = M_NULL; + + +int main() { + using namespace std; + + + + std::map params; + read_params_from_file("C:\\Users\\zjc\\Desktop\\config\\template_color_config.txt", params); + // Initialize MIL application + MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, &MilDisplay, M_NULL, + M_NULL); + + // Load input image + MIL_ID MilImage = M_NULL; + MbufRestore(IMAGE_PATH, MilSystem, &MilImage); + + // Initialize combined result + MIL_ID detection_result = M_NULL; + MIL_ID detection_resize = M_NULL; + + + + MIL_ID output_Image= M_NULL; + TemplateMatcher matcher(MilSystem, MilDisplay, params); + + // Measure execution time + measure_execution_time([&]() + { + pre_process(MilImage, detection_result, params); + MbufAlloc2d(MilSystem, MbufInquire(detection_result, M_SIZE_X, M_NULL)/2, + MbufInquire(detection_result, M_SIZE_Y, M_NULL)/2, 1 + M_UNSIGNED, + M_IMAGE + M_PROC, &detection_resize); + MimResize(detection_result,detection_resize,0.5,0.5,M_DEFAULT); + + matcher.LoadTemplate(params); + matcher.FindTemplates(detection_resize,output_Image,params); + + }); + MbufSave(SAVE_PATH, detection_result); + // Display result + + std::cout << "所有颜色检测已完成并合并。按 退出。" << std::endl; + getchar(); + + MbufFree(detection_result); + MbufFree(MilImage); + + return 0; +} \ No newline at end of file