AutoIt中如何定位色值轻微变化的移动绿色区域位置?
AutoIt识别色值浮动的绿色移动区域解决方案
若你之前使用
PixelSearch未配置色差容忍度,可先尝试调整PixelSearch的最后一个参数(色偏阈值),示例:PixelSearch($iBarLeft, $iBarTop, $iBarRight, $iBarBottom, 0x30D030, 40),其中第6个参数40就是允许的RGB色偏范围,色值浮动不大的场景下可直接满足需求。
如果上述方案不适用,可通过色彩特征匹配的方式实现识别,核心逻辑是利用绿色的通道属性替代固定色值匹配,适配色值轻微波动的场景。
实现步骤
- 预定位水平条坐标范围
因为绿色区域仅在水平条内移动,你可以提前通过AutoIt窗口信息工具拿到水平条的固定坐标边界:$iBarLeft(左边界)、$iBarTop(上边界)、$iBarRight(右边界)、$iBarBottom(下边界),缩小扫描范围提升效率。 - 自定义绿色判断规则
不需要固定色值,通过RGB通道占比判断即可,差值阈值可根据实际色差调整:
Func IsGreen($iR, $iG, $iB) ; 可根据实际色值浮动范围调整阈值30,G值高于R、B的差值越大判断越严格 If $iG - $iR > 30 And $iG - $iB > 30 And $iG > 80 Then Return True EndIf Return False EndFunc
- 扫描区域并定位连续绿色块
为了提升扫描效率,推荐用GDI+批量读取像素,示例完整代码如下:
#include <GDIPlus.au3> #include <WinAPI.au3> ; 替换为你实际测量的水平条坐标范围 Local $iBarLeft = 100, $iBarTop = 200, $iBarRight = 800, $iBarBottom = 230 Local $aGreenPoints = [] ; 初始化GDI+ _GDIPlus_Startup() Local $hScreenDC = _WinAPI_GetDC(0) Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP(_WinAPI_CreateCompatibleBitmap($hScreenDC, $iBarRight - $iBarLeft, $iBarBottom - $iBarTop)) Local $hMemDC = _WinAPI_CreateCompatibleDC($hScreenDC) _WinAPI_SelectObject($hMemDC, $hBitmap) _WinAPI_BitBlt($hMemDC, 0, 0, $iBarRight - $iBarLeft, $iBarBottom - $iBarTop, $hScreenDC, $iBarLeft, $iBarTop, $SRCCOPY) ; 遍历水平条区域筛选绿色像素 For $x = 0 To $iBarRight - $iBarLeft - 1 ; 水平条高度很小,y轴遍历量极低,也可以直接取水平条垂直中点扫描进一步提速 For $y = 0 To $iBarBottom - $iBarTop - 1 Local $iPixel = _GDIPlus_BitmapGetPixel($hBitmap, $x, $y) Local $iR = BitAND(BitShift($iPixel, 16), 0xFF) Local $iG = BitAND(BitShift($iPixel, 8), 0xFF) Local $iB = BitAND($iPixel, 0xFF) If IsGreen($iR, $iG, $iB) Then ReDim $aGreenPoints[UBound($aGreenPoints)+1][2] $aGreenPoints[UBound($aGreenPoints)-1][0] = $iBarLeft + $x $aGreenPoints[UBound($aGreenPoints)-1][1] = $iBarTop + $y EndIf Next Next ; 释放资源 _WinAPI_DeleteDC($hMemDC) _GDIPlus_BitmapDispose($hBitmap) _WinAPI_ReleaseDC(0, $hScreenDC) _GDIPlus_Shutdown() ; 计算绿色区域中心坐标 If UBound($aGreenPoints) > 0 Then Local $iSumX = 0, $iSumY = 0 For $i = 0 To UBound($aGreenPoints) -1 $iSumX += $aGreenPoints[$i][0] $iSumY += $aGreenPoints[$i][1] Next Local $iCenterX = Int($iSumX / UBound($aGreenPoints)) Local $iCenterY = Int($iSumY / UBound($aGreenPoints)) ConsoleWrite("绿色区域中心坐标:" & $iCenterX & "," & $iCenterY & @CRLF) Else ConsoleWrite("未找到绿色区域" & @CRLF) EndIf
- 优化提示:如果对扫描速度要求更高,可以调整x轴遍历步长,比如每2个像素扫描一次,不会影响常规尺寸绿色区域的定位精度。
内容的提问来源于stack exchange,提问作者user84201
相关产品推荐
相关产品推荐

