View Full Version : بهترین راه برای اجتناب از به کار بردن چهار حلقه های تو در تو در متلب
moeinmohebbi
چهارشنبه 28 مرداد 1394, 22:36 عصر
من کدی نوشتم که مجبور به استفاده از 4 حلقه تو در تو در آن شدم و سرعت اجرای آن بسیار کم است . کاری که می خواستم انجام بدم این بود که دو تا تصویر رنگی دارم ، تصویر A و تصویر B ، می خوام مقدار کانال اول هر پیکسل از A رو با مقدار کانال اول تمام پیکسل های تصویر B مقایسه کنم و پیکسل هایی را در تصویر B پیدا کنم که کمترین اختلاف را با پیکسل مورد نظر در تصویر A داشته باشد ، خروجی این مقایسه آرایه ای از پیکسل های تصویر B برای هر پیکسل A خواهد بود .
در قدم بعدی ، برای مقدار کانال دوم هر پیکسل در تصویر A ،میانگین مقادیر کانال دوم پیکسل های موجود در تصویر B که در آرایه ذخیره کردیم را قرار دهیم .
همینطور ، برای مقدار کانال سوم هر پیکسل در تصویر A ،میانگین مقادیر کانال سوم پیکسل های موجود در تصویر B که در آرایه ذخیره کردیم را قرار دهیم .
شاید یکم توضیحش سخت باشه ، این سوال رو در Stack Overflow مطرح کردم ولی نتونستم منظورم رو خوب توضیح بدم و کسی جواب درست و حسابی بهم نداد . اگر متوجه نشدید با یک مثال بیشتر توضیح بدم .
کدی (http://s6.picofile.com/file/8207273876/Code.m.html)که نوشتم رو ضمیمه میکنم .
rahnema1
جمعه 30 مرداد 1394, 00:42 صبح
سلام
در ابتدا یه سوال اینکه چرا w و h را منهای یک کردید فکر کنم نباید این کار را انجام بدید و من هم در کد زیر منهای یک نکردم
همچنین سوال دیگه اینکه وقتی می خواهید x را به دست بیارید نباید abs بگیرید؟
اگه حافظه به مقدار کافی دارید از کد زیر استفاده کنید در واقع حلقه ها تبدیل به کد زیر می شوند
[Yi, Xi] = meshgrid(uint16(1:(w * h)), uint16(1:(w * h)));
x = abs(imgOrginal(Xi) - imgTheme( Yi));
clear Yi Xi;
x = mat2cell(x, ones(1, w*h), w * h);
chrominance1 = cellfun(@(x) mean(imgThemeCh1((x == min(x)))), x);
chrominance2 = cellfun(@(x) mean(imgThemeCh1((x == max(x)))), x);
clear x;
اگه حافظه کم آورد 4 تا حلقه به یک حلقه تبدیل می شه:
for ts = 1:(w * h)
x = abs(imgOrginal(ts) - imgTheme(:));
chrominance1(ts) = mean(imgThemeCh1(x == min(x)));
chrominance2(ts) = mean(imgThemeCh1(x == max(x)));
end
moeinmohebbi
شنبه 31 مرداد 1394, 04:12 صبح
سلام
در ابتدا یه سوال اینکه چرا w و h را منهای یک کردید فکر کنم نباید این کار را انجام بدید و من هم در کد زیر منهای یک نکردم
همچنین سوال دیگه اینکه وقتی می خواهید x را به دست بیارید نباید abs بگیرید؟
اگه حافظه به مقدار کافی دارید از کد زیر استفاده کنید در واقع حلقه ها تبدیل به کد زیر می شوند
( داخل کد از تابع accumarray2 استفاده شده که ضمیمه کردم)
[Yi Xi] = meshgrid(1:(w * h),1:(w * h));
x = imgOrginal(Xi) - imgTheme( Yi);
clear Yi;
a = accumarray2(Xi(:), x, [], @(x) find(x == min(x)))
temp1 = cellfun(@(y, img) img(y), a , mat2cell(imgThemeCh1, ones(1, h), w), 'UniformOutput', false);
chrominance1 = cellfun(@mean, temp1);
a = accumarray2(Xi(:), x, [], @(x) find(x == max(x)))
temp1 = cellfun(@(y, img) img(y), a , mat2cell(imgThemeCh1, ones(1, h), w), 'UniformOutput', false);
chrominance2 = cellfun(@mean, temp1);
clear Xi x a temp1;
تابع accumarray2 :
http://www.sharefile.ir/uploads/1440108332.zip
اگه حافظه کم آورد 4 تا حلقه به یک حلقه تبدیل می شه:
for ts = 1:(w * h)
x = imgOrginal(ts) - imgTheme;
a = find(x==min(x(:)));
temp1=imgThemeCh1(a);
chrominance1(ts)=mean(temp1);
a = find(x==max(x(:)));
temp1=imgThemeCh1(a);
chrominance2(ts) = mean(temp1);
end
سلام مهندس عزیز .
خیلی ممنونم ازت . به طرز معجزه آسایی سرعت اجرا بالا رفت . یکدنیا ممنون .:قلب: :تشویق:
کد بالایی رو اجرا کردم لپ تابم رفت تو کما :) ولی کد پایینی کارمو راه انداخت. روی عکس 128x128 قبلا یک دقیقه و و سی ثانیه طول میکشید الان کمتر از 10 ثانیه خروجی میده .
اما راجع به سوالی که پرسیدید .
چرا w و h را منهای یک کردید فکر کنم نباید این کار را انجام بدید و من هم در کد زیر منهای یک نکردم بله درست می فرمایید . واسه دیباگ کردنش این کار رو کرده بودم و برنگردونده بودم به حالت درست .
همچنین سوال دیگه اینکه وقتی می خواهید x را به دست بیارید نباید abs بگیرید؟ متوجه منظورتون نشدم .
در ضمن از کد پایین که تک حلقه ای بود یه چیزایی دستگیرم شد . :قهقهه: ولی از کد بالایی زیاد سر در نمیارم . منبع مطالعاتی دارید که معرفی کنید بهم . کار من SQL هست و از پارسال که هوش مصنوعی قبول شدم فهمیدم متلب چیه و از این تکنیک ها سر در نمیارم . :)
در نهایت می خوام یه بار دیگه ازتون تشکر کنم بابت راهنمایی و اشتراک دانشتون .
پیروز باشید.
rahnema1
شنبه 31 مرداد 1394, 17:47 عصر
کدی که حافظه زیاد مصرف می کنه یه اشکال داشت که برطرف کردم ضمن اینکه از uint16 استفاده کردم که حافظه کمتری مصرف کنه که دامنه uint16 برای عکس های تا سایز 256 در 256 جواب میده
ضمن اینکه abs را هم اضافه کردم که سوال پرسیدید
کد مربوط به حلقه هم یه کم جمع و جور کردم فکر کنم سرعتش هم بیشتر شده
تا می تونیم نباید از حلقه استفاده کنیم تا سرعت بیشتر بشه و به جای اون اندیسهای حلقه را قبلا با دستوراتی مثل meshgrid تولید کنیم و به خورد ماتریس بدیم
اون علامتهای @ مربوط به تابعهای Inline هست
فکر کنم لازمه به هلپ متلب یا آموزشهای مختلف که تو اینترنت هست مراجعه کنید کتاب هم که فراوون هست.
یه سری دستورات پرکاربرد متلب در pdf هایی به نام reference card یا quick reference هست که می تونید خصوصیات هر کدوم را مطالعه کنید که به چه دردی می خوره
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.