2016-03-05 2 views
0

Я ищу более эффективный способ рисования сплошных линий в PsychoPy. Вот что я придумал, сейчас ...эффективный способ рисования сплошной линии в психопедии

редактировать: единственное улучшение, я мог думать о том, чтобы добавить новую строку только если мышь действительно перемещается, добавив if (mspos1-mspos2).any():

ms = event.Mouse(myWin) 

lines = [] 

mspos1 = ms.getPos() 
while True: 
    mspos2 = ms.getPos() 
    if (mspos1-mspos2).any(): 
     lines.append(visual.Line(myWin, start=mspos1, end=mspos2)) 
    for j in lines: 
     j.draw() 
    myWin.flip() 
    mspos1 = mspos2 

редактирование: Я пробовал с Shape.Stim (код ниже), в надежде, что она будет работать лучше, но получить резкий-х еще быстрее ..

vertices = [ms.getPos()] 
con_line = visual.ShapeStim(myWin, 
     lineColor='red', 
     closeShape=False) 
myclock.reset() 
i = 0 
while myclock.getTime() < 15: 
    new_pos = ms.getPos() 
    if (vertices[i]-new_pos).any(): 
     vertices.append(new_pos) 
     i += 1 
    con_line.vertices=vertices 
    con_line.draw() 
    myWin.flip() 
+1

Можете ли вы описать более, что вы имеете в виду под «более эффективным способом»? Что не так с вашим нынешним подходом, что вы хотели бы улучшить/исправить? – Castaglia

+0

примерно через 14 секунд линии становятся резкими, потому что это слишком большая рабочая нагрузка для рисования всех линий с каждым циклом; поэтому я хотел бы найти другой способ рисовать гладкие линии. – piot

+0

Не могли бы вы понять, что означает «острый»? Предпочтительно размещать снимок экрана из нерезких и резких линий. Кроме того, предложение или два о вашей цели облегчит поиск решений и облегчит их поиск в Google. –

ответ

2

проблема заключается в том, что он становится слишком Ressource с требованием привлечь те, многие visual.Line s или манипулировать этими множествами вершин в visual.ShapeStim на каждой итерации цикла. Таким образом, он будет висеть на ничьей (для линий) или назначении вершин (для ShapeStim) так долго, что мышь достаточно переместилась, чтобы линия отображала разрывы («острый»).

Так что это проблема с производительностью. Вот две идеи:

  1. У вас есть нижний порог для минимального расстояния, пройденного мышью, прежде чем вы хотите добавить новую координату в линию. В приведенном ниже примере я налагаю критерий, согласно которому положение мыши должно быть на расстоянии не менее 10 пикселей от предыдущей вершины для записи. В моем тестировании это сжало количество вершин, записанных в секунду примерно до трети. Только эта стратегия отложит проблему производительности, но не предотвратит ее, поэтому ...
  2. Используйте решение ShapeStim, но регулярно используйте новый ShapeStims, каждый с меньшим количеством вершин, так что стимул для обновления не слишком сложный. В приведенном ниже примере я задал сложность на 500 пикселей, прежде чем перейти к новому стимулу. Может быть небольшой сбой при создании нового стимула, но я ничего не заметил.

Так Объединив эти две стратегии, начиная и заканчивая рисунок мыши с печатью на клавиатуре:

# Setting things up 
from psychopy import visual, event, core 
import numpy as np 

# The crucial controls for performance. Adjust to your system/liking. 
distance_to_record = 10 # number of pixels between coordinate recordings 
screenshot_interval = 500 # number of coordinate recordings before shifting to a new ShapeStim 

# Stimuli 
myWin = visual.Window(units='pix') 
ms = event.Mouse() 
myclock = core.Clock() 

# The initial ShapeStim in the "stimuli" list. We can refer to the latest 
# as stimuli[-1] and will do that throughout the script. The others are 
# "finished" and will only be used for draw. 
stimuli = [visual.ShapeStim(myWin, 
     lineColor='white', 
     closeShape=False, 
     vertices=np.empty((0, 2)))] 

# Wait for a key, then start with this mouse position 
event.waitKeys() 
stimuli[-1].vertices = np.array([ms.getPos()]) 
myclock.reset() 
while not event.getKeys(): 
    # Get mouse position 
    new_pos = ms.getPos() 

    # Calculating distance moved since last. Pure pythagoras. 
    # Index -1 is the last row.index 
    distance_moved = np.sqrt((stimuli[-1].vertices[-1][0]-new_pos[0])**2+(stimuli[-1].vertices[-1][1]-new_pos[1])**2) 

    # If mouse has moved the minimum required distance, add the new vertex to the ShapeStim. 
    if distance_moved > distance_to_record: 
     stimuli[-1].vertices = np.append(stimuli[-1].vertices, np.array([new_pos]), axis=0) 

    # ... and show it (along with any "full" ShapeStims 
    for stim in stimuli: 
     stim.draw() 
    myWin.flip() 

    # Add a new ShapeStim once the old one is too full 
    if len(stimuli[-1].vertices) > screenshot_interval: 
     print "new shapestim now!" 
     stimuli.append(visual.ShapeStim(myWin, 
             lineColor='white', 
             closeShape=False, 
             vertices=[stimuli[-1].vertices[-1]])) # start from the last vertex 
+0

благодарим за это приятное решение! – piot

Смежные вопросы