From 38202919e6ee682fec37100b17afdffb579a0803 Mon Sep 17 00:00:00 2001 From: zjc-zjc-123 <1714105370@qq.com> Date: Thu, 21 Nov 2024 14:46:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0readme=EF=BC=8C=E5=B0=86?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E6=A8=A1=E5=9E=8B=E5=92=8C=E5=AF=BB=E6=89=BE?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E5=88=86=E7=A6=BB=EF=BC=8C=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E4=B8=80=E6=AC=A1=E5=8A=A0=E8=BD=BD=E6=A8=A1=E5=9E=8B=E5=8D=B3?= =?UTF-8?q?=E5=8F=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Matrox/README.md | 7 + src/Matrox/template_matching.cpp | 402 ++++++++++++++----------------- src/Matrox/template_matching.h | 55 ++++- tests/test_template_matching.cpp | 8 +- 4 files changed, 247 insertions(+), 225 deletions(-) diff --git a/src/Matrox/README.md b/src/Matrox/README.md index 36a4653..c45ed5d 100644 --- a/src/Matrox/README.md +++ b/src/Matrox/README.md @@ -84,3 +84,10 @@ void hsv_process(const MIL_ID& inputImage, MIL_ID& outputImageHSV, const std::ma | 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/template_matching.cpp b/src/Matrox/template_matching.cpp index deba732..a75e9d1 100644 --- a/src/Matrox/template_matching.cpp +++ b/src/Matrox/template_matching.cpp @@ -3,6 +3,7 @@ #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) { @@ -16,228 +17,189 @@ void pre_process(const MIL_ID& inputImage, MIL_ID& outputImageSuspect, const map MimArith(outputImageSuspect, M_NULL, outputImageSuspect, M_NOT); } - -class TemplateMatcher { - private: - MIL_ID MilSearchContext; - MIL_ID MilResult; - MIL_ID GraphicList; - - vector ModelImgPaths; - vector ModelsOffsetX; - vector ModelsOffsetY; - vector ModelsSizeX; - vector ModelsSizeY; - vector ModelsDrawColor; - - bool isInitialized; - - map param; - - public: - // Constructor - TemplateMatcher(MIL_ID system, MIL_ID display, map& param): - isInitialized(false) {this->param = param;} - - // Destructor: Free MIL objects - ~TemplateMatcher() { - if (isInitialized) { - MgraFree(GraphicList); - MmodFree(MilSearchContext); - MmodFree(MilResult); - } - } - - // Load template models - void loadTemplates(const vector& template_paths, - const vector& offsetX, const vector& offsetY, - const vector& sizeX, const vector& sizeY, - const vector& drawColor) { - - if (isInitialized) { - cerr << "Templates are already loaded. Reinitializing...\n"; - MgraFree(GraphicList); - MmodFree(MilSearchContext); - MmodFree(MilResult); - } - - ModelsOffsetX = offsetX; - ModelsOffsetY = offsetY; - ModelsSizeX = sizeX; - ModelsSizeY = sizeY; - ModelsDrawColor = drawColor; - ModelImgPaths = template_paths; - - // 搜索上下文和搜索结果的buffer - MmodAlloc(MilSystem, M_GEOMETRIC, M_DEFAULT, &MilSearchContext); - MmodAllocResult(MilSystem, M_DEFAULT, &MilResult); - - // Define templates - for (size_t i = 0; i < template_paths.size(); ++i) { - MIL_ID template_temporary; - MbufRestore(convert_to_wstring(ModelImgPaths[i]), MilSystem, &template_temporary); - MIL_ID template_temporary_uint8 = convert_to_uint8(template_temporary); - if (this->param["isdisplay"] == 1) - { - MdispSelect(MilDisplay, template_temporary_uint8); - } - /* 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); - - - - - 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 the desired search speed. */ - MmodControl(MilSearchContext, M_CONTEXT, M_SPEED, M_VERY_HIGH); - - /* Increase the smoothness for the edge extraction in the search context. */ - MmodControl(MilSearchContext, M_CONTEXT, M_SMOOTHNESS, 75); - - /* Modify the acceptance and the certainty for all the models that were defined. */ - MmodControl(MilSearchContext, M_DEFAULT, M_ACCEPTANCE, 40); - MmodControl(MilSearchContext, M_DEFAULT, M_CERTAINTY, 60); - - /* Set the number of occurrences to 2 for all the models that were defined. */ - MmodControl(MilSearchContext, M_DEFAULT, M_NUMBER, 2); - - // Preprocess templates - MmodPreprocess(MilSearchContext, M_DEFAULT); - - isInitialized = true; - cout << "Templates loaded and preprocessed successfully.\n"; - - /* Draw boxes and positions in the source image to identify the models. */ - // for (int i=0; i to continue.\n\n")); - if (this->param["debug_mode"] == 1) { - MosGetch(); - } - } - - // Search for models in the input image - void findModels(const MIL_ID& inputImage) { - if (!isInitialized) { - 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) { - vector Models(NumResults); - 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()); - - // Display results - cout << "Found " << NumResults << " model(s) in " << Time * 1000.0 << " ms:\n"; - cout << "Result Model X Position Y Position Angle Scale Score\n"; - for (MIL_INT i = 0; i < NumResults; ++i) { - cout << i << " " << Models[i] << " " << XPosition[i] << " " - << YPosition[i] << " " << Angle[i] << " " << Scale[i] - << " " << Score[i] << "%\n"; - - // Draw results - MgraColor(M_DEFAULT, ModelsDrawColor[Models[i]]); - MmodDraw(M_DEFAULT, MilResult, GraphicList, - M_DRAW_EDGES + M_DRAW_POSITION, i, M_DEFAULT); - - } - } else { - cout << "No models found.\n"; - } - MosPrintf(MIL_TEXT("Press to EXIT.\n\n")); - MosGetch(); - - - MbufFree(input_image_uint8); - } - -}; - - -void test_template_matching(const MIL_ID &inputImage, MIL_ID &outputImage, map ¶ms) +TemplateMatcher::TemplateMatcher(MIL_ID system, MIL_ID display, std::map& param) + : MilSystem(system), MilDisplay(display), isInitialized(false), param(param) { - // Create a TemplateMatcher instance - TemplateMatcher matcher(MilSystem, MilDisplay, params); - - //TODO: 1加入加载多个模板的功能 已 - //TODO: 2加入配置文件解析功能,解析后的文件与当前的para map兼容 - // 配置文件当中加入是否显示参数,能调控加载模板的过程是否显示。已 - //TODO: 3修改当前的代码使模板匹配不出错 已 - //TODO: 4成立模板文件夹,能够加载文件夹下的全部模板并实现检测 - //TODO: 5制作标准结构的函数,例如:matcher.findModels(MIL_ID inputImage, MIL_ID output_image, map); - //TODO: 6完善相应部分的手册 - - - // Load template models - vector template_paths = {"C:\\Users\\zjc\\Desktop\\template1.png", - "C:\\Users\\zjc\\Desktop\\template2.png", - "C:\\Users\\zjc\\Desktop\\template3.png", - }; - vector offsetX = {0, 20, 30}; - vector offsetY = {0, 20, 30}; - vector sizeX = {100, 60, 40}; - vector sizeY = {100, 60, 40}; - vector drawColor = {M_COLOR_RED, M_COLOR_GREEN, M_COLOR_BLUE}; - matcher.loadTemplates(template_paths, offsetX, offsetY, sizeX, sizeY, drawColor); - - // Find models - matcher.findModels(inputImage); - - - // Free resources - // } +// 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; + 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) +{ + 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()); + + // 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 + MgraColor(M_DEFAULT, ModelsDrawColor[Models[i]]); + MmodDraw(M_DEFAULT, MilResult, GraphicList, + M_DRAW_EDGES + M_DRAW_POSITION, i, M_DEFAULT); + } + } else { + std::cout << "No models found.\n"; + } + MosPrintf(MIL_TEXT("Press to EXIT.\n\n")); + MosGetch(); + MbufFree(input_image_uint8); +} +void TemplateMatcher::LoadTemplate(TemplateMatcher& matcher, std::map ¶ms) +{ + // Create a TemplateMatcher instance (consider making it static if you want to retain it between calls) + + // Load template models only once + matcher.loadTemplates( + { + "C:\\Users\\zjc\\Desktop\\templates\\template1.png", + "C:\\Users\\zjc\\Desktop\\templates\\template2.png", + "C:\\Users\\zjc\\Desktop\\templates\\template3.png", + "C:\\Users\\zjc\\Desktop\\templates\\template2.png", + }, + {0, 20, 30, 33}, // offsetX + {0, 20, 30, 33}, // offsetY + {100, 60, 40, 33}, // sizeX + {100, 60, 40, 33}, // sizeY + {M_COLOR_RED, M_COLOR_GREEN, M_COLOR_BLUE, M_COLOR_GREEN} // drawColor + ); +} + +void TemplateMatcher::FindTemplates( const MIL_ID& inputImage,const MIL_ID& outputImage,TemplateMatcher& matcher) +{ + // Perform template matching + matcher.findModels(inputImage); + + // Notify user that matching is complete + cout << "Template matching completed.\n"; +} + +//TODO: 1加入加载多个模板的功能 已 +//TODO: 2加入配置文件解析功能,解析后的文件与当前的para map兼容 +// 配置文件当中加入是否显示参数,能调控加载模板的过程是否显示。已 +//TODO: 3修改当前的代码使模板匹配不出错 已 +//TODO: 4成立模板文件夹,能够加载文件夹下的全部模板并实现检测 +//TODO: 5制作标准结构的函数,例如:matcher.findModels(MIL_ID inputImage, MIL_ID output_image, map); +//TODO: 6完善相应部分的手册 diff --git a/src/Matrox/template_matching.h b/src/Matrox/template_matching.h index 6225c96..8230ab6 100644 --- a/src/Matrox/template_matching.h +++ b/src/Matrox/template_matching.h @@ -4,8 +4,57 @@ #ifndef TEMPLATE_MATCHING_H #define TEMPLATE_MATCHING_H -void pre_process(const MIL_ID& inputImage, MIL_ID& outputImageSuspect, const std::map& params); -void template_matching(const MIL_ID& inputImageSuspect, MIL_ID& outputImage, const std::map& params); -void test_template_matching(const MIL_ID &inputImage, MIL_ID &outputImage, std::map ¶ms) ; + +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); + + + +class TemplateMatcher { +private: + MIL_ID MilSystem; + MIL_ID MilDisplay; + MIL_ID MilSearchContext; + MIL_ID MilResult; + MIL_ID GraphicList; + + 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); + + void LoadTemplate(TemplateMatcher &matcher, std::map ¶ms); + + void FindTemplates(const MIL_ID &inputImage, const MIL_ID &outputImage, TemplateMatcher &matcher); + + + // 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/tests/test_template_matching.cpp b/tests/test_template_matching.cpp index 6c6b8b3..a719b21 100644 --- a/tests/test_template_matching.cpp +++ b/tests/test_template_matching.cpp @@ -19,7 +19,7 @@ int main() { using namespace std; std::map params; - read_params_from_file("C:\\Users\\zjc\\Desktop\\config\\config.txt", params); + read_params_from_file("C:\\Users\\zjc\\Desktop\\config\\template_config.txt", params); // Initialize MIL application MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, &MilDisplay, M_NULL, M_NULL); @@ -30,12 +30,16 @@ int main() { // Initialize combined result MIL_ID detection_result = 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); - test_template_matching(detection_result, detection_result, params); + matcher.LoadTemplate(matcher,params); + matcher.FindTemplates(detection_result,output_Image,matcher); + //最后的释放问题应该出在寻找模板里面 }); MbufSave(SAVE_PATH, detection_result); // Display result