Merge pull request #1 from Karllzy/Template_matching

Template matching
This commit is contained in:
zjc-zjc-123 2024-11-13 21:40:01 +08:00 committed by GitHub
commit d3550bac61
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 619 additions and 34 deletions

View File

@ -31,6 +31,12 @@ set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
#mil
include_directories(E:/QTexamble/matrox/Include)
# MIL
link_directories(E:/QTexamble/matrox/LIB)
file(GLOB MIL_LIBS E:/QTexamble/matrox/LIB/*.lib)
# cotton_color
add_executable(cotton_color cotton_color.cpp)
@ -40,16 +46,21 @@ 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})
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})
target_link_libraries(cotton_color2 Qt6::Widgets ${OpenCV_LIBS} ${MIL_LIBS})
add_executable(color_matching Matrox/template_matching.cpp
Matrox/onnx_running.cpp
Matrox/onnx_running.h
Matrox/ui.cpp)
Matrox/onnx_running.cpp)
target_link_libraries(color_matching Qt6::Widgets ${OpenCV_LIBS} ${MIL_LIBS})
add_executable(ui Matrox/ui.cpp)
target_link_libraries(ui Qt6::Widgets)
target_link_libraries(ui Qt6::Widgets)
add_executable(onnx Matrox/onnx_running.cpp)
target_link_libraries(onnx Qt6::Widgets ${MIL_LIBS})

View File

@ -1,3 +1,204 @@
//
// Created by zjc on 24-11-12.
//
#include <mil.h>
#include <iostream>
#include <chrono>
#define IMAGE_PATH MIL_TEXT("C:\\Users\\zjc\\Desktop\\cotton2.bmp")
// 全局变量,方便在各个函数中使用
MIL_ID MilApplication = M_NULL, MilSystem = M_NULL, MilDisplay = M_NULL;
// 时间测量模板函数
template <typename Func>
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<std::chrono::milliseconds>(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("图像已处理并合并,按下 <Enter> 退出程序。\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;
}

View File

@ -1,5 +1,116 @@
//
// Created by zjc on 24-11-12.
// Created by zjc on 24-11-13.
//
#include "onnx_running.h"
#include <mil.h>
//#include <milim.h> // 添加此行
#include <iostream>
#include <mil.h>
// Path definitions.
#define EXAMPLE_ONNX_MODEL_PATH MIL_TEXT("C:\\Users\\zjc\\Desktop\\WeChat Files\\wxid_ipl8u0ctajtn22\\FileStorage\\File\\2024-11\\best(2).onnx")
#define TARGET_IMAGE_DIR_PATH MIL_TEXT("C:\\Users\\zjc\\Desktop\\dimo2.bmp")
int MosMain(void)
{
MIL_ID MilApplication = M_NULL, // MIL application identifier
MilSystem = M_NULL, // MIL system identifier
MilDisplay = M_NULL, // MIL display identifier
MilImage = M_NULL, // MIL image identifier
MilDetectedImage = M_NULL, // MIL image with detections
DetectCtx = M_NULL, // MIL ONNX detection context
DetectRes = M_NULL; // MIL detection result
// Allocate MIL objects.
MappAlloc(M_NULL, M_DEFAULT, &MilApplication);
MsysAlloc(M_DEFAULT, M_SYSTEM_DEFAULT, M_DEFAULT, M_DEFAULT, &MilSystem);
MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_DEFAULT, &MilDisplay);
// Load the image into memory.
if (MbufRestore(TARGET_IMAGE_DIR_PATH, MilSystem, &MilImage) != M_NULL)
{
MosPrintf(MIL_TEXT("Image loaded successfully.\n"));
}
else
{
MosPrintf(MIL_TEXT("Failed to load image.\n"));
return 1; // Exit if the image loading failed
}
// Import the YOLOv5 ONNX model into the detection context.
MosPrintf(MIL_TEXT("Importing the YOLOv5 ONNX model into the detection context...\n"));
MclassAlloc(MilSystem, M_CLASSIFIER_ONNX, M_DEFAULT, &DetectCtx);
MclassImport(EXAMPLE_ONNX_MODEL_PATH, M_ONNX_FILE, DetectCtx, M_DEFAULT, M_DEFAULT, M_DEFAULT);
MosPrintf(MIL_TEXT("Model imported successfully.\n"));
// Preprocess the detection context.
MclassPreprocess(DetectCtx, M_DEFAULT); // Ensure the context is preprocessed.
// Allocate a detection result buffer.
MclassAllocResult(MilSystem, M_PREDICT_ONNX_RESULT, M_DEFAULT, &DetectRes);
// Perform object detection on the image using MclassPredict.
MclassPredict(DetectCtx, MilImage, DetectRes, M_DEFAULT);
MosPrintf(MIL_TEXT("Object detection completed.\n"));
// Allocate a buffer for displaying the detection results.
MbufAlloc2d(MilSystem, 640, 640, 8 + M_UNSIGNED, M_IMAGE + M_PROC, &MilDetectedImage);
// Retrieve and draw the detection results manually.
MIL_INT NumDetections = 0;
MclassGetResult(DetectRes, M_GENERAL, M_TYPE_MIL_INT, &NumDetections);
if (NumDetections > 0)
{
for (MIL_INT i = 0; i < NumDetections; i++)
{
MIL_DOUBLE Score;
MIL_INT ClassIndex;
MIL_DOUBLE BBoxX, BBoxY, BBoxWidth, BBoxHeight;
// Retrieve detection results for each object.
MclassGetResult(DetectRes, i, M_SCORE + M_TYPE_MIL_DOUBLE, &Score);
MclassGetResult(DetectRes, i, M_INDEX + M_TYPE_MIL_INT, &ClassIndex);
MclassGetResult(DetectRes, i, M_SEED_VALUE + M_TYPE_MIL_DOUBLE, &BBoxX);
MclassGetResult(DetectRes, i, M_SEED_VALUE + M_TYPE_MIL_DOUBLE, &BBoxY);
MclassGetResult(DetectRes, i, M_SEED_VALUE + M_TYPE_MIL_DOUBLE, &BBoxWidth);
MclassGetResult(DetectRes, i, M_SEED_VALUE + M_TYPE_MIL_DOUBLE, &BBoxHeight);
// Draw bounding box.
MgraColor(M_DEFAULT, M_COLOR_GREEN);
MgraRect(M_DEFAULT, MilDetectedImage, BBoxX, BBoxY, BBoxX + BBoxWidth, BBoxY + BBoxHeight);
// Optionally, display detection score or class name (if needed).
MIL_TEXT_CHAR Label[256];
MosSprintf(Label, 256, MIL_TEXT("Class %d: %.2lf%%"), ClassIndex, Score * 100);
MgraFont(M_DEFAULT, M_FONT_DEFAULT_SMALL);
MgraText(M_DEFAULT, MilDetectedImage, BBoxX, BBoxY - 10, Label);
}
}
else
{
MosPrintf(MIL_TEXT("No detections found.\n"));
}
// Display the image with detection results.
MdispSelect(MilDisplay, MilDetectedImage);
// Wait for the user to close the window.
MosPrintf(MIL_TEXT("Press <Enter> to exit.\n"));
MosGetch();
// Free all allocated resources.
MbufFree(MilImage);
MbufFree(MilDetectedImage);
MclassFree(DetectRes);
MclassFree(DetectCtx);
MdispFree(MilDisplay);
MsysFree(MilSystem);
MappFree(MilApplication);
return 0;
}

View File

@ -1,8 +1,16 @@
//
// Created by zjc on 24-11-12.
// Created by zjc on 24-11-13.
//
#ifndef ONNX_RUNNING_H
#define ONNX_RUNNING_H
class onnx_running {
};
#endif //ONNX_RUNNING_H

View File

@ -1,3 +1,222 @@
//
// Created by zjc on 24-11-12.
//
#include <mil.h>
//#include <milim.h> // 添加此行
#include <iostream>
/* 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 <Enter> 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 <Enter> to continue.\n\n"));
MosGetch();
/* Free MIL objects. */
MgraFree(GraphicList);
MbufFree(MilImage);
MmodFree(MilSearchContext);
MmodFree(MilResult);
}

