前两篇说了底图还原跟w参数生成方式的流程分析 下面我们来实现一下滑动距离以及滑动轨迹的代码生成
直接上代码
这个是识别缺口距离 sliceimg.img是滑块图片 img是带缺口的背景图片
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2022/11/10 17:44
# @Author : Stone
# @File : 识别缺口距离.py
import io
from PIL import Image
import cv2
import numpy as np
# 将 Image 转换为 Mat,通过 flag 可以控制颜色
def pilImgToCv2(img: Image.Image, flag=cv2.COLOR_RGB2BGR):
return cv2.cvtColor(np.asarray(img), flag)
# 弹窗查看图片
def showImg(bg, name='test', delay=0):
cv2.imshow(name, bg)
cv2.waitKey(delay)
cv2.destroyAllWindows()
def getDistance(imgpath, sliceimgpath):
img=Image.open(imgpath)
slice=Image.open(sliceimgpath)
# 通过 pilImgToCv2 将图片置灰
# 背景图和滑块图都需要做相同处理
grayImg = pilImgToCv2(img, cv2.COLOR_BGR2GRAY)
# img.show(grayImg)
# showImg(grayImg) # 可以通过它来看处理后的图片效果
graySlice = pilImgToCv2(slice, cv2.COLOR_BGR2GRAY)
# 做边缘检测进一步降低干扰,阈值可以自行调整
grayImg = cv2.Canny(grayImg, 255, 255)
# showImg(grayImg) # 可以通过它来看处理后的图片效果
graySlice = cv2.Canny(graySlice, 255, 255)
# 通过模板匹配两张图片,找出缺口的位置
result = cv2.matchTemplate(grayImg, graySlice, cv2.TM_CCOEFF_NORMED)
maxLoc = cv2.minMaxLoc(result)[3]
# 匹配出来的滑动距离
distance = maxLoc[0]
# 下面的逻辑是在图片画出一个矩形框来标记匹配到的位置,可以直观的看到匹配结果,去掉也可以的
sliceHeight, sliceWidth = graySlice.shape[:2]
# 左上角
x, y = maxLoc
# 右下角
x2, y2 = x + sliceWidth, y + sliceHeight
resultBg = pilImgToCv2(img, cv2.COLOR_RGB2BGR)
cv2.rectangle(resultBg, (x, y), (x2, y2), (0, 0, 255), 2)
# showImg(resultBg) # 可以通过它来看处理后的图片效果
print(distance) # 可以通过它来看处理后的图片效果
return distance
if __name__ == '__main__':
sliceimgpath=r'sliceimg.jpg'
imgpath=r'img.jpg'
# cc=Image.open(imgpath)
# cc.show()
print(getDistance(Image.open(imgpath),Image.open(sliceimgpath)))
下面是输入滑动距离 生成的滑动轨迹
def get_slide_track(distance):
"""
根据滑动距离生成滑动轨迹
:param distance: 需要滑动的距离
:return: 滑动轨迹<type 'list'>: [[x,y,t], ...]
x: 已滑动的横向距离
y: 已滑动的纵向距离, 除起点外, 均为0
t: 滑动过程消耗的时间, 单位: 毫秒
"""
if not isinstance(distance, int) or distance < 0:
raise ValueError(f"distance类型必须是大于等于0的整数: distance: {distance}, type: {type(distance)}")
# 初始化轨迹列表
slide_track = [
[random.randint(-50, -10), random.randint(-50, -10), 0],
[0, 0, 0],
]
# 共记录count次滑块位置信息
count = 30 + int(distance / 2)
# 初始化滑动时间
t = random.randint(50, 100)
# 记录上一次滑动的距离
_x = 0
_y = 0
for i in range(count):
# 已滑动的横向距离
x = round(__ease_out_expo(i / count) * distance)
# 滑动过程消耗的时间
t += random.randint(10, 20)
if x == _x:
continue
slide_track.append([x, _y, t])
_x = x
slide_track.append(slide_track[-1])
return slide_track, slide_track[-1][2] # 大数组,滑动时间
def __ease_out_expo(sep):
if sep == 1:
return 1
else:
return 1 - pow(2, -10 * sep)
以上内容仅供学习使用 请勿做其他用途 如有侵权 请联系删除