认知过程中的面孔识别加工(附代码源文件)
系列实验
脑与认知实验:认知科学实验设计
脑与认知实验:图像中的注意区域预测
代码源文件在底下哦! 请多多支持点个赞哈!!!
实验要求
请设计一个关于正常人脸/面孔与异常人脸/面孔的熟悉程度判断实验(比如倒着的人脸、模糊的人脸、惊恐的人脸等),叙述你所要测试的目标(比如是否对倒着的人脸的反应时间比正着的人脸长等)、你的实验设置、实验内容、与实验结果的展示。
熟悉程度判断举例:可以显示大家都认识的名人。也可以是陌生人,让被试先通过照片打乱顺序看几遍,再进入判断,判断该照片是否看过,并记录反应时间。
设计思路
实验的目标:
获取对非正常人脸识别的正确率、获得对正常人脸、非正常人脸、未展现人脸的时间反应比
实验设置:
为了统一人脸的一些人种影响,我全部选择了黄种人的面孔,包括男性与女性(比例为1:1),年龄段为青中年。并且为了防止背景的影响,照片的背景全部设置为了白色背景。为了使得实验的普遍性(防止受试者对某些人像特别熟悉),我所挑选的人脸均为陌生人脸。所有人脸的照片分为三个种类,分别为:展示过的照片(正常面孔)、非正常人脸(全从正常人脸中处理)、其他照片(未展示过的其他照片)。三种类型的的比例分别为1:1:1,其中展示的面孔有6张,也就是说总共有18张照片。其中非正常人脸又分为两种类别,分别为倒立与模糊。实验分成了两种类型进行,各进行了一组。实验的程序设计利用的是Python的PsychoPy。
实验内容:
实验开始时会出现一段指导语,告诉受试者实验流程。在指导语之后会放两遍正常人脸的照片,每张照片每次停留3s。展示完所有正常人脸后,再次显示另外一个指导语告知受试者接下来将看到一些人脸,而这些人脸可能刚才未出现过的,而且人脸还有做模糊处理。若人脸未出现过则按N,出现过则按Y。在所有照片都展示完后实验结束。
实验程序设计:
-
在编程程序一开始时设置了载入所有照片的函数、显示指导语的函数、播放照片的函数、照片打标签的函数。在后续的程序多次调用了这些函数。
-
程序开始后利用载入所有照片的函数把照片都以对象的显示存储进了字典与列表中。
-
然后调用显示指导语函数显示第一个指导语,如图1所示。
-
显示完指导语后将正常人脸打乱了顺序并调用播放函数进行播放三次,如图2所示。
-
播放完成后再次调用指导语函数显示第二个指导语,如图3所示。
-
然后调用打标签函数,将所有的照片都加入新列表打上标签并打乱顺序,进行播放与判断。如图4与图5所示。
-
最后实验所得到的数据全部写入了data/data.csv的文件内,并出现结束语,如图6所示。
下图图7为程序运行的流程图。
程序的目录结构如下图图8所示:
实验结果:
-
对于正常人脸与非正常人脸以及未展示过人脸的判断正确率均为100%。
-
对正常人脸的判断平均用时为1.53s;模糊人脸平均用时1.72s;倒立人脸平均用时2.12秒;未展示的人脸平均用时1.49s。如下图所示
实验总结:
- 本次实验在人脸类别上的设置是比较丰富的,然而非正常人脸却都是从正常人脸中得来,这容易使得受试者在试验后期会认为非正常人脸都是出现过的。而实验的数据却也似乎证明了这一点,受试者虽然在实验前期对于所有的人脸都反应较未迟钝,但是对于非正常人脸的反应是远远满于正常人脸的。
- 本次实验的试验次数过少使得实验结果可能没有一般性。
代码实现
载入所有图片的函数
#加载所有的图片文件
def loadallpic(win, normal, abnormal, other, suffix=".jpeg"): #加载所有的照片到win窗口
#dir存储文件的地址
dirs = [normal, abnormal, other]
allpic = {normal:[], abnormal:[], other:[]}
#用字典存储不同标签的照片对象
x,y = win.pos
width, height =win.size
for dir in dirs:
num = file_num(dir) #查找指定后缀名文件个数
for i 1 pic = visual.ImageStim(win, image=dir+str(i)+suffix, pos=(0, 0), size=(1, 2)) #调整图片大小
allpic[dir].append(pic)
return allpic
# 返回指定后缀文件个数
def file_num(dir,suffix='.jpeg'):
number = 0
for root, dirname, filenames in os.walk(dir):
for filename in filenames:
# os.path.splitext()是一个元组,类似于('188739', '.jpg'),索引1可以获得文件的扩展名
if os.path.splitext(filename)[1] == suffix:
number += 1
return number
显示指导语的函数
def introduction(win, text): #显示指导语
intro = visual.TextStim(win, height=0.1, pos=(0, 0), color='black', bold=True)
intro.text = text
intro.draw() #绘制文字
win.flip()
while 1:
key = event.waitKeys()
if key[0]:
break
播放照片函数
def play_pic(win, pic, duration=3, times=3):
#duration为持续时间
#times为播放次数
#pic为图片列表
for i in range(1, times+1):
for j in range(1, len(pic)+1):
pic[j-1].draw()
win.flip()
core.wait(duration)
if i <= times-1:
text = "第"+str(i)+"次播放完成"+"\n\n请按下任意键进入下一次播放!\n(剩余"+str(times-i)+"次)"
introduction(win, text)
将所有照片打上标签并打乱放入一个新列表中
def tag(allpic): #将所有的照片打上标签然后输入到一个列表中
tag_pic = []
for i in [normal,abnormal,other]:
for j in allpic[i]:
if i == normal:
pic = (j, 1)
elif i == abnormal:
pic = (j, 2)
elif i == other:
pic = (j, 3)
tag_pic.append(pic)
random.shuffle(tag_pic)
return tag_pic
正式实验
def experiment(win, tag_allpic):
tip = visual.TextStim(win, height=0.05, pos=(0, -0.8), color='black', bold=True)
tip.text = "此张人脸是否在展示中出现过?\n若出现则按y\n若未出现则按n"
record = core.Clock()
with open('./data/data.csv', 'a+') as f: # 打开数据文件读一条写一条
f.write("人脸类别,是否回答正确,反应时间\n")
for tag_pic in tag_allpic:
tag_pic[0].draw() # tag_pic是元组第一个元素才是图片第二个是标签
tip.draw()
#判别人脸类型
if tag_pic[1] == 1:
face_type = "normal"
elif tag_pic[1] == 2:
face_type = "abnormal"
elif tag_pic[1] == 3:
face_type = "other"
win.flip() # 显示图片
record.reset() #重置时间
while 1: # 检测按键
key = event.waitKeys(keyList=['y', 'n']) # 只允许按y或n
if key[0] == 'y':
r_time = record.getTime() #记录反应时间
if tag_pic[1] == 1 or tag_pic[1] == 2:
correct = 1 #若是出现过的则正确
else:
correct = 0
break
elif key[0] == 'n':
r_time = record.getTime() # 记录反应时间
if tag_pic[1] == 3:
correct = 1 #若是未现过的则正确
else:
correct = 0
break
f.write(str(face_type)+','+str(correct)+','+str(r_time)+'\n')
if correct == 1:
introduction(win,"回答正确!\n按任意键进入下一张!")
else:
introduction(win, "回答错误!\n按任意键进入下一张!")
源代码压缩包
https://download.csdn.net/download/weixin_51735061/85304249