View File

@ -55,51 +55,86 @@ void vibrantColorDetection(const Mat& inputImage, Mat& outputImage, const map<st
// 对饱和度图像应用阈值处理
threshold(saturation, outputImage, saturationThreshold, 255, THRESH_BINARY);
}
string openFileDialog() {
std::wstring openFileDialog() {
// 初始化文件选择对话框
OPENFILENAME ofn; // 文件对话框结构
wchar_t szFile[260]; // 存储选择的文件路径
OPENFILENAMEW ofn; // 使用宽字符版本的结构
wchar_t szFile[260] = {0}; // 存储选择的文件路径
// 设置 OPENFILENAME 结构的默认值
// 设置 OPENFILENAMEW 结构的默认值
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFile = szFile;
ofn.lpstrFile = szFile; // 设置文件路径缓冲区
ofn.nMaxFile = sizeof(szFile) / sizeof(szFile[0]);
ofn.lpstrFilter = L"Image Files\0*.BMP;*.JPG;*.JPEG;*.PNG;*.GIF\0All Files\0*.*\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.lpstrFileTitle = NULL; // 不需要单独的文件名
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = L"Select an image file";
ofn.lpstrInitialDir = NULL; // 使用默认初始目录
ofn.lpstrTitle = L"Select an image file"; // 对话框标题
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
// 打开文件选择对话框
if (GetOpenFileName(&ofn) == TRUE) {
// 将 wchar_t 转换为 string
wstring ws(szFile);
string filePath(ws.begin(), ws.end());
return filePath;
if (GetOpenFileNameW(&ofn) == TRUE) {
return szFile; // 返回选中的文件路径
}
return ""; // 如果用户取消,返回空字符串
return L""; // 如果用户取消,返回空字符串
}
/**
* @brief Unicode
*
* @return cv::Mat Mat
*/
Mat readImage() {
// 读取输入图像
string imagePath = openFileDialog();
// 读取输入图像路径
std::wstring imagePath = openFileDialog();
if (imagePath.empty()) {
cout << "No file selected or user cancelled." << endl;
wcout << L"No file selected or user cancelled." << endl;
return Mat();
}
// 使用 OpenCV 读取选中的图片
Mat image = imread(imagePath);
// 使用 Windows API 打开文件
HANDLE hFile = CreateFileW(imagePath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
wcout << L"Error: Could not open file." << endl;
return Mat();
}
// 获取文件大小
LARGE_INTEGER fileSize;
if (!GetFileSizeEx(hFile, &fileSize)) {
wcout << L"Error: Could not get file size." << endl;
CloseHandle(hFile);
return Mat();
}
if (fileSize.QuadPart > MAXDWORD) {
wcout << L"Error: File size too large." << endl;
CloseHandle(hFile);
return Mat();
}
DWORD dwFileSize = static_cast<DWORD>(fileSize.QuadPart);
// 读取文件内容到缓冲区
std::vector<BYTE> buffer(dwFileSize);
DWORD bytesRead = 0;
if (!ReadFile(hFile, buffer.data(), dwFileSize, &bytesRead, NULL) || bytesRead != dwFileSize) {
wcout << L"Error: Could not read file." << endl;
CloseHandle(hFile);
return Mat();
}
CloseHandle(hFile);
// 使用 OpenCV 从内存缓冲区读取图像
Mat image = imdecode(buffer, IMREAD_COLOR);
if (image.empty()) {
cout << "Error: Could not load image." << endl;
wcout << L"Error: Could not decode image." << endl;
return Mat();
}
@ -139,7 +174,7 @@ int main() {
vibrantGreenDetection(inputImage, outputImage, params);
// 定义缩放因子1.0 表示原始大小,>1.0 表示放大,<1.0 表示缩小
double scaleFactor = 1.5; // 将图像放大1.5倍
double scaleFactor = 0.6; // 将图像放大1.5倍
// 显示原图和检测到的绿色区域,使用缩放因子
showImage("Original Image", inputImage, scaleFactor);

View File

@ -142,7 +142,7 @@ int main() {
// 使用 map 模拟参数传递
map<string, int> params;
params["saturationThreshold"] = 100; // 设置饱和度阈值为 100
params["saturationThreshold"] = 134; // 设置饱和度阈值为 100
// 调用鲜艳颜色检测函数
vibrantColorDetection(inputImage, outputImage, params);