最近朋友圈喜欢跳一跳,最多也就能蹦到三百多分,凭个人经验,估计python的图片分析能搞定他,于是前天晚上就搞了下,大概能跑1万多分的样子,可惜微信不承认“冏”。
废话不多说,可是说下思路和想法。我用的手机是三星S7 edge,1440 x 2560个像素,两边时间弯曲屏,会导致颜色变化。
A点是棋子的中心坐标位置,B点是下一个台阶的最顶点坐标位置,因为棋子的中心周围的RGB数值不变,可以遍历棋子颜色的坐标所有位置,所有的X,Y坐标的中心值,就是棋子的中心位置。
A点的计算比较容易,就是由上到下,有右到左进行遍历,一旦发现颜色的RGB值不是背景的RGB值,则认为跳跃点出现。
在我的手机上,棋子中心的RGB是(57,57,99),遍历区域内所有的RGB,并计算出中心点,代码如下
def _getflag(): #取棋子所在位置的函数
flag_RGB = 57,57,99 #棋子的RGB值
flag_x_sum = 0 #所有具有中心RGB的X坐标总和
flag_x_num = 0 #所有具有中心RGB的X坐标个数;两个数值的商即是中心RGB的X坐标,同理Y坐标
flag_y_sum = 0
flag_y_num = 0
for flag_y in range(jump_box_top, jump_box_buttom,5): #遍历整个跳跃位置
for flag_x in range(jump_box_left, jump_box_right,5):
flag_xy = flag_x,flag_y
flag_pixel = img_pixel.getpixel(flag_xy)
if (abs(flag_pixel[0] - flag_RGB[0]) <= 5) and (abs(flag_pixel[1] - flag_RGB[1]) <= 5) and (abs(flag_pixel[2] - flag_RGB[2]) <= 5): #这里取RGB的容差为5
flag_x_sum += flag_x
flag_x_num += 1
flag_y_sum += flag_y
flag_y_num += 1
flag_center_x = int(flag_x_sum/flag_x_num) - 6 #坐标有偏差,通过PHOTOPSHOP的测算是6个像素
flag_center_y = int(flag_y_sum/flag_y_num) - 6
return flag_center_x,flag_center_y
B点为跳跃点,分为两种情况,一种是在左侧,一种是在右侧,通过玩游戏可以知道,如果A点在屏幕中心的右侧,那么下一个跳跃点将在L区域,反之则在Y区域。
B的计算就是一个物体表面的中心,这个规则物体的表面可能是椭圆形,菱形等 ,计算起来也比较简单,通过观察我们可以的出来这个结论,就是物体的最高点通常跟物体中心的有着相同的X坐标,并且借此可以的出来X坐标位置,以及物体表面的RGB值。
def _getop():
print("get_top")
top_x_sum = 0
top_x_num = 0
for top_y in range(next_border_top, next_border_buttom,1):#这个边界可以通过棋子所在的位置计算出来
background_xy = jump_box_left,top_y
backfround_pixel = img_pixel.getpixel(background_xy) #去除掉背景色的影响,如果有一点的位置不同于背景色,并且连续出现,那么可以推断出改点为最高点,为什么要剔除不连续出现的情况,就是有的时候音乐盒的音乐符和+分计算符的影响。
for top_x in range(next_border_left, next_border_right,1):
top_xy = top_x,top_y
top_pixel = img_pixel.getpixel(top_xy)
if (abs(top_pixel[0] - backfround_pixel[0]) > 10) or (abs(top_pixel[1] - backfround_pixel[1]) > 10) or (abs(top_pixel[2] - backfround_pixel[2]) > 10) :
top_xy_check = top_x,top_y + 4
#得出最高点后要最一次核实,证明该点下方确实为连续的区域,而并非单个的颜色噪点
top_pixel_check = img_pixel.getpixel(top_xy_check)
if (abs(top_pixel_check[0] - backfround_pixel[0]) > 10) or (abs(top_pixel_check[1] - backfround_pixel[1]) > 10) or (abs(top_pixel_check[2] - backfround_pixel[2]) > 10) :
top_x_sum += top_x
top_x_num += 1
#print(top_pixel,backfround_pixel,top_pixel_check)
if(top_x_num != 0):
#确认该最高点不是音乐符和分数符
top_x = int(top_x_sum / top_x_num)
top_xy_check = (top_x,top_y + 4)
top_pixel_check = img_pixel.getpixel(top_xy_check)
check_xy_if_music = top_x, top_y + 15
check_bc_xy_if_music = jump_box_left, top_y + 15
check_pixel_if_music = img_pixel.getpixel(check_xy_if_music)
check_bc_pixel_if_music = img_pixel.getpixel(check_bc_xy_if_music)
if (abs(check_bc_pixel_if_music[0] - check_pixel_if_music[0]) > 10) or (abs(check_bc_pixel_if_music[1] - check_pixel_if_music[1]) > 10) or (abs(check_bc_pixel_if_music[2] - check_pixel_if_music[2]) > 10) :
return (top_x,top_y,top_pixel_check)
else:
top_x_sum = 0
top_x_num = 0
return (0,0,(0,0,0,255))
最边侧位置的计算,要却分L区域和R区域的情况,思路差不多,如在L区域时,就是计算表面颜色最左侧点出现的情况,注意这时候区别阴影位置。
def _getright():
#print("_getright")
for right_x in range(next_border_right, next_border_left,-3):
for right_y in range(next_border_top, next_border_buttom,3):
right_xy = right_x , right_y
background_xy = next_border_right,right_y
right_pixel = img_pixel.getpixel(right_xy)
backfround_pixel = img_pixel.getpixel(background_xy)
if (abs(right_pixel[0] - backfround_pixel[0]) > 10) or (abs(right_pixel[1] - backfround_pixel[1]) > 10) or (abs(right_pixel[2] - backfround_pixel[2]) > 10) :
right_xy_check = right_x - 4 , right_y
right_pixel_check = img_pixel.getpixel(right_xy_check)
if (abs(right_pixel_check[0] - backfround_pixel[0]) > 10) or (abs(right_pixel_check[1] - backfround_pixel[1]) > 10) or (abs(right_pixel_check[2] - backfround_pixel[2]) > 10) :
#print(background_xy,right_xy,backfround_pixel,right_pixel,right_pixel)
return (right_x,right_y,right_pixel_check)
return (0,0,(0,0,0,255))
http://download.csdn.net/download/youhetaotao/10240077
如果在自己手机上运行的话,要最几次微调,主要是代码里面的写死的像素要重新按照自己的手机像素重新设置下。