From 21b2a539f7d40dc450cc5e3285412a443185ac3e Mon Sep 17 00:00:00 2001 From: zjc-zjc-123 <1714105370@qq.com> Date: Wed, 27 Nov 2024 23:47:45 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E4=BA=86debug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- opencv_template_matching.py | 34 ++++++++++++ src/Matrox/color_range.cpp | 1 - src/Matrox/template_matching.cpp | 25 +++------ src/Matrox/template_matching.h | 2 +- src/Matrox/utils.cpp | 93 ++++++++++++++++++++++++++++++-- src/Matrox/utils.h | 2 + tests/test_color_range.cpp | 19 +++---- tests/test_template_matching.cpp | 92 +++++++++++++++++++++---------- tests/test_total.cpp | 82 +++++++++++++++++++--------- 9 files changed, 265 insertions(+), 85 deletions(-) create mode 100644 opencv_template_matching.py diff --git a/opencv_template_matching.py b/opencv_template_matching.py new file mode 100644 index 0000000..a590aaa --- /dev/null +++ b/opencv_template_matching.py @@ -0,0 +1,34 @@ +import cv2 as cv +import numpy as np +import time +from matplotlib import pyplot as plt +img = cv.imread("C:\\Users\\zjc\\Desktop\\cotton_image_new\\357.bmp", cv.IMREAD_GRAYSCALE) +assert img is not None, "file could not be read, check with os.path.exists()" +img2 = img.copy() +template = cv.imread(r'C:\Users\zjc\Desktop\templates\template1.png', cv.IMREAD_GRAYSCALE) +assert template is not None, "file could not be read, check with os.path.exists()" +w, h = template.shape[::-1] +# All the 6 methods for comparison in a list +methods = ['cv.TM_CCOEFF', 'cv.TM_CCOEFF_NORMED', 'cv.TM_CCORR', + 'cv.TM_CCORR_NORMED', 'cv.TM_SQDIFF', 'cv.TM_SQDIFF_NORMED'] +for meth in methods: + img = img2.copy() + method = eval(meth) + # Apply template Matching + tim1 = time.time() + res = cv.matchTemplate(img,template,method) + print(time.time() - tim1) + min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res) + # If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum + if method in [cv.TM_SQDIFF, cv.TM_SQDIFF_NORMED]: + top_left = min_loc + else: + top_left = max_loc + bottom_right = (top_left[0] + w, top_left[1] + h) + cv.rectangle(img,top_left, bottom_right, 255, 2) + plt.subplot(121),plt.imshow(res,cmap = 'gray') + plt.title('Matching Result'), plt.xticks([]), plt.yticks([]) + plt.subplot(122),plt.imshow(img,cmap = 'gray') + plt.title('Detected Point'), plt.xticks([]), plt.yticks([]) + plt.suptitle(meth) + plt.show() \ No newline at end of file diff --git a/src/Matrox/color_range.cpp b/src/Matrox/color_range.cpp index 10674cd..d58f3e7 100644 --- a/src/Matrox/color_range.cpp +++ b/src/Matrox/color_range.cpp @@ -14,7 +14,6 @@ void lab_process_raw(const MIL_ID& inputImage, MIL_ID& outputImageLab, const std int denoising = params.at("lab_denoising"); - // Check number of bands MIL_INT NumBands = 0; MbufInquire(inputImage, M_SIZE_BAND, &NumBands); diff --git a/src/Matrox/template_matching.cpp b/src/Matrox/template_matching.cpp index e70a586..89c43cc 100644 --- a/src/Matrox/template_matching.cpp +++ b/src/Matrox/template_matching.cpp @@ -17,7 +17,7 @@ void pre_process(const MIL_ID& inputImage, MIL_ID& outputImageSuspect, const map MimArith(outputImageSuspect, M_NULL, outputImageSuspect, M_NOT); } -TemplateMatcher::TemplateMatcher(MIL_ID system, MIL_ID display, std::map& param) +TemplateMatcher::TemplateMatcher(MIL_ID& system, MIL_ID& display, std::map& param) : MilSystem(system), MilDisplay(display), isInitialized(false), param(param) { } @@ -25,11 +25,9 @@ TemplateMatcher::TemplateMatcher(MIL_ID system, MIL_ID display, std::map& template_pat static_cast(ModelsOffsetY[i]), static_cast(ModelsSizeX[i]), static_cast(ModelsSizeY[i])); - - MgraColor(M_DEFAULT, ModelsDrawColor[i]); - MmodDraw(M_DEFAULT, MilSearchContext, GraphicList, - M_DRAW_BOX + M_DRAW_POSITION, i, M_ORIGINAL); - if (this->param["isdisplay"] == 1) { + MgraColor(M_DEFAULT, ModelsDrawColor[i]); + MmodDraw(M_DEFAULT, MilSearchContext, GraphicList, + M_DRAW_BOX + M_DRAW_POSITION, i, M_ORIGINAL); MosGetch(); } + MbufFree(template_temporary); MbufFree(template_temporary_uint8); } @@ -168,19 +165,11 @@ void TemplateMatcher::findModels(const MIL_ID& inputImage,MIL_ID& outputImage) } // 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); + MmodDraw(M_DEFAULT, MilResult, outputImage, M_DRAW_EDGES, i, M_DEFAULT); } - } else { std::cout << "No models found.\n"; } - // MosPrintf(MIL_TEXT("Press to EXIT.\n\n")); - // MosGetch(); MbufFree(input_image_uint8); } @@ -251,7 +240,7 @@ void TemplateMatcher::LoadConfig(const string& config_path) } -void TemplateMatcher::FindTemplates( const MIL_ID& inputImage, MIL_ID& outputImage,const std::map ¶ms) +void TemplateMatcher::FindTemplates( const MIL_ID& inputImage, MIL_ID& outputImage, const std::map ¶ms) { // Perform template matching this -> findModels(inputImage,outputImage); diff --git a/src/Matrox/template_matching.h b/src/Matrox/template_matching.h index 93be1ce..14d274f 100644 --- a/src/Matrox/template_matching.h +++ b/src/Matrox/template_matching.h @@ -35,7 +35,7 @@ private: public: // Constructor - TemplateMatcher(MIL_ID system, MIL_ID display, std::map& param); + TemplateMatcher(MIL_ID& system, MIL_ID& display, std::map& param); void LoadConfig(const std::string& config_path); diff --git a/src/Matrox/utils.cpp b/src/Matrox/utils.cpp index 30636db..9acf3ab 100644 --- a/src/Matrox/utils.cpp +++ b/src/Matrox/utils.cpp @@ -4,7 +4,7 @@ #include "utils.h" - +#include #include #include #include @@ -170,15 +170,24 @@ std::unordered_map loadConfig(const std::string& filename){ Mat mil2mat(const MIL_ID mil_img) { // 获取 MIL 图像的宽度、高度和通道数 - MIL_INT width, height, channels; + MIL_INT width, height, channels, bitDepth; + MbufInquire(mil_img, M_SIZE_X, &width); MbufInquire(mil_img, M_SIZE_Y, &height); MbufInquire(mil_img, M_SIZE_BAND, &channels); + MbufInquire(mil_img, M_SIZE_BIT, &bitDepth); if (channels == 1) { // 单通道图像,直接读取整个缓冲区 Mat grayImage(height, width, CV_8UC1); - MbufGet(mil_img, grayImage.data); + if (bitDepth == 1) { + MIL_ID temp_img; + temp_img = convert_to_uint8(mil_img); + MbufGet(temp_img, grayImage.data); + MbufFree(temp_img); + } else { + MbufGet(mil_img, grayImage.data); + } return grayImage; } if (channels == 3) { @@ -217,3 +226,81 @@ Mat mil2mat(const MIL_ID mil_img) { return Mat(); } + +#include +#include +#include + +void displayCombinedResults(const std::vector& images, const std::string& windowName) { + // Get the screen resolution (you can adjust this if needed, this is for a typical screen) + int screen_width = round(GetSystemMetrics(SM_CXSCREEN) * 0.4); + int screen_height = round(GetSystemMetrics(SM_CYSCREEN) * 0.4); + + // First, we need to find the maximum width and height among the input images + int max_width = 0; + int max_height = 0; + + // Loop over all images to get the maximum dimensions + for (const auto& img : images) { + if (!img.empty()) { + max_width = max(max_width, img.cols); + max_height = max(max_height, img.rows); + } + } + + // Resize all images to a reasonable scale to fit the screen + float scale_factor = min((float)screen_width / max_width, (float)screen_height / max_height); + + // If the images are already too large, reduce the scale factor + if (scale_factor > 1.0) scale_factor = 1.0; + + std::vector resized_images; + for (const auto& img : images) { + if (!img.empty()) { + cv::Mat resized_img; + // Resize each image based on the scale factor + cv::resize(img, resized_img, cv::Size(), scale_factor, scale_factor); + resized_images.push_back(resized_img); + } + } + + // Calculate the grid size for displaying images + int num_images = resized_images.size(); + int num_cols = std::ceil(std::sqrt(num_images)); // Trying to make a square-like grid + int num_rows = std::ceil((float)num_images / num_cols); + + std::vector rows; + + for (int i = 0; i < num_rows; ++i) { + std::vector row_images; + + for (int j = 0; j < num_cols; ++j) { + int index = i * num_cols + j; + if (index < resized_images.size()) { + row_images.push_back(resized_images[index]); + } else { + // If there's no image, create an empty placeholder (black) image + row_images.push_back(cv::Mat::zeros(resized_images[0].rows, resized_images[0].cols, resized_images[0].type())); + } + } + + // Concatenate horizontally to create a single row + cv::Mat row; + cv::hconcat(row_images, row); + rows.push_back(row); + } + + // Concatenate all rows vertically to create the final grid + cv::Mat final_result; + cv::vconcat(rows, final_result); + + // Set the window properties to allow resizing + cv::namedWindow(windowName, cv::WINDOW_NORMAL); + cv::resizeWindow(windowName, screen_width, screen_height); // Resize window to screen size + + // Display the combined result + cv::imshow(windowName, final_result); + + // Wait for the user to press a key or the window to close + cv::waitKey(0); +} diff --git a/src/Matrox/utils.h b/src/Matrox/utils.h index 5ca75cb..1a35d68 100644 --- a/src/Matrox/utils.h +++ b/src/Matrox/utils.h @@ -43,4 +43,6 @@ cv::Mat mil2mat(MIL_ID mil_img); void processImage(cv::Mat& img); std::unordered_map loadConfig(const std::string& filename); + +void displayCombinedResults(const std::vector& images, const std::string& windowName); #endif //UTILS_H diff --git a/tests/test_color_range.cpp b/tests/test_color_range.cpp index d24d087..caa4a33 100644 --- a/tests/test_color_range.cpp +++ b/tests/test_color_range.cpp @@ -5,7 +5,7 @@ #include "Matrox/utils.h" #include "Matrox/color_range.h" -#define IMAGE_PATH MIL_TEXT("C:\\Users\\zjc\\Desktop\\xixian.png") +#define IMAGE_PATH MIL_TEXT("C:\\Users\\zjc\\Desktop\\123.bmp") #define SAVE_PATH MIL_TEXT("C:\\Users\\zjc\\Desktop\\diguandai.png") // Global variables @@ -23,16 +23,17 @@ int main() // Define color ranges std::map params; - read_params_from_file("C:\\Users\\zjc\\Desktop\\config\\color_range_config.txt", params); - + read_params_from_file("..\\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); + for(int i = 0; i < 50; i++) { + // Measure execution time + measure_execution_time([&]() { + high_sat_detect(MilImage, detection_result, params); + }); + MbufSave(convert_to_wstring("./runs/test_color_range" + std::to_string(i) + ".png"), + detection_result); + } // Display result std::cout << "所有颜色检测已完成并合并。按 退出。" << std::endl; diff --git a/tests/test_template_matching.cpp b/tests/test_template_matching.cpp index c09b1ad..d23a935 100644 --- a/tests/test_template_matching.cpp +++ b/tests/test_template_matching.cpp @@ -7,15 +7,74 @@ #include #include "Matrox/utils.h" #include "Matrox/template_matching.h" - +#include #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; +namespace fs = std::filesystem; +void LoadImagesFromFolder(const std::string& folderPath, MIL_ID MilSystem) +{ + // 遍历文件夹中的所有文件 + for (const auto& entry : fs::directory_iterator(folderPath)) + { + // 只处理图片文件(例如 .jpg, .png, .bmp 等) + if (entry.is_regular_file() && + (entry.path().extension() == ".jpg" || + entry.path().extension() == ".png" || + entry.path().extension() == ".bmp")) + { + MIL_ID MilImage = M_NULL; // 每次读取新图像时都创建新的 MilImage 对象 + std::string imagePath = entry.path().string(); // 获取文件的路径 + + // 使用 MIL_TEXT 宏将 imagePath 转换为适合 MIL 函数的字符串格式 + + std::map params; + read_params_from_file("C:\\Users\\zjc\\Desktop\\config\\template_color_config.txt", params); + // 调用 MbufRestore 加载图像 + MbufRestore(convert_to_wstring(imagePath), MilSystem, &MilImage); + + if (MilImage != M_NULL) + { + std::cout << "Successfully loaded image: " << imagePath << std::endl; + // Initialize combined result + MIL_ID detection_result = M_NULL; + MIL_ID detection_resize = M_NULL; + cv::Mat template_result; + MIL_ID output_Image= M_NULL; + TemplateMatcher matcher(MilSystem, MilDisplay, params); + matcher.LoadConfig("C:\\Users\\zjc\\Desktop\\config\\template_config.txt"); + // Measure execution time + for (int i = 0; i <1; i++) { + 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.FindTemplates(detection_resize,output_Image,params); + template_result = mil2mat(output_Image); + cv::imwrite("./runs/template_result222"+std::to_string(i)+".png", template_result); + }); + } + MbufFree(detection_result); + MbufFree(MilImage); + MbufFree(output_Image); + } + else + { + std::cerr << "Failed to load image: " << imagePath << std::endl; + } + + } + } +} + int main() { using namespace std; @@ -26,36 +85,13 @@ int main() { 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; + std::string folderPath ="C:/Users/zjc/Desktop/cotton_image_new"; // 请替换为你自己的文件夹路径 + // 加载文件夹中的所有图片 + LoadImagesFromFolder(folderPath, MilSystem); - - - MIL_ID output_Image= M_NULL; - TemplateMatcher matcher(MilSystem, MilDisplay, params); - matcher.LoadConfig("C:\\Users\\zjc\\Desktop\\config\\template_config.txt"); - // 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.FindTemplates(detection_resize,output_Image,params); - - }); - MbufSave(SAVE_PATH, detection_result); // Display result + MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL); - std::cout << "所有颜色检测已完成并合并。按 退出。" << std::endl; - getchar(); - - MbufFree(detection_result); - MbufFree(MilImage); return 0; } \ No newline at end of file diff --git a/tests/test_total.cpp b/tests/test_total.cpp index 57d3026..9591744 100644 --- a/tests/test_total.cpp +++ b/tests/test_total.cpp @@ -3,7 +3,9 @@ #include #include #include - +#include +#include +#include #include "Mil.h" #include "Matrox/utils.h" #include "Matrox/color_range.h" @@ -12,8 +14,11 @@ // 宏定义 #define SAVE_PATH3 MIL_TEXT("C:\\Users\\zjc\\Desktop\\suspect.png") #define SAVE_PATH4 MIL_TEXT("C:\\Users\\zjc\\Desktop\\suspect2.png") -#define IMAGE_PATH MIL_TEXT(".\\test_imgs\\357.bmp") -std::string imagePath = "C:\\Users\\zjc\\Desktop\\dimo.bmp"; +#define IMAGE_PATH MIL_TEXT(".\\test_imgs\\dimo.bmp") + +#define run_high_sat true; +#define run_templating true; +#define run_deep_learning true; MIL_ID MilApplication, MilSystem, MilDisplay; std::map params; @@ -25,61 +30,88 @@ int main() { // 读取图片 MIL_ID MilImage=M_NULL, MilHighSatResult = M_NULL, MilTemplateMatchingResult = M_NULL; MbufRestore(IMAGE_PATH, MilSystem, &MilImage); - if (MilImage == M_NULL) { - std::cerr << "Error: Failed to restore image from " << IMAGE_PATH << std::endl; - MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL); - return -1; - } Timer timer1, timer2; std::map params; read_params_from_file("..\\config\\color_range_config.txt", params); read_params_from_file("..\\config\\template_color_config.txt", params); - TemplateMatcher matcher(MilSystem, MilDisplay, params); - matcher.LoadConfig("..\\config\\template_config.txt"); +#if run_templating + TemplateMatcher matcher(MilSystem, MilDisplay, params); + matcher.LoadConfig("..\\config\\template_config.txt"); +#endif + +#if run_deep_learning ONNXRunner runner; runner.load("C:\\Users\\zjc\\Desktop\\dimo_11.14.onnx"); +#endif + timer1.printElapsedTime("Load config and templates and models"); - cv::Mat deep_result, high_sat_result, template_result, total_result; + cout << "Sequence running start:" << endl; for(int i = 0; i < 10; i++) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); cout << i << endl; timer1.restart(); timer2.restart(); + cv::Mat deep_result, high_sat_result, template_result, total_result; + // 艳丽色彩检测 +#if run_high_sat high_sat_detect(MilImage, MilHighSatResult, params); - timer1.printElapsedTime("High Sat Predict finished"); + MIL_ID MilHighSatUint8 = convert_to_uint8(MilHighSatResult); + MdispSelect(MilDisplay, MilHighSatUint8); + high_sat_result = mil2mat(MilHighSatResult); + timer1.printElapsedTime("High Sat finished"); +#else + high_sat_result = cv::Mat::zeros(1024,4096, CV_8UC1); +#endif + +#if run_templating // 模板匹配检测 matcher.predict(MilImage, MilTemplateMatchingResult, params); - timer1.printElapsedTime("Template Matching Predict finished"); + template_result = mil2mat(MilTemplateMatchingResult); + timer1.printElapsedTime("Template Matching finished"); +#else + template_result= cv::Mat::zeros(1024,4096, CV_8UC1); +#endif +#if run_deep_learning // 深度学习检测 cv::Mat cv_input = mil2mat(MilImage); std::vector result = runner.predict(cv_input); deep_result = runner.postProcess(result, cv_input); - std::string savepath = "C:\\Users\\zjc\\Desktop\\suspect_mask2.png"; - cv::imwrite(savepath, deep_result); - timer1.printElapsedTime("Deep Learning Predict finished"); - high_sat_result = mil2mat(MilHighSatResult); - template_result = mil2mat(MilTemplateMatchingResult); + // 640x640 的全零矩阵 +#else + deep_result = cv::Mat::zeros(1024,4096, CV_8UC1); +#endif + + + + timer1.printElapsedTime("Deep Learning finished"); + if (!deep_result.empty() && !high_sat_result.empty() && !template_result.empty()) { - cv::bitwise_and(deep_result, high_sat_result, total_result); - cv::bitwise_and(total_result, template_result, total_result); + cv::bitwise_or(deep_result, high_sat_result, total_result); + cv::bitwise_or(total_result, template_result, total_result); } else { cerr << "Error: One or more detection results are empty!" << endl; } timer2.printElapsedTime("Prediction finished Total"); - cv::imshow("Result", total_result); - cv::waitKey(0); + + cv::imwrite("./runs/deep_result"+std::to_string(i)+".png", deep_result); + cv::imwrite("./runs/high_sat_result"+std::to_string(i)+".png", high_sat_result); + cv::imwrite("./runs/template_result"+std::to_string(i)+".png", template_result); + cv::imwrite("./runs/total_result"+std::to_string(i)+".png", total_result); + std::vector images = {deep_result, high_sat_result, template_result, total_result}; + displayCombinedResults(images, "Combined Results"); } - - - // 释放资源 MbufFree(MilImage); MbufFree(MilHighSatResult); MbufFree(MilTemplateMatchingResult); +#if run_templating + matcher.~TemplateMatcher(); +#endif MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL); std::cout << "所有模块检测已完成!按 退出。" << std::endl;