Very new to PsychoPy. I’m trying to export every frame within my looped routine as an image (preferably jpeg) so that I can upload the task to Mturq. I tried entering code into the “each frame” tab on the code component in builder, but it doesn’t seem to be working. Any idea what the best/simplest line of code to use for this would be? Do I need to add anything else?
I entered win.getMovieFrame() into the “every frame” tab and win.saveMovieFrames(fileName=‘jpgs/stimuli.jpg’) into the “end routine” tab.
Unfortunately, this made the task run weirdly (timing off, some frames missing) and saved ~80 jpgs instead of 5 (I only have 5 conditions). I was hoping it would save one image for every condition. Any idea what I’m doing wrong?
For reference, here is the code that builder spits out:
-------Run Routine “Slide1”-------
while continueRoutine and routineTimer.getTime() > 0:
# get current time
t = Slide1Clock.getTime()
tThisFlip = win.getFutureFlipTime(clock=Slide1Clock)
tThisFlipGlobal = win.getFutureFlipTime(clock=None)
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame
# *polygon_2* updates
if polygon_2.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
# keep track of start time/frame for later
polygon_2.frameNStart = frameN # exact frame index
polygon_2.tStart = t # local t and not account for scr refresh
polygon_2.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(polygon_2, 'tStartRefresh') # time at next scr refresh
polygon_2.setAutoDraw(True)
if polygon_2.status == STARTED:
# is it time to stop? (based on global clock, using actual start)
if tThisFlipGlobal > polygon_2.tStartRefresh + 8-frameTolerance:
# keep track of stop time/frame for later
polygon_2.tStop = t # not accounting for scr refresh
polygon_2.frameNStop = frameN # exact frame index
win.timeOnFlip(polygon_2, 'tStopRefresh') # time at next scr refresh
polygon_2.setAutoDraw(False)
# *image* updates
if image.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
# keep track of start time/frame for later
image.frameNStart = frameN # exact frame index
image.tStart = t # local t and not account for scr refresh
image.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(image, 'tStartRefresh') # time at next scr refresh
image.setAutoDraw(True)
if image.status == STARTED:
# is it time to stop? (based on global clock, using actual start)
if tThisFlipGlobal > image.tStartRefresh + 8-frameTolerance:
# keep track of stop time/frame for later
image.tStop = t # not accounting for scr refresh
image.frameNStop = frameN # exact frame index
win.timeOnFlip(image, 'tStopRefresh') # time at next scr refresh
image.setAutoDraw(False)
# *image_2* updates
if image_2.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
# keep track of start time/frame for later
image_2.frameNStart = frameN # exact frame index
image_2.tStart = t # local t and not account for scr refresh
image_2.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(image_2, 'tStartRefresh') # time at next scr refresh
image_2.setAutoDraw(True)
if image_2.status == STARTED:
# is it time to stop? (based on global clock, using actual start)
if tThisFlipGlobal > image_2.tStartRefresh + 8-frameTolerance:
# keep track of stop time/frame for later
image_2.tStop = t # not accounting for scr refresh
image_2.frameNStop = frameN # exact frame index
win.timeOnFlip(image_2, 'tStopRefresh') # time at next scr refresh
image_2.setAutoDraw(False)
# *Text2* updates
if Text2.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
# keep track of start time/frame for later
Text2.frameNStart = frameN # exact frame index
Text2.tStart = t # local t and not account for scr refresh
Text2.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(Text2, 'tStartRefresh') # time at next scr refresh
Text2.setAutoDraw(True)
if Text2.status == STARTED:
# is it time to stop? (based on global clock, using actual start)
if tThisFlipGlobal > Text2.tStartRefresh + 8-frameTolerance:
# keep track of stop time/frame for later
Text2.tStop = t # not accounting for scr refresh
Text2.frameNStop = frameN # exact frame index
win.timeOnFlip(Text2, 'tStopRefresh') # time at next scr refresh
Text2.setAutoDraw(False)
win.getMovieFrame()'''
-------Ending Routine “Slide1”-------
for thisComponent in Slide1Components:
if hasattr(thisComponent, "setAutoDraw"):
thisComponent.setAutoDraw(False)
trials_2.addData('polygon_2.started', polygon_2.tStartRefresh)
trials_2.addData('polygon_2.stopped', polygon_2.tStopRefresh)
trials_2.addData('image.started', image.tStartRefresh)
trials_2.addData('image.stopped', image.tStopRefresh)
trials_2.addData('image_2.started', image_2.tStartRefresh)
trials_2.addData('image_2.stopped', image_2.tStopRefresh)
trials_2.addData('Text2.started', Text2.tStartRefresh)
trials_2.addData('Text2.stopped', Text2.tStopRefresh)
win.saveMovieFrames(fileName='jpgs/stimuli.jpg')
thisExp.nextEntry()
This is why it is important to be very precise about descriptions of what you want to achieve on online forums like this: answers will be be in response to what you write, not what you wish for
But if what you want is just one frame per routine, rather than every frame, just put in a check so that the frame grabbing only happens on, say, the first frame:
# check the frame counter:
if frameN == 0:
# so that this only happens once per routine:
win.getMovieFrame()
I was actually hoping to get an image for every condition, not every routine. I have 5 conditions looped in one routine. If I set FrameN == 0, I just get one image from my routine. Is there a way to capture one image for every condition?
Just try it and see. The frame counter resets every time the routine runs. I was assuming that the condition changes on each iteration of the loop (and that seems to be the case). So with the code above, the number of screenshots you get won’t be equal to 1, but rather equal to the number of iterations in the trials loop (which looks like it would be 5).
I’m also rather new to PsychoPy, and I’m facing the same problem. My experiment look quite similar to the one mentioned in this thread, therefore I tried inserting (I’m using the Builder) the code you suggested (win.getMovieFrame() in Each Frame Tab; win.saveMovieFrames() in End Routine Tab), but I can’t get all the screenshots the loop produces (5), just the first.
I’m using PsychoPy 3.2.4, on Windows 7.
OK, that seems odd. Insert some (temporary) debugging code so we can track how many times this code gets called:
# check the frame counter:
if frameN == 0:
# so that this only happens once per routine:
win.getMovieFrame()
# check how many times this actually occurs
print(your_loop_name.thisN)