Остановить программу MATLAB после X повторений? - PullRequest
2 голосов
/ 22 февраля 2012

У меня есть эта программа, которая, как вы можете видеть, вытаскивает случайные изображения из каталога и просит пользователя сравнить их. После установки значения с помощью ползунка пользователь нажимает кнопку «Следующая пробная версия», которая сбрасывает ползунок и пару случайных изображений. Как изменить код так, чтобы после определенного количества повторений (нажатий кнопок) программа автоматически заканчивалась (желательно с сообщением «Эксперимент завершен»)?

Я не могу найти ничего о том, как это сделать, в документации MATLAB. Нужно ли устанавливать переменную, чтобы при каждом нажатии кнопки «1» добавлялось к значению переменной, чтобы при достижении определенного числа (скажем, «100») оно заканчивалось? Это самый простой способ сделать это?

Вот сценарий:

function trials

files = dir(fullfile('samples','*.png'));
nFiles = numel(files);
combos = nchoosek(1:nFiles, 2);
index = combos(randperm(size(combos, 1)), :);
picture1 = files(index(1)).name;
picture2 = files(index(2)).name;
image1 = fullfile('samples',picture1);
image2 = fullfile('samples',picture2);
subplot(1,2,1); imshow(image1);
subplot(1,2,2); imshow(image2);

uicontrol('Style', 'text',...
        'Position', [200 375 200 20],...
        'String','How related are these pictures?');
uicontrol('Style', 'text',...
        'Position', [50 375 100 20],...
        'String','Unrelated');
uicontrol('Style', 'text',...
        'Position', [450 375 100 20],...
        'String','Closely related');
uicontrol('Style','pushbutton','String','Next Trial',...
        'Position', [250 45 100 20],...
        'Callback','clf; trials()');

h = uicontrol(gcf,...
   'Style','slider',...
   'Min' ,0,'Max',50, ...
   'Position',[100 350 400 20], ...
   'Value', 25,...
   'SliderStep',[0.02 0.1], ...
   'BackgroundColor',[0.8,0.8,0.8]);

set(gcf, 'WindowButtonMotionFcn', @cb);

lastVal = get(h, 'Value'); 

function cb(s,e)
    if get(h, 'Value') ~= lastVal 
    lastVal = get(h, 'Value'); 
    fprintf('Slider value: %f\n', lastVal); 
    end
end

end

1 Ответ

3 голосов
/ 22 февраля 2012

Одна проблема, которую я вижу здесь, заключается в том, что обратный вызов для вашей кнопки «Следующая пробная версия» просто снова вызывает функцию trials. Это снова сгенерирует комбинации изображений, которые вы хотите / должны сделать только один раз. Вы должны установить обратный вызов как другую вложенную функцию (например, cb), чтобы он мог получить доступ к уже сгенерированным комбинациям.

Другая проблема заключается в том, как вы инициализируете picture1 и picture2. Вы должны выполнить индексацию следующим образом:

picture1 = files(index(1,1)).name;  %# Note that index is 2-dimensional!
picture2 = files(index(1,2)).name;

Теперь вам нужно сначала инициализировать переменную, чтобы отслеживать количество попыток внутри функции trials, а также максимальное количество попыток:

nReps = 1;
maxReps = 100;

Тогда обратный вызов кнопки «Следующая пробная версия» будет выглядеть примерно так:

function newTrial(s, e)
    %# I assume you need the slider value for each trial, so fetch it
    %#   and save/store it here.

    %# Check the number of trials:
    if (nReps == maxReps)
        close(gcf);  %# Close the figure window
    else
        nReps = nReps + 1;
    end

    %# Get the new images:
    picture1 = files(index(nReps, 1)).name;
    picture2 = files(index(nReps, 2)).name;
    image1 = fullfile('samples', picture1);
    image2 = fullfile('samples', picture2);

    %# Plot the new images:
    subplot(1,2,1);
    imshow(image1);
    subplot(1,2,2);
    imshow(image2);

    %# Reset the slider to the default value:
    set(h, 'Value', 25);
end


Еще одно предложение ... вместо отображения значения ползунка на экране, используя FPRINTF , я бы создал текстовый объект в вашем графическом интерфейсе и просто обновил бы его строковое значение:

hText = uicontrol('Style', 'text', ...
                  'String', 'Slider value: 25', ... );

%# And in function cb...
set(hText, 'String', sprintf('Slider value: %f', lastVal));
...