项目场景:
在进行视觉跟踪时直接算出两个坐标相对距离来操作硬件会导致硬件过载,抖动,使用体验差
例如:项目场景视觉跟踪
–
原因分析:
提示:这里填写问题的分析:
算出相对距离后直接操作硬件会使硬件以最大负荷运行,惯量大。因此引入直线插补算法来解决
解决方案:
构造一个适用于PYTHON的,已centerx,centery为0.0点 终点,center_pos_y center_pos_x为起点的四象限直线插补算法输出为步进数据,例如右下移动1像素为(1.1) 左上为(-1,-1) 注意这个问题slope = (centery - center_pos_y) / (centerx - center_pos_x)
ZeroDivisionError: float division by zero, 使用一个变量来记录插补点的数量,如果小于设定的阈值,则停止插补操作或给出提示信息,如果超过,则正常进行插补操作。
# 定义起点和终点的坐标
center_pos_x = float(input("请输入起点的x坐标:"))
center_pos_y = float(input("请输入起点的y坐标:"))
centerx = 0.0 # 终点的x坐标
centery = 0.0 # 终点的y坐标
# 计算直线的斜率和截距
# 注意这个问题slope = (centery - center_pos_y) / (centerx - center_pos_x)
# ZeroDivisionError: float division by zero
# 这是因为当终点和起点的x坐标相同时,除数为0,而这在数学上是不允许的
# 为了避免这个错误,我们可以先判断终点和起点的x坐标是否相同
# 如果相同,说明直线是垂直于x轴的,斜率不存在,截距等于任意一点的x坐标
# 如果不同,说明直线是斜的,可以正常计算斜率和截距
if centerx == center_pos_x:
slope = None # 斜率不存在
intercept = centerx # 截距等于任意一点的x坐标
else:
slope = (centery - center_pos_y) / (centerx - center_pos_x) # 正常计算斜率
intercept = centery - slope * centerx # 正常计算截距
# 判断直线所在的象限
if slope is None: # 如果斜率不存在,说明直线是垂直于x轴的
if intercept > 0: # 如果截距大于0,说明直线在第一象限和第四象限之间
quadrant = "第一象限和第四象限之间"
elif intercept < 0: # 如果截距小于0,说明直线在第二象限和第三象限之间
quadrant = "第二象限和第三象限之间"
else: # 如果截距等于0,说明直线就是y轴本身
quadrant = "y轴本身"
else: # 如果斜率存在,说明直线是斜的
if slope > 0 and intercept > 0:
quadrant = "第一象限"
elif slope < 0 and intercept > 0:
quadrant = "第二象限"
elif slope < 0 and intercept < 0:
quadrant = "第三象限"
elif slope > 0 and intercept < 0:
quadrant = "第四象限"
else:
quadrant = "无法确定"
# 输出直线的方程和象限
if slope is None: # 如果斜率不存在,说明直线是垂直于x轴的
print(f"直线的方程是:x = {intercept}")
else: # 如果斜率存在,说明直线是斜的
print(f"直线的方程是:y = {slope}x + {intercept}")
print(f"直线位于{quadrant}")
# 定义插补步长
dir=3#像素移动倍率
step = dir # 可以根据需要调整
# 根据起点和终点的坐标,生成插补点的坐标列表
if slope is None: # 如果斜率不存在,说明直线是垂直于x轴的
# 此时只需要根据起点和终点的y坐标生成插补点的y坐标列表即可
# x坐标都等于截距
if center_pos_y < centery:
y_list = [center_pos_y + i * step for i in range(int((centery - center_pos_y) / step) + 1)]
else:
y_list = [center_pos_y - i * step for i in range(int((center_pos_y - centery) / step) + 1)]
x_list = [intercept] * len(y_list) # x坐标都等于截距
else: # 如果斜率存在,说明直线是斜的
# 此时需要根据起点和终点的x坐标生成插补点的x坐标列表
# 然后根据插补点的x坐标计算对应的y坐标列表
if center_pos_x < centerx:
x_list = [center_pos_x + i * step for i in range(int((centerx - center_pos_x) / step) + 1)]
else:
x_list = [center_pos_x - i * step for i in range(int((center_pos_x - centerx) / step) + 1)]
y_list = [slope * x + intercept for x in x_list]
# 定义步进数据的格式
# 步进数据是一个二维列表,每一行表示一个插补点的坐标和方向
# 方向用(1,1)表示右下移动1像素,(-1,-1)表示左上移动1像素,(0,0)表示不变
step_data = []
# 定义一个变量来记录插补点的数量
count = 0
# 定义一个阈值,表示最少需要生成多少个插补点
min_count = 10 # 可以根据需要调整
# 遍历插补点的坐标列表,计算每个插补点的方向
for i in range(len(x_list)):
# 获取当前插补点的坐标
x = x_list[i]
y = y_list[i]
# 判断当前插补点的方向
# 如果是第一个插补点,方向都是(0,0)
if i == 0:
dir_x = 0
dir_y = 0
else:
# 如果是其他插补点,根据前一个插补点的坐标判断方向
prev_x = x_list[i - 1]
prev_y = y_list[i - 1]
# 如果当前x坐标大于前一个x坐标,方向是(1,0),否则是(-1,0)
if x > prev_x:
dir_x = dir
elif x < prev_x:
dir_x = -dir
else:
dir_x = 0
# 如果当前y坐标大于前一个y坐标,方向是(0,1),否则是(0,-1)
if y > prev_y:
dir_y = dir
elif y < prev_y:
dir_y = -dir
else:
dir_y = 0
# 将当前插补点的坐标和方向添加到步进数据中
step_data.append([x, y, (dir_x, dir_y)])
# 每生成一个插补点,数量加一
count += 1
# 如果插补点的数量达到或超过阈值,则停止插补操作或给出提示信息
if count >= min_count:
print("已达到最小插补点数量,无法继续插补")
break # 跳出循环
# 输出步进数据
print("步进数据如下:")
for data in step_data:
print(data)