mirror of
https://github.com/Karllzy/cotton_color.git
synced 2025-11-08 18:53:53 +00:00
迁移项目到CLion
This commit is contained in:
parent
1eea87feae
commit
6cc26faeab
4
.gitignore
vendored
4
.gitignore
vendored
@ -360,4 +360,6 @@ MigrationBackup/
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
FodyWeavers.xsd
|
||||
|
||||
.idea
|
||||
26
CMakeLists.txt
Normal file
26
CMakeLists.txt
Normal file
@ -0,0 +1,26 @@
|
||||
cmake_minimum_required(VERSION 3.29)
|
||||
project(cotton_color)
|
||||
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
# 设置 OpenCV 路径
|
||||
set(OpenCV_DIR "E:/opencv4.10/opencv/build")
|
||||
|
||||
# 找到 OpenCV 包
|
||||
find_package(OpenCV REQUIRED)
|
||||
|
||||
add_definitions(-DUNICODE -D_UNICODE)
|
||||
# 包含头文件路径
|
||||
include_directories(${OpenCV_INCLUDE_DIRS})
|
||||
|
||||
# 添加可执行文件
|
||||
add_executable(cotton_color cotton_color.cpp)
|
||||
# 链接 OpenCV 库
|
||||
target_link_libraries(cotton_color ${OpenCV_LIBS} comdlg32)
|
||||
|
||||
|
||||
# 添加可执行文件
|
||||
add_executable(cotton_color2 cotton_color2.cpp)
|
||||
# 链接 OpenCV 库
|
||||
target_link_libraries(cotton_color2 ${OpenCV_LIBS} comdlg32)
|
||||
13
README.md
13
README.md
@ -49,5 +49,14 @@ L a* b* 色彩空间检测,检测明黄色、白色。
|
||||
激进方案 -> 深度学习 - > 区块判别 -> 杂质 |
|
||||
|
|
||||
保守方案 -> 深度学习确认 -> 杂质
|
||||
|
||||
|
||||
|
||||
讨论记录:
|
||||
|
||||
暗红色(棉叶)
|
||||
|
||||
棉花亮度低
|
||||
|
||||
黑线、黑色孔洞
|
||||
|
||||
土黄
|
||||
|
||||
|
||||
146
cotton_color.cpp
146
cotton_color.cpp
@ -1,135 +1,157 @@
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
#include <commdlg.h> // 包含文件对话框相关的函数
|
||||
|
||||
#include <commdlg.h> // 包含文件对话框相关的函数
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
|
||||
/**
|
||||
* @brief 鲜艳色彩检测函数,通过饱和度阈值检测输入图像中鲜艳的颜色区域。
|
||||
* @brief 鲜艳色彩检测函数,通过饱和度阈值检测输入图像中鲜艳的颜色区域。
|
||||
*
|
||||
* 此函数将输入图像从 BGR 色彩空间转换到 HSV 色彩空间,并提取出饱和度 (S) 通道。然后,通过设置饱和度阈值,
|
||||
* 来检测图像中饱和度大于阈值的区域,标记为输出图像的鲜艳颜色区域。
|
||||
*
|
||||
* @param inputImage 输入图像,类型为 cv::Mat,要求为 BGR 色彩空间。
|
||||
* @param outputImage 输出图像,类型为 cv::Mat,输出图像将标记出鲜艳颜色区域,原始图像尺寸。
|
||||
* @param saturationThreshold 饱和度阈值,类型为 int,用于过滤低饱和度的区域,范围通常为 0 到 255。
|
||||
* 饱和度高于此阈值的区域将被认为是鲜艳的颜色。
|
||||
*
|
||||
* @note 饱和度阈值越高,输出图像将只保留更为鲜艳的区域。
|
||||
* 若饱和度阈值过低,可能会检测到过多的区域。
|
||||
* @param inputImage 输入图像,类型为 cv::Mat,要求为 BGR 色彩空间。
|
||||
* @param outputImage 输出图像,类型为 cv::Mat,输出图像将标记出鲜艳颜色区域,原始图像尺寸。
|
||||
* @param params 参数映射,用于传递各种可配置的参数,如饱和度阈值等。
|
||||
*/
|
||||
/**
|
||||
* @brief 鲜艳色彩检测函数,通过饱和度阈值检测输入图像中鲜艳的颜色区域。
|
||||
*
|
||||
* @param inputImage 输入图像,类型为 cv::Mat,要求为 BGR 色彩空间。
|
||||
* @param outputImage 输出图像,类型为 cv::Mat,输出图像将标记出鲜艳颜色区域,原始图像尺寸。
|
||||
* @param params 参数映射,用于传递各种可配置的参数,如饱和度阈值等。
|
||||
*/
|
||||
void vibrantColorDetection(const Mat& inputImage, Mat& outputImage, const map<string, int>& params) {
|
||||
// 从参数映射中获取饱和度阈值
|
||||
// 从参数映射中获取饱和度阈值
|
||||
int saturationThreshold = params.at("saturationThreshold");
|
||||
|
||||
// 将输入图像从 BGR 转换为 HSV
|
||||
// 将输入图像从 BGR 转换为 HSV
|
||||
Mat hsvImage;
|
||||
cvtColor(inputImage, hsvImage, COLOR_BGR2HSV);
|
||||
|
||||
// 分离 HSV 图像的各个通道
|
||||
// 分离 HSV 图像的各个通道
|
||||
Mat channels[3];
|
||||
split(hsvImage, channels);
|
||||
|
||||
// 获取饱和度通道 (S)
|
||||
// 获取饱和度通道 (S)
|
||||
Mat saturation = channels[1];
|
||||
|
||||
// 创建输出图像,将饱和度大于阈值的区域标记为杂质
|
||||
// 创建输出图像,将饱和度大于阈值的区域标记为杂质
|
||||
outputImage = Mat::zeros(inputImage.size(), CV_8UC1);
|
||||
|
||||
// 对饱和度图像应用阈值处理
|
||||
// 对饱和度图像应用阈值处理
|
||||
threshold(saturation, outputImage, saturationThreshold, 255, THRESH_BINARY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 打开文件对话框,返回选中文件的路径。
|
||||
*
|
||||
* @return 选中文件的完整路径,类型为 std::wstring。如果用户取消选择,返回空字符串。
|
||||
*/
|
||||
std::wstring openFileDialog() {
|
||||
// 初始化文件选择对话框
|
||||
OPENFILENAMEW ofn; // 使用宽字符版本的结构
|
||||
wchar_t szFile[260] = {0}; // 存储选择的文件路径
|
||||
|
||||
string openFileDialog() {
|
||||
// 初始化文件选择对话框
|
||||
OPENFILENAME ofn; // 文件对话框结构
|
||||
wchar_t szFile[260]; // 存储选择的文件路径
|
||||
|
||||
// 设置 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();
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
// 读取输入图像
|
||||
Mat inputImage = readImage();
|
||||
// 读取输入图像
|
||||
Mat inputImage = readImage();
|
||||
|
||||
if (inputImage.empty()) {
|
||||
cout << "Error: Could not load image." << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 创建输出图像
|
||||
// 创建输出图像
|
||||
Mat outputImage;
|
||||
|
||||
// 使用 map 模拟 JSON 参数传递
|
||||
// 使用 map 模拟参数传递
|
||||
map<string, int> params;
|
||||
params["saturationThreshold"] = 100; // 设置饱和度阈值为100
|
||||
params["saturationThreshold"] = 100; // 设置饱和度阈值为 100
|
||||
|
||||
// 调用鲜艳颜色检测函数
|
||||
// 调用鲜艳颜色检测函数
|
||||
vibrantColorDetection(inputImage, outputImage, params);
|
||||
|
||||
// 显示原图和检测到的鲜艳区域
|
||||
// 显示原图和检测到的鲜艳区域
|
||||
imshow("Original Image", inputImage);
|
||||
imshow("Detected Vibrant Colors", outputImage);
|
||||
|
||||
// 等待用户按键
|
||||
// 等待用户按键
|
||||
waitKey(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,10 +104,13 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(mil_path64)\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(mil_path64)\..\lib\</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>mil.lib;Mil3d.lib;milim.lib;miledge.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
@ -118,14 +121,14 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>C:\Users\ZLSDKJ\source\opencv\build\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>C:\Users\zjc\source\opencv\build\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>C:\Users\ZLSDKJ\source\opencv\build\x64\vc16\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>C:\Users\zjc\source\opencv\build\x64\vc16\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>Comdlg32.lib;opencv_world4100.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
157
cotton_color2.cpp
Normal file
157
cotton_color2.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
#include <commdlg.h> // 包含文件对话框相关的函数
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* @brief 鲜艳色彩检测函数,通过饱和度阈值检测输入图像中鲜艳的颜色区域。
|
||||
*
|
||||
* @param inputImage 输入图像,类型为 cv::Mat,要求为 BGR 色彩空间。
|
||||
* @param outputImage 输出图像,类型为 cv::Mat,输出图像将标记出鲜艳颜色区域,原始图像尺寸。
|
||||
* @param params 参数映射,用于传递各种可配置的参数,如饱和度阈值等。
|
||||
*/
|
||||
void vibrantColorDetection(const Mat& inputImage, Mat& outputImage, const map<string, int>& params) {
|
||||
// 从参数映射中获取饱和度阈值
|
||||
int saturationThreshold = params.at("saturationThreshold");
|
||||
|
||||
// 将输入图像从 BGR 转换为 HSV
|
||||
Mat hsvImage;
|
||||
cvtColor(inputImage, hsvImage, COLOR_BGR2HSV);
|
||||
|
||||
// 分离 HSV 图像的各个通道
|
||||
Mat channels[3];
|
||||
split(hsvImage, channels);
|
||||
|
||||
// 获取饱和度通道 (S)
|
||||
Mat saturation = channels[1];
|
||||
|
||||
// 创建输出图像,将饱和度大于阈值的区域标记为杂质
|
||||
outputImage = Mat::zeros(inputImage.size(), CV_8UC1);
|
||||
|
||||
// 对饱和度图像应用阈值处理
|
||||
threshold(saturation, outputImage, saturationThreshold, 255, THRESH_BINARY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 打开文件对话框,返回选中文件的路径。
|
||||
*
|
||||
* @return 选中文件的完整路径,类型为 std::wstring。如果用户取消选择,返回空字符串。
|
||||
*/
|
||||
std::wstring openFileDialog() {
|
||||
// 初始化文件选择对话框
|
||||
OPENFILENAMEW ofn; // 使用宽字符版本的结构
|
||||
wchar_t szFile[260] = {0}; // 存储选择的文件路径
|
||||
|
||||
// 设置 OPENFILENAMEW 结构的默认值
|
||||
ZeroMemory(&ofn, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = NULL;
|
||||
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.nMaxFileTitle = 0;
|
||||
ofn.lpstrInitialDir = NULL; // 使用默认初始目录
|
||||
ofn.lpstrTitle = L"Select an image file"; // 对话框标题
|
||||
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
|
||||
|
||||
// 打开文件选择对话框
|
||||
if (GetOpenFileNameW(&ofn) == TRUE) {
|
||||
return szFile; // 返回选中的文件路径
|
||||
}
|
||||
|
||||
return L""; // 如果用户取消,返回空字符串
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 读取图像文件,支持 Unicode 路径。
|
||||
*
|
||||
* @return 加载的图像,类型为 cv::Mat。如果加载失败,返回空的 Mat。
|
||||
*/
|
||||
Mat readImage() {
|
||||
// 读取输入图像路径
|
||||
std::wstring imagePath = openFileDialog();
|
||||
|
||||
if (imagePath.empty()) {
|
||||
wcout << L"No file selected or user cancelled." << endl;
|
||||
return Mat();
|
||||
}
|
||||
|
||||
// 使用 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()) {
|
||||
wcout << L"Error: Could not decode image." << endl;
|
||||
return Mat();
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
int main() {
|
||||
// 读取输入图像
|
||||
Mat inputImage = readImage();
|
||||
|
||||
if (inputImage.empty()) {
|
||||
cout << "Error: Could not load image." << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 创建输出图像
|
||||
Mat outputImage;
|
||||
|
||||
// 使用 map 模拟参数传递
|
||||
map<string, int> params;
|
||||
params["saturationThreshold"] = 100; // 设置饱和度阈值为 100
|
||||
|
||||
// 调用鲜艳颜色检测函数
|
||||
vibrantColorDetection(inputImage, outputImage, params);
|
||||
|
||||
// 显示原图和检测到的鲜艳区域
|
||||
imshow("Original Image", inputImage);
|
||||
imshow("Detected Vibrant Colors", outputImage);
|
||||
|
||||
// 等待用户按键
|
||||
waitKey(0);
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user