ورود

View Full Version : مشکل در باینری کردن تصویر



mahsava
چهارشنبه 15 بهمن 1393, 00:16 صبح
من یک سری تصویر دارم که سعی کردم به روش های مختلفی اونا رو باینری کنم ولی هر روشی یه ایرادی داره و بعضی جاها خطا میده (رزولوشن تصاویر پایینه و نویزشون زیاده. تصاویر هم کمی با هم فرق می کنن).

128175

نتیجه ی اعمال یکی از روش های باینری کردن (روش Otsu) این تصویره:

128176

حالا میخوام اون قسمت تصویر رو که درون شبه دایره قرار داره، از توی تصویر بکشم بیرون یا به اصلاح یه ماسک درست کنم و بقیه ی تصویر رو بریزم دور (چون تقریبا میشه گفت فقط با داخل این شبه دایره کار دارم).
دنبال یک راه ساده می گردم. درضمن Matlab من نسخه ی 2010 هست و بعضی از توابع مثل imfindcircles رو نداره.
کسی می تونه راهنماییم کنه؟

rahnema1
پنج شنبه 16 بهمن 1393, 14:45 عصر
سلام
میشه با روشهایی مثل flood fill داخل مناطق حاشیه ای را سفید کرد

mahsava
شنبه 18 بهمن 1393, 00:41 صبح
یک مشکلی که اینجا وجود داره اینه که تو بعضی از تصاویر قسمت مچ دست به پیش زمینه چسبیده. برای همین جدا کردنش آسون نیست. من فکر می کنم باید یه جوری از مختصات اون دایره ی وسط استفاده کنم. البته تو تصاویر مختلف یه کم مکانش جا به جا شده.
یک ایده این بود که تو دو مرحله دو تا حلقه بذاریم روی ردیف ها و بعد روی ستون ها. توی هر ردیف به ترتیب پیکسل های سیاه رو سفید می کنیم تا به اولین پیسکل سفید برسیم. این کار رو اول واسه پیسکل های سمت چپ دست انجام میدیم و دفعه ی دوم برای پیکسل های سمت راست.
نتیجه تقریبا خوبه فقط مشکلش اینه که واسه بعضی از تصاویر ممکنه سمت چپ یا سمت راست دست، اصلا هیچ پیکسل سفیدی وجود نداشته باشه.
مثلا این یکی از همون موارده:

128238

که نتیجه اش میشه این تصویر:

128239

همین طور که می بینید، گوشه ی پایین سمت چپ کار رو خراب کرده.

rahnema1
یک شنبه 19 بهمن 1393, 13:15 عصر
این روش را تست کنید
خطوط اضافی را به راحتی می توان حذف کرد چون طول آنها از طول حاشیه دست کمتره

