如何在视觉搜索任务中防止Distractor与Target重叠?
解决视觉搜索任务中刺激位置重叠的问题
核心思路是维护一个已使用位置的列表,每次生成新坐标时检查是否与已有位置过近,直到找到符合要求的位置。具体实现如下:
第一步:定义位置冲突判断函数
先写一个辅助函数,计算两个坐标的欧氏距离,判断是否小于设定的最小间距(这里用刺激大小0.1加上一点余量0.02,避免边缘接触):
import math def is_position_valid(new_pos, existing_positions, min_distance=0.12): for pos in existing_positions: distance = math.hypot(new_pos[0] - pos[0], new_pos[1] - pos[1]) if distance < min_distance: return False return True
第二步:修改干扰项与目标物生成逻辑
生成每个刺激前,循环生成坐标直到找到不冲突的位置,同时把有效的位置存入列表:
for trial in range(20): ClosedD_num = random.choice([1, 5, 9]) ClosedD_list = [] used_positions = [] # 存储已使用的有效位置 for _ in range(ClosedD_num): # 循环生成坐标直到找到无冲突的位置 while True: x_pos = random.uniform(-0.5, 0.5) y_pos = random.uniform(-0.5, 0.5) new_pos = (x_pos, y_pos) if is_position_valid(new_pos, used_positions): used_positions.append(new_pos) break ClosedD = visual.ImageStim( win=window, name='ClosedD', image='images/closed_d.png', mask=None, anchor='center', ori=randint(1, 360), pos=new_pos, size=(0.1, 0.1), color=[1, 1, 1], colorSpace='rgb', opacity=None, flipHoriz=False, flipVert=False, texRes=128.0, interpolate=True, depth=-3.0) ClosedD_list.append(ClosedD) ClosedD.setAutoDraw(True) # 移出内层循环,避免重复设置 # 处理目标物生成逻辑 ClosedT_present = random.choice([0, 1]) ClosedT = None if ClosedT_present == 1: # 生成不与干扰项冲突的目标物位置 while True: r_pos = random.uniform(-0.5, 0.5) s_pos = random.uniform(-0.5, 0.5) target_pos = (r_pos, s_pos) if is_position_valid(target_pos, used_positions): break ClosedT = visual.ImageStim( win=window, name='ClosedT', image='images/closed_t.png', mask=None, anchor='center', ori=randint(1, 360), pos=target_pos, size=(0.1, 0.1), color=[1, 1, 1], colorSpace='rgb', opacity=None, flipHoriz=False, flipVert=False, texRes=128.0, interpolate=True, depth=-3.0) ClosedT.setAutoDraw(True) else: ClosedT = visual.ImageStim( win=window, name='ClosedT', image='images/closed_t.png', mask=None, anchor='center', ori=randint(1, 360), pos=(0,0), size=(0.1, 0.1), color=[1, 1, 1], colorSpace='rgb', opacity=None, flipHoriz=False, flipVert=False, texRes=128.0, interpolate=True, depth=-3.0) ClosedT.setAutoDraw(False) window.flip() # 每次试次结束后清理刺激,避免残留 for stim in ClosedD_list: stim.setAutoDraw(False) if ClosedT: ClosedT.setAutoDraw(False)
关键修改说明
- 新增
used_positions列表记录所有已使用的有效位置,确保新坐标不会与已有位置过近 - 用
while True循环强制生成符合要求的坐标,直到找到有效位置 - 调整
ClosedD.setAutoDraw(True)的位置,避免重复执行无效操作 - 目标物仅在需要出现时才生成有效位置,减少无用计算
- 增加试次结束后的刺激清理步骤,防止上一次的刺激留在窗口中
你可以根据实际需求调整min_distance的值,若需要更大的刺激间距,直接修改该参数即可。
内容的提问来源于stack exchange,提问作者Markovka
相关产品推荐
相关产品推荐

