diff --git a/src/Matrox/mask.cpp b/src/Matrox/mask.cpp index cd9e02c..bd49989 100644 --- a/src/Matrox/mask.cpp +++ b/src/Matrox/mask.cpp @@ -7,70 +7,114 @@ #include "utils.h" -std::vector> generateMaskFromImage(const MIL_ID& inputImage, int widthBlocks, int heightBlocks, int threshold = 10, int rowRange = 50) { - // 读取图像 - cv::Mat image = mil2mat(inputImage); - // - // // 检查图像是否成功读取 - // if (image.empty()) { - // std::cerr << "无法加载图像,请检查路径是否正确: " << imagePath << std::endl; - // exit(EXIT_FAILURE); - // } +#include +#include +#include +using namespace std; - // 确保图像是二值化的 +// Function to convert an image into a mask based on sizeThreshold +vector> generateMask( + const MIL_ID& inputImg, + int outputWidth, + int outputHeight, + int sizeThreshold +) { + cv::Mat image = mil2mat(inputImg); + + // Ensure the image is binary 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; + int blockWidth = imageWidth / outputWidth; + int blockHeight = imageHeight / outputHeight; - // 创建掩膜矩阵 (uint8_t 类型) - std::vector> mask(heightBlocks, std::vector(widthBlocks, 0)); + vector> mask(outputHeight, vector(outputWidth, 0)); - // 遍历每个块并统计白色像素点的数量 - for (int i = 0; i < heightBlocks; ++i) { - for (int j = 0; j < widthBlocks; ++j) { - // 计算块的起始和结束位置 + for (int i = 0; i < outputHeight; ++i) { + for (int j = 0; j < outputWidth; ++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; + int x_end = (j == outputWidth - 1) ? imageWidth : (j + 1) * blockWidth; + int y_end = (i == outputHeight - 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); - // 如果白色像素数大于阈值,将该块标记为 255 - if (whitePixelCount > threshold) { + if (whitePixelCount > sizeThreshold) { mask[i][j] = 1; } } } - // 遍历每一列,处理规则:当某列出现第一个1时,将其后rowRange行全部置为255 - for (int j = 0; j < widthBlocks; ++j) { - int i = 0; - while (i < heightBlocks) { - if (mask[i][j] == 1) { - // 找到第一个1,处理后面rowRange行 - for (int k = i; k < std::min(i + rowRange, heightBlocks); ++k) { - mask[k][j] = 1; - } - // 跳过已经设置为255的后rowRange行 - i += rowRange; - } else { - // 如果当前位置为0,则继续检测下一行 - ++i; - } - } - } - return mask; } +pair>, vector>> applyRowRangeDelay( + const vector>& mask, + const vector>& tail, + int rowRange +) { + int outputHeight = (int)mask.size(); + int outputWidth = (int)mask[0].size(); + + vector> mask_after_row_range(outputHeight, vector(outputWidth, 0)); + vector> newTail(rowRange, vector(outputWidth, 0)); + + // 先将旧的 tail 映射到 mask_after_row_range 的顶部几行 + for (int i = 0; i < (int)tail.size(); ++i) { + for (int j = 0; j < outputWidth; ++j) { + if (i < outputHeight) { + mask_after_row_range[i][j] = max(mask_after_row_range[i][j], tail[i][j]); + } + } + } + + // 对当前 mask 应用 rowRange 的拖影效果 + for (int j = 0; j < outputWidth; ++j) { + for (int i = 0; i < outputHeight; ++i) { + if (mask[i][j] == 1) { + // 从当前行 i 开始,向下扩展 rowRange 行 + int end_line = i + rowRange - 1; + + // 先处理仍在 mask 范围内的部分 + int inside_mask_end = min(end_line, outputHeight - 1); + for (int line = i; line <= inside_mask_end; ++line) { + mask_after_row_range[line][j] = 1; + } + + // 超出 mask 范围的行进入 tail + if (end_line >= outputHeight) { + // 从 outputHeight 行开始的部分属于 tail + for (int line = outputHeight; line <= end_line; ++line) { + int tail_line_idx = line - outputHeight; + if (tail_line_idx >= 0 && tail_line_idx < (int)newTail.size()) { + newTail[tail_line_idx][j] = 1; + } + } + } + } + } + } + + return {mask_after_row_range, newTail}; +} + + +// Updated wrapper function +pair>, vector>> generateMaskWithTail( + const MIL_ID& inputImg, + const vector>& tail, + int outputWidth, + int outputHeight, + int sizeThreshold = 10, + int rowRange = 50 +) { + // Generate the mask from the image + vector> mask = generateMask(inputImg, outputWidth, outputHeight, sizeThreshold); + + // Apply rowRange delay + return applyRowRangeDelay(mask, tail, rowRange); +} diff --git a/src/Matrox/mask.h b/src/Matrox/mask.h index 6a3ebfd..66c70f3 100644 --- a/src/Matrox/mask.h +++ b/src/Matrox/mask.h @@ -10,7 +10,16 @@ #include #include"mil.h" #include +using namespace std; -std::vector> generateMaskFromImage(const MIL_ID& inputImage, int widthBlocks, int heightBlocks, int threshold , int rowRange) ; +pair>, vector>> generateMaskWithTail( + const MIL_ID& inputImg, + const vector>& tail, + int outputWidth, + int outputHeight, + int sizeThreshold, + int rowRange +); + #endif //MASK_H diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4c23ee4..d01e9fb 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -18,7 +18,7 @@ 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}) +target_link_libraries(test_mask Matrox CVDL ${OpenCV_LIBS} ${MIL_LIBS}) #测试用例 4:test_onnx add_executable(test_onnx diff --git a/tests/test_mask.cpp b/tests/test_mask.cpp index de2ad34..a0c42d2 100644 --- a/tests/test_mask.cpp +++ b/tests/test_mask.cpp @@ -1,49 +1,188 @@ // // Created by zjc on 24-11-26. // -// #include #include "vector" -#include"iostream" -#include"string" -#include"Matrox/mask.h" +#include "iostream" +#include "string" +#include "Matrox/mask.h" +#include "CVDL/OnnxRunner.h" +#include "mil.h" -#include"mil.h" -#define Image_PATH3 MIL_TEXT("C:\\Users\\zjc\\Desktop\\mask_5.png") +#define Image_PATH0 MIL_TEXT("test_imgs\\test_mask_imgs\\mask_1.png") +#define Image_PATH1 MIL_TEXT("test_imgs\\test_mask_imgs\\mask_6.png") MIL_ID MilApplication, MilSystem, MilDisplay; int main() { - // 指定图像路径 - // std::string imagePath = "C:\\Users\\zjc\\Desktop\\mask_1.png"; MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, &MilDisplay, M_NULL, M_NULL); - MIL_ID MilImage = M_NULL, MilHighSatResult = M_NULL, MilTemplateMatchingResult = M_NULL; - MbufRestore(Image_PATH3, MilSystem, &MilImage); - // std::unordered_map config = loadConfig("C:\\Users\\zjc\\Desktop\\config\\mask_config.txt"); - // // 设置分块数量和白色像素点阈值 - // int widthBlocks = config["widthBlocks"]; - // int heightBlocks = config["heightBlocks"]; - // int threshold = config["threshold"]; - - // 输出参数值 - // std::cout << "widthBlocks: " << widthBlocks << std::endl; int widthBlocks = 24; - int heightBlocks = 1024; + int heightBlocks = 96; int threshold = 20; - int rowRange = 50; // 后续50行设置为 + int rowRange = 1; - // 生成掩膜 - std::vector> mask = generateMaskFromImage(MilImage, widthBlocks, heightBlocks, threshold, rowRange); + std::vector> tail(0); - // 打印掩膜结果 - for (int i = 0; i < heightBlocks; ++i) { - for (int j = 0; j < widthBlocks; ++j) { - std::cout << (int)mask[i][j] << " "; + std::cout << "=============================row 632, 1020 = 1 ===========================================" << std::endl; + for (int imgIndex = 0; imgIndex < 2; imgIndex++) { + MIL_ID MilImage = M_NULL; + if (imgIndex == 0) + MbufRestore(Image_PATH0, MilSystem, &MilImage); + else + MbufRestore(Image_PATH1, MilSystem, &MilImage); + + Timer timer1; + timer1.restart(); + auto [mask, newTail] = generateMaskWithTail(MilImage, tail, widthBlocks, heightBlocks, threshold, rowRange); + tail = newTail; + timer1.printElapsedTime("Convert to mask spent"); + + // 打印mask结果 + for (int r = 0; r < heightBlocks; ++r) { + std::cout << "mask Row: " << r << " "; + for (int c = 0; c < widthBlocks; ++c) { + std::cout << (int)mask[r][c] << " "; + } + std::cout << std::endl; } - std::cout << std::endl; - } - MbufFree(MilImage); - MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL); + if(imgIndex==0) + { + + // 打印tail结果(使用tail.size()进行循环,避免越界) + for (size_t r = 0; r < tail.size(); ++r) { + std::cout << "tail 0 Row: " << r << " "; + for (size_t c = 0; c < tail[r].size(); ++c) { + std::cout << (int)tail[r][c] << " "; + } + std::cout << std::endl; + } + } + MbufFree(MilImage); + } + + std::cout << "=============================row 1020 = 1 ===========================================" << std::endl; + rowRange = 10; + tail = std::vector>(rowRange, std::vector(widthBlocks, 0)); + for (int imgIndex = 0; imgIndex < 2; imgIndex++) { + MIL_ID MilImage = M_NULL; + if (imgIndex == 0) + MbufRestore(Image_PATH0, MilSystem, &MilImage); + else + MbufRestore(Image_PATH1, MilSystem, &MilImage); + + Timer timer1; + timer1.restart(); + auto [mask, newTail] = generateMaskWithTail(MilImage, tail, widthBlocks, heightBlocks, threshold, rowRange); + tail = newTail; + timer1.printElapsedTime("Convert to mask spent"); + + // 打印mask结果 + for (int r = 0; r < heightBlocks; ++r) { + std::cout << "Row: " << r << " "; + for (int c = 0; c < widthBlocks; ++c) { + std::cout << (int)mask[r][c] << " "; + } + std::cout << std::endl; + } + + if(imgIndex==0) + { + // 打印tail结果(使用tail.size()进行循环,避免越界) + for (size_t r = 0; r < tail.size(); ++r) { + std::cout << "tail 0 Row: " << r << " "; + for (size_t c = 0; c < tail[r].size(); ++c) { + std::cout << (int)tail[r][c] << " "; + } + std::cout << std::endl; + } + } + + MbufFree(MilImage); + } + + std::cout << "=============================row 1030 = 1 ===========================================" << std::endl; + rowRange = 20; + tail = std::vector>(rowRange, std::vector(widthBlocks, 0)); + for (int imgIndex = 0; imgIndex < 2; imgIndex++) { + MIL_ID MilImage = M_NULL; + if (imgIndex == 0) + MbufRestore(Image_PATH0, MilSystem, &MilImage); + else + MbufRestore(Image_PATH1, MilSystem, &MilImage); + + Timer timer1; + timer1.restart(); + auto [mask, newTail] = generateMaskWithTail(MilImage, tail, widthBlocks, heightBlocks, threshold, rowRange); + tail = newTail; + timer1.printElapsedTime("Convert to mask spent"); + + // 打印mask结果 + for (int r = 0; r < heightBlocks; ++r) { + std::cout << "Row: " << r << " "; + for (int c = 0; c < widthBlocks; ++c) { + std::cout << (int)mask[r][c] << " "; + } + std::cout << std::endl; + } + + // 打印tail结果 + if(imgIndex==0) + { + // 打印tail结果(使用tail.size()进行循环,避免越界) + for (size_t r = 0; r < tail.size(); ++r) { + std::cout << "tail 0 Row: " << r << " "; + for (size_t c = 0; c < tail[r].size(); ++c) { + std::cout << (int)tail[r][c] << " "; + } + std::cout << std::endl; + } + } + + MbufFree(MilImage); + } + + std::cout << "=============================row 1030 = 1 ===========================================" << std::endl; + rowRange = 40; + tail = std::vector>(rowRange, std::vector(widthBlocks, 0)); + for (int imgIndex = 0; imgIndex < 2; imgIndex++) { + MIL_ID MilImage = M_NULL; + if (imgIndex == 0) + MbufRestore(Image_PATH0, MilSystem, &MilImage); + else + MbufRestore(Image_PATH1, MilSystem, &MilImage); + + Timer timer1; + timer1.restart(); + auto [mask, newTail] = generateMaskWithTail(MilImage, tail, widthBlocks, heightBlocks, threshold, rowRange); + tail = newTail; + timer1.printElapsedTime("Convert to mask spent"); + + // 打印mask结果 + for (int r = 0; r < heightBlocks; ++r) { + std::cout << "Row: " << r << " "; + for (int c = 0; c < widthBlocks; ++c) { + std::cout << (int)mask[r][c] << " "; + } + std::cout << std::endl; + } + + // 打印tail结果 + if(imgIndex==0) + { + // 打印tail结果(使用tail.size()进行循环,避免越界) + for (size_t r = 0; r < tail.size(); ++r) { + std::cout << "tail 0 Row: " << r << " "; + for (size_t c = 0; c < tail[r].size(); ++c) { + std::cout << (int)tail[r][c] << " "; + } + std::cout << std::endl; + } + } + + MbufFree(MilImage); + } + + MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL); return 0; -} \ No newline at end of file +}