mirror of
https://github.com/Karllzy/cotton_color.git
synced 2025-11-08 18:53:53 +00:00
commit
5862effd69
@ -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})
|
||||
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)
|
||||
|
||||
@ -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 即可
|
||||
@ -1,204 +0,0 @@
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
//
|
||||
// Created by zjc on 24-11-12.
|
||||
//
|
||||
|
||||
#ifndef COLOR_RANGE_H
|
||||
#define COLOR_RANGE_H
|
||||
|
||||
#endif //COLOR_RANGE_H
|
||||
@ -1,222 +0,0 @@
|
||||
|
||||
|
||||
#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);
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
//
|
||||
// Created by zjc on 24-11-12.
|
||||
//
|
||||
|
||||
#ifndef TEMPLATE_MATCHING_H
|
||||
#define TEMPLATE_MATCHING_H
|
||||
|
||||
#endif //TEMPLATE_MATCHING_H
|
||||
232
opencv_onnx.cpp
Normal file
232
opencv_onnx.cpp
Normal file
@ -0,0 +1,232 @@
|
||||
//
|
||||
// Created by zjc on 24-11-19.
|
||||
//
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <opencv2/dnn/dnn.hpp>
|
||||
#include <iostream>
|
||||
|
||||
// 参数
|
||||
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<double> 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<Detection>& 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<int>(originalWidth * scale);
|
||||
int newHeight = static_cast<int>(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<Detection> 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<int>(cx - w / 2);
|
||||
int top = static_cast<int>(cy - h / 2);
|
||||
int width = static_cast<int>(w);
|
||||
int height = static_cast<int>(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<int> indices;
|
||||
std::vector<cv::Rect> boxes;
|
||||
std::vector<float> 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<Detection> 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;
|
||||
}
|
||||
//
|
||||
13
src/CMakeLists.txt
Normal file
13
src/CMakeLists.txt
Normal file
@ -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})
|
||||
5
src/CVDL/OnnxRunner.cpp
Normal file
5
src/CVDL/OnnxRunner.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by zjc on 24-11-26.
|
||||
//
|
||||
|
||||
#include "OnnxRunner.h"
|
||||
16
src/CVDL/OnnxRunner.h
Normal file
16
src/CVDL/OnnxRunner.h
Normal file
@ -0,0 +1,16 @@
|
||||
//
|
||||
// Created by zjc on 24-11-26.
|
||||
//
|
||||
|
||||
#ifndef ONNXRUNNER_H
|
||||
#define ONNXRUNNER_H
|
||||
|
||||
|
||||
|
||||
class OnnxRunner {
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //ONNXRUNNER_H
|
||||
93
src/Matrox/README.md
Normal file
93
src/Matrox/README.md
Normal file
@ -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<std::string, int>& params);
|
||||
// 用法
|
||||
// std::map<std::string, int> params;
|
||||
// params["saturation_threshold"] = 150;
|
||||
// params["saturation_denoising"] = 2;
|
||||
|
||||
void hsv_process(const MIL_ID& inputImage, MIL_ID& outputImageHSV, const std::map<std::string, int>& params);
|
||||
// std::map<std::string, int> 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 | | |  |
|
||||
| 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.读取配置文件函数
|
||||
|
||||
202
src/Matrox/color_range.cpp
Normal file
202
src/Matrox/color_range.cpp
Normal file
@ -0,0 +1,202 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <mil.h>
|
||||
#include <string>
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
// Optimized LabProcess function
|
||||
void lab_process_raw(const MIL_ID& inputImage, MIL_ID& outputImageLab, const std::map<std::string, int>& params,
|
||||
const std::vector<std::string>& 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<int> lab_min_ps = {L_min, a_min, b_min};
|
||||
std::vector<int> lab_max_ps = {L_max, a_max, b_max};
|
||||
|
||||
std::vector<int> lab_min_cv = psLabToOpenCVLab(lab_min_ps);
|
||||
std::vector<int> 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<std::string, int>& params) {
|
||||
const std::vector<std::string> 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<std::string, int>& 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<std::string, int>& 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);
|
||||
}
|
||||
|
||||
|
||||
69
src/Matrox/color_range.h
Normal file
69
src/Matrox/color_range.h
Normal file
@ -0,0 +1,69 @@
|
||||
//
|
||||
// Created by zjc on 24-11-12.
|
||||
//
|
||||
|
||||
#ifndef COLOR_RANGE_H
|
||||
#define COLOR_RANGE_H
|
||||
|
||||
#include <mil.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
void lab_process(const MIL_ID& inputImage, MIL_ID& outputImageLab, const std::map<std::string, int>& params);
|
||||
// 用法
|
||||
// std::map<std::string, int> params;
|
||||
// params["saturation_threshold"] = 150;
|
||||
|
||||
void hsv_process(const MIL_ID& inputImage, MIL_ID& outputImageHSV, const std::map<std::string, int>& params);
|
||||
// 用法
|
||||
// std::map<std::string, int> 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<std::string, int>& params,
|
||||
const std::vector<std::string>& color_vector);
|
||||
// 新增了可自定义的色彩矩阵
|
||||
|
||||
void high_sat_detect(const MIL_ID& inputImage, MIL_ID& outputImage, const std::map<std::string, int>& params);
|
||||
|
||||
#endif //COLOR_RANGE_H
|
||||
53
src/Matrox/mask.cpp
Normal file
53
src/Matrox/mask.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
#include "mask.h"
|
||||
// 读取二值化的单通道一位图片并生成掩膜
|
||||
std::vector<std::vector<bool>> 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<std::vector<bool>> mask(heightBlocks, std::vector<bool>(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;
|
||||
}
|
||||
|
||||
|
||||
16
src/Matrox/mask.h
Normal file
16
src/Matrox/mask.h
Normal file
@ -0,0 +1,16 @@
|
||||
//
|
||||
// Created by zjc on 24-11-26.
|
||||
//
|
||||
|
||||
|
||||
#ifndef MASK_H
|
||||
#define MASK_H
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
std::vector<std::vector<bool>> generateMaskFromImage(const std::string& imagePath, int widthBlocks, int heightBlocks, int threshold);
|
||||
|
||||
|
||||
#endif //MASK_H
|
||||
@ -13,9 +13,9 @@
|
||||
#include <vector>
|
||||
|
||||
// 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"));
|
||||
283
src/Matrox/template_matching.cpp
Normal file
283
src/Matrox/template_matching.cpp
Normal file
@ -0,0 +1,283 @@
|
||||
#include <execution>
|
||||
#include <mil.h>
|
||||
#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) {
|
||||
// 异色检测, 检测出不同与棉花颜色的物体作为模板匹配的对象
|
||||
const vector<string> colors = {"cotton", "background"};
|
||||
map <string, int> 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<std::string, int>& 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<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;
|
||||
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<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,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<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());
|
||||
|
||||
// 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 <Enter> to EXIT.\n\n"));
|
||||
MosGetch();
|
||||
MbufFree(input_image_uint8);
|
||||
}
|
||||
|
||||
std::vector<std::string> splitString(const std::string& str, char delimiter) {
|
||||
std::vector<std::string> 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<std::string>& template_paths,
|
||||
std::vector<MIL_INT>& offsetX,
|
||||
std::vector<MIL_INT>& offsetY,
|
||||
std::vector<MIL_INT>& sizeX,
|
||||
std::vector<MIL_INT>& sizeY,
|
||||
std::vector<MIL_DOUBLE>& 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<std::string, int>& params)
|
||||
{
|
||||
std::vector<std::string> template_paths;
|
||||
std::vector<MIL_INT> offsetX, offsetY, sizeX, sizeY;
|
||||
std::vector<MIL_DOUBLE> 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<std::string, int> ¶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: 完善相应部分的手册 已
|
||||
|
||||
70
src/Matrox/template_matching.h
Normal file
70
src/Matrox/template_matching.h
Normal file
@ -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<std::string, int>& params);
|
||||
// void LoadTemplate(const MIL_ID &inputImage, MIL_ID &outputImage, std::map<std::string, int> ¶ms);
|
||||
|
||||
extern std::vector<std::string> template_paths;
|
||||
extern std::vector<MIL_INT> offsetX, offsetY, sizeX, sizeY;
|
||||
extern std::vector<MIL_DOUBLE> 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<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,MIL_ID& outputImage);
|
||||
|
||||
void LoadTemplate(std::map<std::string, int> ¶ms);
|
||||
|
||||
void FindTemplates(const MIL_ID &inputImage, MIL_ID &outputImage,const std::map<std::string, int> ¶ms);
|
||||
|
||||
void loadConfig(const std::string& filename,
|
||||
std::vector<std::string>& template_paths,
|
||||
std::vector<MIL_INT>& offsetX,
|
||||
std::vector<MIL_INT>& offsetY,
|
||||
std::vector<MIL_INT>& sizeX,
|
||||
std::vector<MIL_INT>& sizeY,
|
||||
std::vector<MIL_DOUBLE>& drawColor);
|
||||
// Destructor
|
||||
~TemplateMatcher();
|
||||
|
||||
};
|
||||
// void FindTemplates( const MIL_ID& inputImage,const MIL_ID& outputImage,TemplateMatcher& matcher);
|
||||
// void LoadTemplate(TemplateMatcher& matcher, std::map<std::string, int> ¶ms);
|
||||
|
||||
#endif //TEMPLATE_MATCHING_H
|
||||
124
src/Matrox/utils.cpp
Normal file
124
src/Matrox/utils.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
//
|
||||
// Created by zjc on 24-11-18.
|
||||
//
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <opencv2/core/mat.hpp>
|
||||
|
||||
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<int> psLabToOpenCVLab(const vector<int>& 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<int> opencvLabToPsLab(const vector<int>& 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<std::string, int>& 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) {}
|
||||
42
src/Matrox/utils.h
Normal file
42
src/Matrox/utils.h
Normal file
@ -0,0 +1,42 @@
|
||||
//
|
||||
// Created by zjc on 24-11-18.
|
||||
//
|
||||
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <Mil.h>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
|
||||
// 声明全局变量(注意:这里只是声明,不是定义)
|
||||
extern __int64 MilApplication;
|
||||
extern __int64 MilSystem;
|
||||
extern __int64 MilDisplay;
|
||||
|
||||
template <typename Func>
|
||||
// Time measurement function
|
||||
void measure_execution_time(Func func) {
|
||||
std::chrono::time_point<std::chrono::steady_clock> start;
|
||||
start = std::chrono::steady_clock::now();
|
||||
func();
|
||||
auto end = std::chrono::steady_clock::now();
|
||||
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
|
||||
std::cout << "Function execution time: " << duration.count() << " milliseconds" << std::endl;
|
||||
}
|
||||
|
||||
std::vector<int> psLabToOpenCVLab(const std::vector<int>& lab_ps);
|
||||
|
||||
std::vector<int> opencvLabToPsLab(const std::vector<int>& 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<std::string, int>& params) ;
|
||||
|
||||
#endif //UTILS_H
|
||||
24
tests/CMakeLists.txt
Normal file
24
tests/CMakeLists.txt
Normal file
@ -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})
|
||||
47
tests/test_color_range.cpp
Normal file
47
tests/test_color_range.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <mil.h>
|
||||
#include <string>
|
||||
#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<std::string, int> 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 << "所有颜色检测已完成并合并。按 <Enter> 退出。" << std::endl;
|
||||
getchar();
|
||||
|
||||
// Free resources
|
||||
MbufFree(detection_result);
|
||||
MbufFree(MilImage);
|
||||
MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
30
tests/test_mask.cpp
Normal file
30
tests/test_mask.cpp
Normal file
@ -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<std::vector<bool>> 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;
|
||||
}
|
||||
66
tests/test_template_matching.cpp
Normal file
66
tests/test_template_matching.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
//
|
||||
// Created by zjc on 24-11-20.
|
||||
//
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <mil.h>
|
||||
#include <string>
|
||||
#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<std::string, int> 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 << "所有颜色检测已完成并合并。按 <Enter> 退出。" << std::endl;
|
||||
getchar();
|
||||
|
||||
MbufFree(detection_result);
|
||||
MbufFree(MilImage);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user