mirror of
https://github.com/Karllzy/cotton_color.git
synced 2025-11-09 03:03:53 +00:00
修复cotton_color的bug 添加color_range的matrox实现
This commit is contained in:
parent
ea72ee9310
commit
af063ae8e0
@ -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)
|
||||
target_link_libraries(ui Qt6::Widgets)
|
||||
|
||||
|
||||
@ -1,3 +1,204 @@
|
||||
//
|
||||
// Created by zjc on 24-11-12.
|
||||
//
|
||||
|
||||
#include <mil.h>
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#define IMAGE_PATH MIL_TEXT("C:\\Users\\zjc\\Desktop\\cotton2.bmp")
|
||||
|
||||
// 全局变量,方便在各个函数中使用
|
||||
MIL_ID MilApplication = M_NULL, MilSystem = M_NULL, MilDisplay = M_NULL;
|
||||
|
||||
|
||||
// 时间测量模板函数
|
||||
template <typename Func>
|
||||
void measureExecutionTime(Func func) {
|
||||
// 获取当前时间作为起点
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
// 执行传入的函数
|
||||
func();
|
||||
|
||||
// 获取当前时间作为结束点
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
|
||||
// 计算时间差并转换为毫秒
|
||||
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
|
||||
|
||||
std::cout << "Function execution time: " << duration.count() << " milliseconds" << std::endl;
|
||||
}
|
||||
|
||||
// LabProcess 函数,支持通过参数控制阈值范围,提供默认值
|
||||
void LabProcess(MIL_ID& inputImage, MIL_ID& outputImageLab,
|
||||
MIL_DOUBLE lowerL = 101.0, MIL_DOUBLE upperL = 135.0,
|
||||
MIL_DOUBLE lowerA = 101.0, MIL_DOUBLE upperA = 120.0,
|
||||
MIL_DOUBLE lowerB = 95.0, MIL_DOUBLE upperB = 134.0)
|
||||
{
|
||||
MIL_ID MilLabImage = M_NULL, MilLChannel = M_NULL, MilAChannel = M_NULL, MilBChannel = M_NULL;
|
||||
MIL_ID MilBinaryL = M_NULL, MilBinaryA = M_NULL, MilBinaryB = M_NULL;
|
||||
|
||||
// 检查输入图像的通道数
|
||||
MIL_INT NumBands = 0;
|
||||
MbufInquire(inputImage, M_SIZE_BAND, &NumBands);
|
||||
if (NumBands != 3)
|
||||
{
|
||||
printf("输入图像不是 3 通道图像,请提供彩色图像。\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// 分配用于存储 Lab 图像的缓冲区
|
||||
MbufAllocColor(MbufInquire(inputImage, M_OWNER_SYSTEM, M_NULL), 3,
|
||||
MbufInquire(inputImage, M_SIZE_X, M_NULL),
|
||||
MbufInquire(inputImage, M_SIZE_Y, M_NULL),
|
||||
8 + M_UNSIGNED,
|
||||
M_IMAGE + M_PROC + M_DISP,
|
||||
&MilLabImage);
|
||||
|
||||
// 将图像从 sRGB 转换到 Lab
|
||||
MimConvert(inputImage, MilLabImage, M_SRGB_TO_LAB);
|
||||
|
||||
// 创建 Lab 通道的子缓冲区
|
||||
MbufChildColor(MilLabImage, 0, &MilLChannel);
|
||||
MbufChildColor(MilLabImage, 1, &MilAChannel);
|
||||
MbufChildColor(MilLabImage, 2, &MilBChannel);
|
||||
|
||||
// 分配二值图像缓冲区
|
||||
MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL),
|
||||
MbufInquire(inputImage, M_SIZE_Y, M_NULL), 8 + M_UNSIGNED,
|
||||
M_IMAGE + M_PROC + M_DISP, &MilBinaryL);
|
||||
MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL),
|
||||
MbufInquire(inputImage, M_SIZE_Y, M_NULL), 8 + M_UNSIGNED,
|
||||
M_IMAGE + M_PROC + M_DISP, &MilBinaryA);
|
||||
MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL),
|
||||
MbufInquire(inputImage, M_SIZE_Y, M_NULL), 8 + M_UNSIGNED,
|
||||
M_IMAGE + M_PROC + M_DISP, &MilBinaryB);
|
||||
|
||||
// 对每个通道进行阈值分割
|
||||
MimBinarize(MilLChannel, MilBinaryL, M_IN_RANGE, lowerL, upperL);
|
||||
MimBinarize(MilAChannel, MilBinaryA, M_IN_RANGE, lowerA, upperA);
|
||||
MimBinarize(MilBChannel, MilBinaryB, M_IN_RANGE, lowerB, upperB);
|
||||
|
||||
// 分配输出图像缓冲区
|
||||
MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL),
|
||||
MbufInquire(inputImage, M_SIZE_Y, M_NULL), 8 + M_UNSIGNED,
|
||||
M_IMAGE + M_PROC + M_DISP, &outputImageLab);
|
||||
|
||||
// 将结果合并
|
||||
MimArith(MilBinaryL, MilBinaryA, outputImageLab, M_AND);
|
||||
MimArith(outputImageLab, MilBinaryB, outputImageLab, M_AND);
|
||||
|
||||
// 释放资源
|
||||
MbufFree(MilBinaryL);
|
||||
MbufFree(MilBinaryA);
|
||||
MbufFree(MilBinaryB);
|
||||
MbufFree(MilLChannel);
|
||||
MbufFree(MilAChannel);
|
||||
MbufFree(MilBChannel);
|
||||
MbufFree(MilLabImage);
|
||||
}
|
||||
|
||||
// HSVProcess 函数,支持通过参数控制饱和度阈值,提供默认值
|
||||
void HSVProcess(MIL_ID& inputImage, MIL_ID& outputImageHSV, MIL_DOUBLE saturationThreshold = 120.0)
|
||||
{
|
||||
MIL_ID MilHSVImage = M_NULL, MilHChannel = M_NULL, MilSChannel = M_NULL, MilVChannel = M_NULL;
|
||||
|
||||
// 检查输入图像的通道数
|
||||
MIL_INT NumBands = 0;
|
||||
MbufInquire(inputImage, M_SIZE_BAND, &NumBands);
|
||||
if (NumBands != 3)
|
||||
{
|
||||
printf("输入图像不是 3 通道图像,请提供彩色图像。\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// 分配用于存储 HSV 图像的缓冲区
|
||||
MbufAllocColor(MbufInquire(inputImage, M_OWNER_SYSTEM, M_NULL), 3,
|
||||
MbufInquire(inputImage, M_SIZE_X, M_NULL),
|
||||
MbufInquire(inputImage, M_SIZE_Y, M_NULL),
|
||||
8 + M_UNSIGNED,
|
||||
M_IMAGE + M_PROC + M_DISP,
|
||||
&MilHSVImage);
|
||||
|
||||
// 将图像从 sRGB 转换到 HSV
|
||||
MimConvert(inputImage, MilHSVImage, M_RGB_TO_HSV);
|
||||
|
||||
// 创建 HSV 通道的子缓冲区
|
||||
MbufChildColor(MilHSVImage, 0, &MilHChannel);
|
||||
MbufChildColor(MilHSVImage, 1, &MilSChannel);
|
||||
MbufChildColor(MilHSVImage, 2, &MilVChannel);
|
||||
|
||||
// 分配输出图像缓冲区
|
||||
MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL),
|
||||
MbufInquire(inputImage, M_SIZE_Y, M_NULL), 8 + M_UNSIGNED,
|
||||
M_IMAGE + M_PROC + M_DISP, &outputImageHSV);
|
||||
|
||||
// 对 S 通道进行阈值分割
|
||||
MimBinarize(MilSChannel, outputImageHSV, M_GREATER, saturationThreshold, M_NULL);
|
||||
|
||||
// 释放资源
|
||||
MbufFree(MilHChannel);
|
||||
MbufFree(MilSChannel);
|
||||
MbufFree(MilVChannel);
|
||||
MbufFree(MilHSVImage);
|
||||
}
|
||||
|
||||
// 综合测试函数,调用 LabProcess 和 HSVProcess 并合并结果
|
||||
void test_hsv(MIL_ID& inputImage,
|
||||
MIL_DOUBLE lowerL = 101.0, MIL_DOUBLE upperL = 135.0,
|
||||
MIL_DOUBLE lowerA = 101.0, MIL_DOUBLE upperA = 120.0,
|
||||
MIL_DOUBLE lowerB = 95.0, MIL_DOUBLE upperB = 134.0,
|
||||
MIL_DOUBLE saturationThreshold = 120.0)
|
||||
{
|
||||
MIL_ID MilResultLab = M_NULL, MilResultHSV = M_NULL, MilCombinedResult = M_NULL;
|
||||
|
||||
// 调用 LabProcess
|
||||
LabProcess(inputImage, MilResultLab, lowerL, upperL, lowerA, upperA, lowerB, upperB);
|
||||
|
||||
// 调用 HSVProcess
|
||||
HSVProcess(inputImage, MilResultHSV, saturationThreshold);
|
||||
|
||||
// 分配合并结果的缓冲区
|
||||
MbufAlloc2d(MilSystem, MbufInquire(inputImage, M_SIZE_X, M_NULL),
|
||||
MbufInquire(inputImage, M_SIZE_Y, M_NULL), 8 + M_UNSIGNED,
|
||||
M_IMAGE + M_PROC + M_DISP, &MilCombinedResult);
|
||||
|
||||
// 合并 Lab 和 HSV 的结果(取“或”运算)
|
||||
MimArith(MilResultLab, MilResultHSV, MilCombinedResult, M_OR);
|
||||
|
||||
//// 显示合并后的结果图像
|
||||
MdispSelect(MilDisplay, MilCombinedResult);
|
||||
|
||||
//// 等待用户查看处理后的图像
|
||||
printf("图像已处理并合并,按下 <Enter> 退出程序。\n");
|
||||
getchar();
|
||||
|
||||
// 释放资源
|
||||
MbufFree(MilResultLab);
|
||||
MbufFree(MilResultHSV);
|
||||
MbufFree(MilCombinedResult);
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
MIL_ID MilImage = M_NULL;
|
||||
|
||||
// 初始化 MIL 应用程序
|
||||
MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, &MilDisplay, M_NULL, M_NULL);
|
||||
|
||||
// 加载输入图像
|
||||
MbufRestore(IMAGE_PATH, MilSystem, &MilImage);
|
||||
|
||||
// 使用 lambda 表达式测量 test_hsv() 的执行时间
|
||||
measureExecutionTime([&]() {
|
||||
test_hsv(MilImage);
|
||||
});
|
||||
|
||||
|
||||
// 释放资源
|
||||
MbufFree(MilImage);
|
||||
MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -55,51 +55,86 @@ void vibrantColorDetection(const Mat& inputImage, Mat& outputImage, const map<st
|
||||
// 对饱和度图像应用阈值处理
|
||||
threshold(saturation, outputImage, saturationThreshold, 255, THRESH_BINARY);
|
||||
}
|
||||
string openFileDialog() {
|
||||
std::wstring openFileDialog() {
|
||||
// 初始化文件选择对话框
|
||||
OPENFILENAME ofn; // 文件对话框结构
|
||||
wchar_t szFile[260]; // 存储选择的文件路径
|
||||
OPENFILENAMEW ofn; // 使用宽字符版本的结构
|
||||
wchar_t szFile[260] = {0}; // 存储选择的文件路径
|
||||
|
||||
// 设置 OPENFILENAME 结构的默认值
|
||||
// 设置 OPENFILENAMEW 结构的默认值
|
||||
ZeroMemory(&ofn, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = NULL;
|
||||
ofn.lpstrFile = szFile;
|
||||
ofn.lpstrFile = szFile; // 设置文件路径缓冲区
|
||||
ofn.nMaxFile = sizeof(szFile) / sizeof(szFile[0]);
|
||||
ofn.lpstrFilter = L"Image Files\0*.BMP;*.JPG;*.JPEG;*.PNG;*.GIF\0All Files\0*.*\0";
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.lpstrFileTitle = NULL;
|
||||
ofn.lpstrFileTitle = NULL; // 不需要单独的文件名
|
||||
ofn.nMaxFileTitle = 0;
|
||||
ofn.lpstrInitialDir = NULL;
|
||||
ofn.lpstrTitle = L"Select an image file";
|
||||
ofn.lpstrInitialDir = NULL; // 使用默认初始目录
|
||||
ofn.lpstrTitle = L"Select an image file"; // 对话框标题
|
||||
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
|
||||
|
||||
// 打开文件选择对话框
|
||||
if (GetOpenFileName(&ofn) == TRUE) {
|
||||
// 将 wchar_t 转换为 string
|
||||
wstring ws(szFile);
|
||||
string filePath(ws.begin(), ws.end());
|
||||
return filePath;
|
||||
if (GetOpenFileNameW(&ofn) == TRUE) {
|
||||
return szFile; // 返回选中的文件路径
|
||||
}
|
||||
|
||||
return ""; // 如果用户取消,返回空字符串
|
||||
return L""; // 如果用户取消,返回空字符串
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief 读取图像文件,支持 Unicode 路径。
|
||||
*
|
||||
* @return 加载的图像,类型为 cv::Mat。如果加载失败,返回空的 Mat。
|
||||
*/
|
||||
Mat readImage() {
|
||||
// 读取输入图像
|
||||
string imagePath = openFileDialog();
|
||||
// 读取输入图像路径
|
||||
std::wstring imagePath = openFileDialog();
|
||||
|
||||
if (imagePath.empty()) {
|
||||
cout << "No file selected or user cancelled." << endl;
|
||||
wcout << L"No file selected or user cancelled." << endl;
|
||||
return Mat();
|
||||
}
|
||||
|
||||
// 使用 OpenCV 读取选中的图片
|
||||
Mat image = imread(imagePath);
|
||||
// 使用 Windows API 打开文件
|
||||
HANDLE hFile = CreateFileW(imagePath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
wcout << L"Error: Could not open file." << endl;
|
||||
return Mat();
|
||||
}
|
||||
|
||||
// 获取文件大小
|
||||
LARGE_INTEGER fileSize;
|
||||
if (!GetFileSizeEx(hFile, &fileSize)) {
|
||||
wcout << L"Error: Could not get file size." << endl;
|
||||
CloseHandle(hFile);
|
||||
return Mat();
|
||||
}
|
||||
|
||||
if (fileSize.QuadPart > MAXDWORD) {
|
||||
wcout << L"Error: File size too large." << endl;
|
||||
CloseHandle(hFile);
|
||||
return Mat();
|
||||
}
|
||||
|
||||
DWORD dwFileSize = static_cast<DWORD>(fileSize.QuadPart);
|
||||
|
||||
// 读取文件内容到缓冲区
|
||||
std::vector<BYTE> buffer(dwFileSize);
|
||||
DWORD bytesRead = 0;
|
||||
if (!ReadFile(hFile, buffer.data(), dwFileSize, &bytesRead, NULL) || bytesRead != dwFileSize) {
|
||||
wcout << L"Error: Could not read file." << endl;
|
||||
CloseHandle(hFile);
|
||||
return Mat();
|
||||
}
|
||||
|
||||
CloseHandle(hFile);
|
||||
|
||||
// 使用 OpenCV 从内存缓冲区读取图像
|
||||
Mat image = imdecode(buffer, IMREAD_COLOR);
|
||||
|
||||
if (image.empty()) {
|
||||
cout << "Error: Could not load image." << endl;
|
||||
wcout << L"Error: Could not decode image." << endl;
|
||||
return Mat();
|
||||
}
|
||||
|
||||
@ -139,7 +174,7 @@ int main() {
|
||||
vibrantGreenDetection(inputImage, outputImage, params);
|
||||
|
||||
// 定义缩放因子,1.0 表示原始大小,>1.0 表示放大,<1.0 表示缩小
|
||||
double scaleFactor = 1.5; // 将图像放大1.5倍
|
||||
double scaleFactor = 0.6; // 将图像放大1.5倍
|
||||
|
||||
// 显示原图和检测到的绿色区域,使用缩放因子
|
||||
showImage("Original Image", inputImage, scaleFactor);
|
||||
|
||||
@ -142,7 +142,7 @@ int main() {
|
||||
|
||||
// 使用 map 模拟参数传递
|
||||
map<string, int> params;
|
||||
params["saturationThreshold"] = 100; // 设置饱和度阈值为 100
|
||||
params["saturationThreshold"] = 134; // 设置饱和度阈值为 100
|
||||
|
||||
// 调用鲜艳颜色检测函数
|
||||
vibrantColorDetection(inputImage, outputImage, params);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user