不好用,识别速度慢,有时候识别不准确
#include <windows.h>
#include <stdio.h>
#include <math.h>
HDC hdcScreen;
void leftClick();
void RGBtoHSV(int r, int g, int b, int* h, int* s, int* v);
int fuzzyFindColor(int x1, int y1, int x2, int y2,int targetH, int targetS, int targetV,int hTol, int sTol, int vTol,int* outX, int* outY);
void leftClick() {// 模拟鼠标左键按下mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);// 短暂延迟,模拟真实点击的持续时间Sleep(50);// 模拟鼠标左键释放mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
}
// 1. RGB转HSV(纯C工具函数,0<=H<=360,0<=S,V<=100)
void RGBtoHSV(int r, int g, int b, int* h, int* s, int* v) {/*作用:将输入的 0-255 整数(硬件设备的绝对亮度值)转换为 0-1 的相对比例(消除绝对值影响,统一计算标准)。细节:除以 255.0f(浮点型)而非 255(整数),确保结果为浮点数(避免整数除法导致的截断)。*/float R = r / 255.0f, G = g / 255.0f, B = b / 255.0f;float max = (R > G ? (R > B ? R : B) : (G > B ? G : B));float min = (R < G ? (R < B ? R : B) : (G < B ? G : B));float delta = max - min;// 计算色相Hif (delta < 1e-6) *h = 0;else if (max == R) *h = (int)(60 * fmod(((G - B) / delta) + 6, 6));else if (max == G) *h = (int)(60 * (((B - R) / delta) + 2));else *h = (int)(60 * (((R - G) / delta) + 4));// 计算饱和度S*s = (max < 1e-6) ? 0 : (int)((delta / max) * 100);// 计算明度V*v = (int)(max * 100);
}// 2. 区域模糊找色(返回第一个匹配点坐标)
// 参数:x1,y1/x2,y2=查找区域;targetH/S/V=目标颜色;h/s/vTol=模糊阈值;outX/outY=输出坐标
int fuzzyFindColor(int x1, int y1, int x2, int y2,int targetH, int targetS, int targetV,int hTol, int sTol, int vTol,int* outX, int* outY) {// 校验区域合法性if (x1 > x2 || y1 > y2) return 0;// 获取屏幕设备上下文(DC)//hdcScreen = CreateDCA("DISPLAY", NULL, NULL, NULL);hdcScreen=GetDC(NULL);//2if (!hdcScreen) return 0;int h, s, v;COLORREF pixel; // 存储RGB颜色(0x00BBGGRR)int r, g, b;// 遍历区域内所有像素for (int y = y1; y <= y2; y++) {for (int x = x1; x <= x2; x++) {// 读取当前像素的RGB值pixel = GetPixel(hdcScreen, x, y);r = GetRValue(pixel); // 提取红色分量g = GetGValue(pixel); // 提取绿色分量b = GetBValue(pixel); // 提取蓝色分量// RGB转HSVRGBtoHSV(r, g, b, &h, &s, &v);// printf("RGB %d, %d,%d)\n", r, g, b);// printf("hsv %d, %d,%d)\n", h, s, v);// 模糊匹配:判断HSV是否在阈值范围内if ((h >= targetH - hTol && h <= targetH + hTol) &&(s >= targetS - sTol && s <= targetS + sTol) &&(v >= targetV - vTol && v <= targetV + vTol)) {*outX = x;*outY = y;//DeleteDC(hdcScreen); // 释放资源ReleaseDC(NULL, hdcScreen);//2leftClick();return 1; // 找到匹配点}}}//DeleteDC(hdcScreen); // 释放资源ReleaseDC(NULL, hdcScreen);//2return 0; // 未找到
}// 3. 测试主函数
int main() {while (1){int matchX, matchY;// 需求:在(100,100)-(800,600)区域找HSV(30,80,90),阈值H±3、S±8、V±15int found = fuzzyFindColor(537 , 533, 543, 538,180, 50, 8,179, 49, 7,&matchX, &matchY);if (found) {printf("--------------------------------------------------------------找到匹配点!坐标:(%d, %d)\n", matchX, matchY);Sleep(1000);}else {printf("未找到匹配颜色未找到匹配颜色未找到匹配颜色\n");}//system("pause"); // 暂停查看结果}return 0;
}