游戏验证码之“从五个怪中找出最壮实的那个”
发布时间:2024-04-19 05:29 浏览量:7
前言
这篇文章来自于学员群的问题,有一个游戏的验证是从五个相同样子的怪中找出最壮实的那个,具体样子看下图:
如果是手动验证很容易知道第3只怪是最壮实的,那么怎么让脚本也能知道呢?
以下是我关于这个脚本的思考过程,未必是最好的思路,仅供参考:
①、最壮实的怪有什么特点?
这个怪最大,占据的像素(数量)面积最大。
②、怎么知道每个怪的面积?
把怪和背景分离开得二值化,获取怪的像素数,不过这个问题我好像解决不了,原因是怪与怪之间有重叠的部分。
③、怪的整体面积不好算出来,可以不可以算局部面积?
我们其实并不是真的需要知道每个怪的面积大小,我们最终目的是找到最大的怪,如果相同局部对比,局部最大的那个怪就是最大的怪,比如都比较头部,头最大的怪就是整体最大的怪。
④、找哪个局部最为合理呢?
我最初的想方法是找高光,也就是最亮的那个像素点。
使用RGB阈值做了二值化,最亮的那个像素点是最大的怪脚的高光部分。
于是我思考为啥最大的怪高光是最亮的像素点呢?
因为图像在缩小后,高光点会变暗。
依据这个特性是不是找到最亮的像素点就找到最大的怪了???
按照这个思路写了如下代码:
Dim t = TickCount验证图(155,116,681,330) TracePrint "用时:",TickCount-tFunction 验证图(x1, y1, x2, y2)Dim GetColorDim arr = {0,0,0}KeepCapture For j = y1 To y2For i = x1 To x2GetColor = GetPixelColor(i,j)Dim record = ColorDiff(GetColor, "000000")If record > arr[1] Then arr[1] = recordarr[2] = iarr[3] = jEnd IfNextNextReleaseCapture TracePrint encode.TableToJson(arr)Dim n = (x2-x1)/5For i = 0 To 4 If x1 + n * i输出结果:
原本我以为到这里就可以结束了,但是测试其他图发现这个思路有问题了。
上面我说到图像在缩小后,高光点会变暗,但是图像在放大后,高光点也可能会变暗。这就难办了,如果最大的怪是放大图片得到的,那根据高光点判断就会出错了。
⑤、根据高光点判断不行,那么就根据高光面,大怪的高光面理论上是比小怪的高光面要大的。
找到高光点后,把它做个扩展,让高光的颜色值范围变大一些,然后看高光面哪个面积大,哪个就是最大的怪。
Dim t = TickCount验证图 178,117,686,347TracePrint "用时:",TickCount-tFunction 验证图(x1, y1, x2, y2)Dim GetColorDim arr = {0,0,0}KeepCapture For j = y1 To y2For i = x1 To x2GetColor = GetPixelColor(i,j)Dim record = ColorDiff(GetColor, "000000")If record > arr[1] Then arr[1] = recordarr[2] = iarr[3] = jEnd IfNextNextReleaseCapture TracePrint encode.TableToJson(arr)Dim arr_num = {0,0}Dim n = (x2-x1)/5For i = 0 To 4// TracePrint "范围:",x1+n*i,y1,x1+n*(i+1),y2// TracePrint "范围"&i+1&"数量:",GetColorNum(x1+n*i,y1,x1+n*(i+1),y2,GetPixelColor(arr[2],arr[3]),0.96)Dim num = GetColorNum(x1+n*i,y1,x1+n*(i+1),y2,GetPixelColor(arr[2],arr[3]),0.9)TracePrint i+1,numIf num > arr_num[1] Then arr_num[1] = numarr_num[2] = i+1End IfNextTracePrint "最壮实的怪:",arr_num[2]End Function原本我以为写到这里就可以了,后来又遇到问题了,如果高光点在重叠地方,就会出错。
看上图,最大的怪是第4个怪,但是高光点在武器上,这个武器高光正好在第3个怪上,脚本就会以为这个高光是第3个怪的,最终以为最大的怪是第三个怪。
⑥、不能以高光面作为判断区域,必须放大判断区域,我想的方式是用亮面。
Dim t = TickCount验证图1 178,117,686,347TracePrint "用时:",TickCount-tFunction 验证图1(x1, y1, x2, y2)Dim GetColorDim arr = {0,0,0}KeepCapture For j = y1 To y2For i = x1 To x2GetColor = GetPixelColor(i,j)Dim record = ColorDiff(GetColor, "000000")If record > arr[1] Then arr[1] = recordarr[2] = iarr[3] = jEnd IfNextNextReleaseCapture TracePrint encode.TableToJson(arr)Dim arr_num = {0,0}Dim n = (x2-x1)/5For i = 0 To 4// TracePrint "范围:",x1+n*i,y1,x1+n*(i+1),y2// TracePrint "范围"&i+1&"数量:",GetColorNum(x1+n*i,y1,x1+n*(i+1),y2,GetPixelColor(arr[2],arr[3]),0.96)Dim num = GetColorNum(x1+n*i,y1,x1+n*(i+1),y2,GetPixelColor(arr[2],arr[3]),0.6)TracePrint i+1,numIf num > arr_num[1] Then arr_num[1] = numarr_num[2] = i+1End IfNextTracePrint "最壮实的怪:",arr_num[2]End Function这次代码和上面的代码只改动了一个数字,就是相似度从0.9改成了0.6,可以理解为和高光点90%相似的所有像素点组合是高光面,和高光点60%相似的所有像素点组合是亮面,通过扩大区域增加了识别的准确度。
⑦、写到这里突然我发现,我干嘛要通过高光点找亮面呢,这不是脱裤子放屁吗?直接找亮面不好吗?
亮面,阈值大于128就可以认为是亮面的颜色值。
Dim t = TickCount验证图 178,117,686,347TracePrint "用时:",TickCount-tFunction 验证图(x1, y1, x2, y2)Dim GetColor,numDim arr_num = {0,0}Dim n = (x2-x1)/5KeepCaptureFor i = 0 To 4num = 0For j = y1 To y2For r = x1+n*i To x1+n*(i+1)GetColor = GetPixelColor(r, j)If ColorDiff(GetColor, "000000") > 384 Then num = num + 1End IfNextNextIf num > arr_num[1] Then arr_num[1] = numarr_num[2] = i+1End IfNextTracePrint "最壮实的怪:",arr_num[2]ReleaseCaptureEnd Function优化完以后,速度提升一倍,识别用时从1秒变成0.5秒。
- 上一篇:完美诠释人帅穿啥都是帅的
- 下一篇:男人,有多爱你,睡觉前做的三件事能看清