From af063ae8e0a1c86b4c31356dc52dc32a6f79ca48 Mon Sep 17 00:00:00 2001 From: zjc-zjc-123 <1714105370@qq.com> Date: Wed, 13 Nov 2024 18:52:18 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dcotton=5Fcolor=E7=9A=84bug=20?= =?UTF-8?q?=20=20=E6=B7=BB=E5=8A=A0color=5Frange=E7=9A=84matrox=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 13 ++- Matrox/color_range.cpp | 201 +++++++++++++++++++++++++++++++++++++++++ cotton_color.cpp | 79 +++++++++++----- cotton_color2.cpp | 2 +- 4 files changed, 269 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 84c61e4..ca90d5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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,17 @@ 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) add_executable(color_matching Matrox/template_matching.cpp Matrox/onnx_running.cpp Matrox/onnx_running.h Matrox/ui.cpp) add_executable(ui Matrox/ui.cpp) -target_link_libraries(ui Qt6::Widgets) \ No newline at end of file +target_link_libraries(ui Qt6::Widgets) + diff --git a/Matrox/color_range.cpp b/Matrox/color_range.cpp index 9eee56e..e4d93ef 100644 --- a/Matrox/color_range.cpp +++ b/Matrox/color_range.cpp @@ -1,3 +1,204 @@ // // Created by zjc on 24-11-12. // + +#include +#include +#include +#define IMAGE_PATH MIL_TEXT("C:\\Users\\zjc\\Desktop\\cotton2.bmp") + +// 全局变量,方便在各个函数中使用 +MIL_ID MilApplication = M_NULL, MilSystem = M_NULL, MilDisplay = M_NULL; + + +// 时间测量模板函数 +template +void measureExecutionTime(Func func) { + // 获取当前时间作为起点 + auto start = std::chrono::high_resolution_clock::now(); + + // 执行传入的函数 + func(); + + // 获取当前时间作为结束点 + auto end = std::chrono::high_resolution_clock::now(); + + // 计算时间差并转换为毫秒 + auto duration = std::chrono::duration_cast(end - start); + + std::cout << "Function execution time: " << duration.count() << " milliseconds" << std::endl; +} + +// LabProcess 函数,支持通过参数控制阈值范围,提供默认值 +void LabProcess(MIL_ID& inputImage, MIL_ID& outputImageLab, + MIL_DOUBLE lowerL = 101.0, MIL_DOUBLE upperL = 135.0, + MIL_DOUBLE lowerA = 101.0, MIL_DOUBLE upperA = 120.0, + MIL_DOUBLE lowerB = 95.0, MIL_DOUBLE upperB = 134.0) +{ + MIL_ID MilLabImage = M_NULL, MilLChannel = M_NULL, MilAChannel = M_NULL, MilBChannel = M_NULL; + MIL_ID MilBinaryL = M_NULL, MilBinaryA = M_NULL, MilBinaryB = M_NULL; + + // 检查输入图像的通道数 + MIL_INT NumBands = 0; + MbufInquire(inputImage, M_SIZE_BAND, &NumBands); + if (NumBands != 3) + { + printf("输入图像不是 3 通道图像,请提供彩色图像。\n"); + return; + } + + // 分配用于存储 Lab 图像的缓冲区 + MbufAllocColor(MbufInquire(inputImage, M_OWNER_SYSTEM, M_NULL), 3, + MbufInquire(inputImage, M_SIZE_X, M_NULL), + MbufInquire(inputImage, M_SIZE_Y, M_NULL), + 8 + M_UNSIGNED, + M_IMAGE + M_PROC + M_DISP, + &MilLabImage); + + // 将图像从 sRGB 转换到 Lab + MimConvert(inputImage, MilLabImage, M_SRGB_TO_LAB); + + // 创建 Lab 通道的子缓冲区 + MbufChildColor(MilLabImage, 0, &MilLChannel); + MbufChildColor(MilLabImage, 1, &MilAChannel); + MbufChildColor(MilLabImage, 2, &MilBChannel); + + // 分配二值图像缓冲区 + MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL), + MbufInquire(inputImage, M_SIZE_Y, M_NULL), 8 + M_UNSIGNED, + M_IMAGE + M_PROC + M_DISP, &MilBinaryL); + MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL), + MbufInquire(inputImage, M_SIZE_Y, M_NULL), 8 + M_UNSIGNED, + M_IMAGE + M_PROC + M_DISP, &MilBinaryA); + MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL), + MbufInquire(inputImage, M_SIZE_Y, M_NULL), 8 + M_UNSIGNED, + M_IMAGE + M_PROC + M_DISP, &MilBinaryB); + + // 对每个通道进行阈值分割 + MimBinarize(MilLChannel, MilBinaryL, M_IN_RANGE, lowerL, upperL); + MimBinarize(MilAChannel, MilBinaryA, M_IN_RANGE, lowerA, upperA); + MimBinarize(MilBChannel, MilBinaryB, M_IN_RANGE, lowerB, upperB); + + // 分配输出图像缓冲区 + MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL), + MbufInquire(inputImage, M_SIZE_Y, M_NULL), 8 + M_UNSIGNED, + M_IMAGE + M_PROC + M_DISP, &outputImageLab); + + // 将结果合并 + MimArith(MilBinaryL, MilBinaryA, outputImageLab, M_AND); + MimArith(outputImageLab, MilBinaryB, outputImageLab, M_AND); + + // 释放资源 + MbufFree(MilBinaryL); + MbufFree(MilBinaryA); + MbufFree(MilBinaryB); + MbufFree(MilLChannel); + MbufFree(MilAChannel); + MbufFree(MilBChannel); + MbufFree(MilLabImage); +} + +// HSVProcess 函数,支持通过参数控制饱和度阈值,提供默认值 +void HSVProcess(MIL_ID& inputImage, MIL_ID& outputImageHSV, MIL_DOUBLE saturationThreshold = 120.0) +{ + MIL_ID MilHSVImage = M_NULL, MilHChannel = M_NULL, MilSChannel = M_NULL, MilVChannel = M_NULL; + + // 检查输入图像的通道数 + MIL_INT NumBands = 0; + MbufInquire(inputImage, M_SIZE_BAND, &NumBands); + if (NumBands != 3) + { + printf("输入图像不是 3 通道图像,请提供彩色图像。\n"); + return; + } + + // 分配用于存储 HSV 图像的缓冲区 + MbufAllocColor(MbufInquire(inputImage, M_OWNER_SYSTEM, M_NULL), 3, + MbufInquire(inputImage, M_SIZE_X, M_NULL), + MbufInquire(inputImage, M_SIZE_Y, M_NULL), + 8 + M_UNSIGNED, + M_IMAGE + M_PROC + M_DISP, + &MilHSVImage); + + // 将图像从 sRGB 转换到 HSV + MimConvert(inputImage, MilHSVImage, M_RGB_TO_HSV); + + // 创建 HSV 通道的子缓冲区 + MbufChildColor(MilHSVImage, 0, &MilHChannel); + MbufChildColor(MilHSVImage, 1, &MilSChannel); + MbufChildColor(MilHSVImage, 2, &MilVChannel); + + // 分配输出图像缓冲区 + MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL), + MbufInquire(inputImage, M_SIZE_Y, M_NULL), 8 + M_UNSIGNED, + M_IMAGE + M_PROC + M_DISP, &outputImageHSV); + + // 对 S 通道进行阈值分割 + MimBinarize(MilSChannel, outputImageHSV, M_GREATER, saturationThreshold, M_NULL); + + // 释放资源 + MbufFree(MilHChannel); + MbufFree(MilSChannel); + MbufFree(MilVChannel); + MbufFree(MilHSVImage); +} + +// 综合测试函数,调用 LabProcess 和 HSVProcess 并合并结果 +void test_hsv(MIL_ID& inputImage, + MIL_DOUBLE lowerL = 101.0, MIL_DOUBLE upperL = 135.0, + MIL_DOUBLE lowerA = 101.0, MIL_DOUBLE upperA = 120.0, + MIL_DOUBLE lowerB = 95.0, MIL_DOUBLE upperB = 134.0, + MIL_DOUBLE saturationThreshold = 120.0) +{ + MIL_ID MilResultLab = M_NULL, MilResultHSV = M_NULL, MilCombinedResult = M_NULL; + + // 调用 LabProcess + LabProcess(inputImage, MilResultLab, lowerL, upperL, lowerA, upperA, lowerB, upperB); + + // 调用 HSVProcess + HSVProcess(inputImage, MilResultHSV, saturationThreshold); + + // 分配合并结果的缓冲区 + MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL), + MbufInquire(inputImage, M_SIZE_Y, M_NULL), 8 + M_UNSIGNED, + M_IMAGE + M_PROC + M_DISP, &MilCombinedResult); + + // 合并 Lab 和 HSV 的结果(取“或”运算) + MimArith(MilResultLab, MilResultHSV, MilCombinedResult, M_OR); + + //// 显示合并后的结果图像 + MdispSelect(MilDisplay, MilCombinedResult); + + //// 等待用户查看处理后的图像 + printf("图像已处理并合并,按下 退出程序。\n"); + getchar(); + + // 释放资源 + MbufFree(MilResultLab); + MbufFree(MilResultHSV); + MbufFree(MilCombinedResult); +} + + +int main() +{ + MIL_ID MilImage = M_NULL; + + // 初始化 MIL 应用程序 + MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, &MilDisplay, M_NULL, M_NULL); + + // 加载输入图像 + MbufRestore(IMAGE_PATH, MilSystem, &MilImage); + + // 使用 lambda 表达式测量 test_hsv() 的执行时间 + measureExecutionTime([&]() { + test_hsv(MilImage); + }); + + + // 释放资源 + MbufFree(MilImage); + MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL); + + return 0; +} \ No newline at end of file diff --git a/cotton_color.cpp b/cotton_color.cpp index 7060728..28c80f3 100644 --- a/cotton_color.cpp +++ b/cotton_color.cpp @@ -55,51 +55,86 @@ void vibrantColorDetection(const Mat& inputImage, Mat& outputImage, const map MAXDWORD) { + wcout << L"Error: File size too large." << endl; + CloseHandle(hFile); + return Mat(); + } + + DWORD dwFileSize = static_cast(fileSize.QuadPart); + + // 读取文件内容到缓冲区 + std::vector 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); diff --git a/cotton_color2.cpp b/cotton_color2.cpp index c6ab671..5de3194 100644 --- a/cotton_color2.cpp +++ b/cotton_color2.cpp @@ -142,7 +142,7 @@ int main() { // 使用 map 模拟参数传递 map params; - params["saturationThreshold"] = 100; // 设置饱和度阈值为 100 + params["saturationThreshold"] = 134; // 设置饱和度阈值为 100 // 调用鲜艳颜色检测函数 vibrantColorDetection(inputImage, outputImage, params);