I = imreag(11.jpg');
I = rgb2gray(I);
E = edge(I,'Lindeberg');
[r c]= size(E);
E([1,r],:) = 1;
E(:,[1,c]) = 1;
Eshrinked = bwmorph(E,'shrink',inf);
Ecleaned = bwmorph(Eshrinked,'clean');
imshow(Ecleaned)

mahsava
یک شنبه 19 بهمن 1393, 18:23 عصر
ممنون از لطفتون.
این جور پردازش رو من قبل امتحان کردم (با راهنمایی خودتون). من دارم روی یک مجموعه داده از تصاویر کار می کنم که تعداد تصاویرش زیاده.
مشکلی که وجود داره اینه که تصاویر با هم خیلی فرق می کنن. این کد روی یک تصویر خوب کار می کنه اما روی یک تصویر دیگه هنوز جای ویرایش داره. یعنی بسته به تصویر، عملیات مورفولوژیک لازم متفاوته. همین باعث میشه من نتونم به یک روش خودکار جامع همه ی تصاویر رو پردازش کنم

rahnema1
یک شنبه 19 بهمن 1393, 20:03 عصر
به نظر می رسه اجرای تنهای آستانه مشکل را حل نمی کنه بلکه لازمه از خصوصیات محلی مانند لبه هم استفاده بشه

mahsava
سه شنبه 28 بهمن 1393, 13:54 عصر
این روش را تست کنید
خطوط اضافی را به راحتی می توان حذف کرد چون طول آنها از طول حاشیه دست کمتره

I = imreag(11.jpg');
I = rgb2gray(I);
E = edge(I,'Lindeberg');
[r c]= size(E);
E([1,r],:) = 1;
E(:,[1,c]) = 1;
Eshrinked = bwmorph(E,'shrink',inf);
Ecleaned = bwmorph(Eshrinked,'clean');
imshow(Ecleaned)


Lindeberg توی matlab 2014 نیست. خودتون پیاده سازیش کردین یا فقط تو octave هست؟

rahnema1
سه شنبه 28 بهمن 1393, 14:46 عصر
Lindeberg توی matlab 2014 نیست. خودتون پیاده سازیش کردین یا فقط تو octave هست؟

درسته فقط توی octave هست. توی متلب دقت نکرده بودم

mahsava
سه شنبه 28 بهمن 1393, 15:05 عصر
من یه کم مقدار آستانه رو برای لبه یاب canny تغییر دادم. جواب ها خوب بودند. فقط یه مشکل کوچیک پیدا شد و اون هم اینه که دره ی بین دو تا انگشت ناپیوستگی پیدا می کنه.

128569

با عملیات مورفولوژیکی (dilation و erosion) سعی کردم ناپیوستگی رو از بین ببرم اما تصویر رو اینجوری خراب کرد.

128570

به نظر شما نوع structring element رو باید عوض کنم؟ خط، مستطیل، دیسک رو امتحان کردم

rahnema1
سه شنبه 28 بهمن 1393, 15:10 عصر
شما تصویر canny را با تصویر یک روش دیگه or کنید ببیند چه جوابی میده.

mahsava
سه شنبه 28 بهمن 1393, 15:13 عصر
باشه این کار رو می کنم. ولی نتیجه ی هیچ روشی به خوبی canny نیست.

rahnema1
سه شنبه 28 بهمن 1393, 15:26 عصر
با روش lindeberg این جور میشه
http://www.sharefile.ir/uploads/1424220665.gif
که بعد از clean کردن به این شکل در میاد
http://www.sharefile.ir/uploads/1424269722.gif
که اون قسمتهای کوچک را هم به راحتی می شه پاک کرد

mahsava
سه شنبه 28 بهمن 1393, 17:25 عصر
روش linedberg بهتر از canny کار می کنه؟ من نتونستم کدش رو پیدا کنم.
بعضی از تصاویر هستند که بین دو انگشت یک مقداری سیاهه. مثل این تصویر. البته من سعی کردم با فیلترهای مختلف تصویر رو بهبود بدم ولی در نهایت نتونستم اون سیاهی رو حذف کنم.

128576

فقط همین تصاویر مشکل ناپیوستگی دارند. تصویری که شما زحمت کشیدید و روش کار کردید هیچ مشکلی با لبه یاب canny نداره.

rahnema1
سه شنبه 28 بهمن 1393, 18:58 عصر
قبل از لبه یابی یک دستور histeq بزنیم تا لبه ها بهتر پیدا بشن بعد از histeq و استفاده از روش lindeberg
http://www.sharefile.ir/uploads/1424287033.gif
http://www.sharefile.ir/uploads/1424232147.gif


I = imread('m2.jpg');
I = rgb2gray(I);
I = histeq(I);
E = edge(I,'Lindeberg',2);
[r c]= size(E);
E([1,r],:) = 1;
E(:,[1,c]) = 1;
Eshrinked = bwmorph(E,'shrink',inf);
Ecleaned = bwmorph(Eshrinked,'clean');
imshow(Ecleaned)

mahsava
سه شنبه 28 بهمن 1393, 19:40 عصر
در آخر هم بزرگترین مولفه ی همبند رو جدا می کنیم. درسته؟
این روش رو من با استفاده از لبه یاب log امتحان کردم. چند تا از تصاویر کلا سیاه شدن ولی بقیه خوب بودن.

rahnema1
سه شنبه 28 بهمن 1393, 19:44 عصر
در آخر هم بزرگترین مولفه ی همبند رو جدا می کنیم. درسته؟
این روش رو من با استفاده از لبه یاب log امتحان کردم. چند تا از تصاویر کلا سیاه شدن ولی بقیه خوب بودن.

درسته همبند یا connected
با این حساب حله دیگه

mahsava
سه شنبه 28 بهمن 1393, 19:51 عصر
خب به نظر شما این روش Lindeberg رو چطور پیاده سازی کنم؟
برای تصاویری که سیاه میشن فکر کنم باید چک بشه که اگه یک مولفه ی همبند داشت، shrink نکنه. درسته؟ اینجوری دیگه تصویر سیاه نمیشه و از بین نمیره.
یه سوال دیگه: چرا پیکسل های دور تصویر رو "1" کردین؟

rahnema1
سه شنبه 28 بهمن 1393, 19:53 عصر
چند تا از تصاویر مشکل دار را لطفا بفرستید
فکر کنم lindeberg را بتونم از سورس octave بیرون بیارم
دورش را اگه 1 نمی کردیم shrink خوب عمل نمی کرد

mahsava
سه شنبه 28 بهمن 1393, 20:10 عصر
128582

این هم دومی

128583

البته این تصاویری هستند که من با لبه یاب log نتونستم خروجی ازشون بگیرم. ممکنه با روش
lindeberg درست باشن.

واقعا ممنون. خیلی کمک کردین.

rahnema1
سه شنبه 28 بهمن 1393, 20:28 عصر
نحوه استفاده:

I = rgb2gray(imread('m2.jpg'));
imshow(lindeberg(I))

اینها را در فایل lindeberg.m بذارید:

function bw = lindeberg(I)
%%I = rgb2gray(imread('m2.jpg'));
%%imshow(lindeberg(I))
%% In case the user asks for more then 1 output argument
%% we define thresh to be -1.
thresh = -1;
s = 2;
%% Filters for computing the derivatives
Px = [-1 0 1; -1 0 1; -1 0 1];
Py = [1 1 1; 0 0 0; -1 -1 -1];
Pxx = conv2(Px, Px, 'full');
Pyy = conv2(Py, Py, 'full');
Pxy = conv2(Px, Py, 'full');
Pxxx = conv2(Pxx, Px, 'full');
Pyyy = conv2(Pyy, Py, 'full');
Pxxy = conv2(Pxx, Py, 'full');
Pxyy = conv2(Pyy, Px, 'full');
%% Change scale
h = ceil(3*s);
f = exp( (-(-h:h).^2)./(2*s^2) ); f = f / sum(f);
%% Pad image
%%I = double(impad(I, h, h, 'symmetric'));
I = double(padarray(I, [h, h], 'symmetric'));
%% Perform the filtering

L = conv2(f, f, I, 'valid');

%L = imsmooth(double(im), 'Gaussian', sigma);
%% Compute derivatives
Lx = conv2(L, Px, 'same');
Ly = conv2(L, Py, 'same');
Lxx = conv2(L, Pxx, 'same');
Lyy = conv2(L, Pyy, 'same');
Lxy = conv2(L, Pxy, 'same');
Lxxx = conv2(L, Pxxx, 'same');
Lyyy = conv2(L, Pyyy, 'same');
Lxxy = conv2(L, Pxxy, 'same');
Lxyy = conv2(L, Pxyy, 'same');
%% Compute directional derivatives
Lvv = Lx.^2.*Lxx + 2.*Lx.*Ly.*Lxy + Ly.^2.*Lyy;
Lvvv = Lx.^3.*Lxxx + 3.*Lx.^2.*Ly.*Lxxy ...
+ 3.*Lx.*Ly.^2.*Lxyy + 3.*Ly.^3.*Lyyy;
%% Perform edge detection
bw = zerocrossings(Lvv) & Lvvv < 0;
end
function z = zerocrossings(f)
z0 = f<0; %% Negative
[R,C] = size(f);
z = zeros(R,C);
z(1:R-1,:) =z(1:R-1,:)| z0(2:R,:); %% Grow
z(2:R,:) = z(2:R,:)| z0(1:R-1,:);
z(:,1:C-1) = z(:,1:C-1)| z0(:,2:C);
z(:,2:C) = z(:,2:C)| z0(:,1:C-1);

z = z & ~(z0); %% 'Positive zero-crossings'?
end

mahsava
سه شنبه 28 بهمن 1393, 20:42 عصر
بسیار عالی!
خیلی خیلی ممنون. امیدوارم تو Matlab هم جواب بده.