更新readme,将加载模型和寻找模型分离,实现一次加载模型即可

This commit is contained in:
zjc-zjc-123 2024-11-21 14:46:37 +08:00
parent 96c55d89c0
commit 38202919e6
4 changed files with 247 additions and 225 deletions

View File

@ -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.读取配置文件函数

View File

@ -3,6 +3,7 @@
#include <iostream>
#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<string, int>& 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<string> ModelImgPaths;
vector<MIL_INT> ModelsOffsetX;
vector<MIL_INT> ModelsOffsetY;
vector<MIL_INT> ModelsSizeX;
vector<MIL_INT> ModelsSizeY;
vector<MIL_DOUBLE> ModelsDrawColor;
bool isInitialized;
map<string, int> param;
public:
// Constructor
TemplateMatcher(MIL_ID system, MIL_ID display, map<string, int>& 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<string>& template_paths,
const vector<MIL_INT>& offsetX, const vector<MIL_INT>& offsetY,
const vector<MIL_INT>& sizeX, const vector<MIL_INT>& sizeY,
const vector<MIL_DOUBLE>& 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<MIL_DOUBLE>(ModelsOffsetX[i]),
static_cast<MIL_DOUBLE>(ModelsOffsetY[i]),
static_cast<MIL_DOUBLE>(ModelsSizeX[i]),
static_cast<MIL_DOUBLE>(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<ModelImgPaths.size(); i++)
// {
// MgraColor(M_DEFAULT, ModelsDrawColor[i]);
// MmodDraw( M_DEFAULT, MilSearchContext, GraphicList,
// M_DRAW_BOX+M_DRAW_POSITION, i, M_ORIGINAL);
// }
/* 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 <Enter> 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<MIL_INT> Models(NumResults);
vector<MIL_DOUBLE> 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 <Enter> to EXIT.\n\n"));
MosGetch();
MbufFree(input_image_uint8);
}
};
void test_template_matching(const MIL_ID &inputImage, MIL_ID &outputImage, map<string, int> &params)
TemplateMatcher::TemplateMatcher(MIL_ID system, MIL_ID display, std::map<std::string, int>& param)
: MilSystem(system), MilDisplay(display), isInitialized(false), param(param)
{
// Create a TemplateMatcher instance
TemplateMatcher matcher(MilSystem, MilDisplay, params);
//TODO: 1加入加载多个模板的功能 已
//TODO: 2加入配置文件解析功能解析后的文件与当前的para map<string, int>兼容
// 配置文件当中加入是否显示参数,能调控加载模板的过程是否显示。已
//TODO: 3修改当前的代码使模板匹配不出错 已
//TODO: 4成立模板文件夹能够加载文件夹下的全部模板并实现检测
//TODO: 5制作标准结构的函数例如matcher.findModels(MIL_ID inputImage, MIL_ID output_image, map);
//TODO: 6完善相应部分的手册
// Load template models
vector<string> template_paths = {"C:\\Users\\zjc\\Desktop\\template1.png",
"C:\\Users\\zjc\\Desktop\\template2.png",
"C:\\Users\\zjc\\Desktop\\template3.png",
};
vector<MIL_INT> offsetX = {0, 20, 30};
vector<MIL_INT> offsetY = {0, 20, 30};
vector<MIL_INT> sizeX = {100, 60, 40};
vector<MIL_INT> sizeY = {100, 60, 40};
vector<MIL_DOUBLE> 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<std::string>& template_paths,
const std::vector<MIL_INT>& offsetX,
const std::vector<MIL_INT>& offsetY,
const std::vector<MIL_INT>& sizeX,
const std::vector<MIL_INT>& sizeY,
const std::vector<MIL_DOUBLE>& 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<MIL_DOUBLE>(ModelsOffsetX[i]),
static_cast<MIL_DOUBLE>(ModelsOffsetY[i]),
static_cast<MIL_DOUBLE>(ModelsSizeX[i]),
static_cast<MIL_DOUBLE>(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 <Enter> 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<MIL_INT> Models(NumResults);
std::vector<MIL_DOUBLE> 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 <Enter> to EXIT.\n\n"));
MosGetch();
MbufFree(input_image_uint8);
}
void TemplateMatcher::LoadTemplate(TemplateMatcher& matcher, std::map<std::string, int> &params)
{
// 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<string, int>兼容
// 配置文件当中加入是否显示参数,能调控加载模板的过程是否显示。已
//TODO: 3修改当前的代码使模板匹配不出错 已
//TODO: 4成立模板文件夹能够加载文件夹下的全部模板并实现检测
//TODO: 5制作标准结构的函数例如matcher.findModels(MIL_ID inputImage, MIL_ID output_image, map);
//TODO: 6完善相应部分的手册

View File

@ -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<std::string, int>& params);
void template_matching(const MIL_ID& inputImageSuspect, MIL_ID& outputImage, const std::map<std::string, int>& params);
void test_template_matching(const MIL_ID &inputImage, MIL_ID &outputImage, std::map<std::string, int> &params) ;
void pre_process(const MIL_ID& inputImage, MIL_ID& outputImageSuspect, const std::map<std::string, int>& params);
// void LoadTemplate(const MIL_ID &inputImage, MIL_ID &outputImage, std::map<std::string, int> &params);
class TemplateMatcher {
private:
MIL_ID MilSystem;
MIL_ID MilDisplay;
MIL_ID MilSearchContext;
MIL_ID MilResult;
MIL_ID GraphicList;
std::vector<std::string> ModelImgPaths;
std::vector<MIL_INT> ModelsOffsetX;
std::vector<MIL_INT> ModelsOffsetY;
std::vector<MIL_INT> ModelsSizeX;
std::vector<MIL_INT> ModelsSizeY;
std::vector<MIL_DOUBLE> ModelsDrawColor;
bool isInitialized;
std::map<std::string, int> param;
public:
// Constructor
TemplateMatcher(MIL_ID system, MIL_ID display, std::map<std::string, int>& param);
// Load template models
void loadTemplates(const std::vector<std::string>& template_paths,
const std::vector<MIL_INT>& offsetX, const std::vector<MIL_INT>& offsetY,
const std::vector<MIL_INT>& sizeX, const std::vector<MIL_INT>& sizeY,
const std::vector<MIL_DOUBLE>& drawColor);
// Search for models in the input image
void findModels(const MIL_ID& inputImage);
void LoadTemplate(TemplateMatcher &matcher, std::map<std::string, int> &params);
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<std::string, int> &params);
#endif //TEMPLATE_MATCHING_H

View File

@ -19,7 +19,7 @@ int main() {
using namespace std;
std::map<std::string, int> 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