سؤال

لدي هذا البرنامج، والذي كما ترون يقوم بسحب صور عشوائية من الدليل، ويطلب من المستخدم مقارنتها.بعد ضبط القيمة باستخدام شريط التمرير، يضغط المستخدم على زر "التجربة التالية"، الذي يقوم بإعادة تعيين شريط التمرير وزوج الصور العشوائي.كيف أقوم بتعديل الكود بحيث، بعد عدد معين من التكرارات (الضغط على الزر)، ينتهي البرنامج تلقائيًا (ويفضل أن يكون ذلك برسالة "انتهت التجربة")؟

لا يمكنني العثور على أي شيء حول كيفية القيام بذلك في وثائق 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
هل كانت مفيدة؟

المحلول

إحدى المشاكل التي أراها هنا هي أن رد الاتصال لزر "التجربة التالية" الخاص بك يستدعي الوظيفة ببساطة 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


اقتراح إضافي واحد...بدلاً من عرض قيمة شريط التمرير على الشاشة باستخدام FPPRINTF, ، سأقوم بإنشاء كائن نصي في واجهة المستخدم الرسومية الخاصة بك وقم ببساطة بتحديث قيمة السلسلة الخاصة به:

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

%# And in function cb...
set(hText, 'String', sprintf('Slider value: %f', lastVal));
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top