PDA

View Full Version : حذف پیش زمینه از تصویر



mahsava
جمعه 28 شهریور 1393, 15:55 عصر
تصویری از پشت دست فردی داریم و با استفاده از یکی از الگوریتم های لبه یابی کانتور آن را به دست آورده ایم. حال می خواهیم با استفاده از این کانتور (و یا روش بهتری) شیء را از تصویر جدا کرده و پیش زمینه را حذف کنیم. چه کدی باید نوشته شود؟
(سعی کردم تصاویر را اضافه کنم ولی نشد!)

rahnema1
جمعه 28 شهریور 1393, 22:37 عصر
توی تاپیک زیر این مباحث گفته شده
http://barnamenevis.org/showthread.php?458959

mahsava
سه شنبه 01 مهر 1393, 14:41 عصر
ممنون. تاپیک مفیدی بود. اما مشکل من همون ابتدای کاره. تو اون تاپیک چون شکل هندوانه کاملا محدب هست راحت میشه با استفاده از کانتور از پیش زمینه جداش کرد. اما شکلی که من دارم تصویر یک دسته.

123801

که کانتورش رو به دست آوردم

123800

حالا میخوام از روی کانتور یه ماسک درست کنم که با کانوالو کردنش در تصویر اصلی بتونم کل دست رو از پیش زمینه جدا کنم. کدش رو نوشتم اما خطا داره. مشکل قسمت هایی از کانتوره که لبه ی افقی داریم (که ممکنه طولش دو پیکسل یا بیشتر باشه).

mahsava
سه شنبه 01 مهر 1393, 15:22 عصر
کد رو باید بین چه تگی قرار بدم که تروتمیز دیده بشه؟

mahsava
سه شنبه 01 مهر 1393, 16:03 عصر
function [ maskIm ] = contour2mask( contourIm )
% this function get a contour (binary image), fill inside of it with 1 and
% return a binary mask
rowsNo = size(contourIm,1);
colsNo = size(contourIm,2);
maskIm = zeros(rowsNo,colsNo);
for i=1:rowsNo
sw = 1;
startPoint = 0;
endPoint = 0;
count = 0;
j = 1;
while j < colsNo
if i == 181
a = 0;
end
while j < colsNo && ~contourIm(i,j) % find first 1
j = j + 1;
end
if j < colsNo
startPoint = j;
count = 1;
else break; % no 1s
end
while j < colsNo && contourIm(i,j) % find next 0
count = count + 1;
j = j + 1;
end
if count > 3
sw = 0;
endPoint = startPoint + count - 1;
else while j < colsNo && ~contourIm(i,j) % find next 1
count = count + 1;
j = j + 1;
end
if j < colsNo && contourIm(i,j)
count = count + 1;
j = j + 1;
end
if j <= colsNo && contourIm(i,j)
count = count + 1;
j = j + 1;
end
endPoint = startPoint + count - 1;

end
for k=startPoint:endPoint
maskIm(i,k) = 1;
end
j = j + 1;
end
end

rahnema1
چهارشنبه 02 مهر 1393, 08:25 صبح
مهم اینه که یک محدوده کاملا بسته داشته باشیم تا بتونید اون را پر کنیم
اون لبه دست که شما گذاشته بودید بعضی جا ها منافذی داشت که با عملیات مورفولوژیکی پر شد پایین دست هم باید بسته می شد
در شمن به جای اون حلقه میشه از دستور imfill استفاده کرد که داخل محدوده را پر کنه
غیر از این روش یک روش دیگه را می تونید استفاده کنید که لبه دست را با استفاده از گزینه Lindeberg از دستور edge به دست بیارید و تعداد زیادی خط ایجاد می شه که بلند ترین اونها لبه دست مورد نظره که با استفاده از bwconncomp و لیبل گذاری هر سگمنت میشه اون را استخراج و داخل اون را پر کرد

contourIm=imread('2.bmp')>100;
maskIm=contourIm;
kernel=[-1, -size(maskIm,1), 1, size(maskIm,1)];
maskIm=(bwmorph(bwmorph(maskIm,'bridge'),'spur'));
maskIm=(bwmorph(maskIm & bwmorph(maskIm==0,'majority'),'bridge'));
maskIm=(bwmorph(maskIm,'shrink'));
idx=find(maskIm-bwmorph(maskIm,'shrink'));
[p1r p1c]= ind2sub(size(maskIm),idx(1));
[p2r p2c]= ind2sub(size(maskIm),idx(2));
Length=max([abs(p2c-p1c) abs(p2r-p1r)])+2;
lr= round(linspace(p1r,p2r,Length));
lc= round(linspace(p1c,p2c,Length));
idx2=sub2ind(size(maskIm),lr,lc);
maskIm(idx2)=1;
list1=[sub2ind(size(maskIm),round(size(maskIm,1)/2),round(size(maskIm,2)/2))];
while numel(list1)>0
list2=[];
for L=1:numel(list1)
idxkernel=list1(L)+kernel;
idxfill=idxkernel(find(maskIm(idxkernel)==0));
maskIm(idxfill)=1;
list2=[list2 idxfill];
end
list1=list2;
end
imshow(maskIm);

mahsava
چهارشنبه 02 مهر 1393, 13:48 عصر
بسیار عالی. خیلی ممنون از راهنماییتون.
متوجه نشدم تصویری که تو خط اول می خونیدش کدومه؟ خودتون ساختینش؟ چرا مقادیر بزرگتر از 100؟ متوجه نشدم دقیقا چیکار کردین.

rahnema1
چهارشنبه 02 مهر 1393, 19:09 عصر
بسیار عالی. خیلی ممنون از راهنماییتون.
متوجه نشدم تصویری که تو خط اول می خونیدش کدومه؟ خودتون ساختینش؟ چرا مقادیر بزرگتر از 100؟ متوجه نشدم دقیقا چیکار کردین.

همون تصویر 2 که گذاشتید توسط browser هم به فرمت jpg و هم bmp ذخیره کرده و یه مشکل داشت که تصویر شامل 0و 255 نبود بلکه مقادیر دیگه هم داشت که یک آستانه گذاشتم مثل مقدار 100 که پایین تر ازاون سیاه و بالاتر از اون سفید بشه با دستور unique می تونید متوجه بشید که محتوای اون تصویر فقط دو تا عدد نیست

mahsava
چهارشنبه 02 مهر 1393, 19:58 عصر
من همین کد رو اجرا کردم ولی خطای خارج از آرایه داد. روند کار رو نگاه کردم داشت درست پیش می رفت ولی از یه جایی به بعد شروع کرد به پر کردن بیرون از دست. شما مشخصه Matlab رو خیلی تخصصی بلدین. خط های اول مشخص بود که عملیات موفولوژیکی انجام میده ولی من متوجه نشدم خط های بعدی چطور عمل می کنن. باید بیشتر اجراش کنم شاید بفهمم مشکلش چیه

rahnema1
چهارشنبه 02 مهر 1393, 20:05 عصر
من همین کد رو اجرا کردم ولی خطای خارج از آرایه داد. روند کار رو نگاه کردم داشت درست پیش می رفت ولی از یه جایی به بعد شروع کرد به پر کردن بیرون از دست. شما مشخصه Matlab رو خیلی تخصصی بلدین. خط های اول مشخص بود که عملیات موفولوژیکی انجام میده ولی من متوجه نشدم خط های بعدی چطور عمل می کنن. باید بیشتر اجراش کنم شاید بفهمم مشکلش چیه
من برنامه را در متلب تست نکردم در نرم افزار octave که شبیه متلب هست اجرا کردم. شاید بعضی نتایج مورفولوژی نتایجش کمی متفاوت باشه در نتیجه محدوده دست کاملا بسته نشده یه کم با توابع مورفولوژی ور برید تا محدوده کاملا بسته بشه

mahsava
چهارشنبه 02 مهر 1393, 20:12 عصر
بازم ممنون. کمک خیلی بزرگی کردین. من یه مدت کلی وقت گذاشتم رو این قسمت از کد ولی به هیچ نتیجه ای نرسیدم!
باید بهش بیشتر ور برم.

rahnema1
چهارشنبه 02 مهر 1393, 20:29 عصر
اینجور شد
http://www.sharefile.ir/uploads/1411674740.png

mahsava
چهارشنبه 02 مهر 1393, 20:48 عصر
تصویر کلا 13 بایته؟!

rahnema1
چهارشنبه 02 مهر 1393, 20:52 عصر
تصویر که دو تا مقدار بیشتر نداره : 0 و 1 علاوه بر این تصویر فشرده هم میشه که حجمش اینقدر میشه

mahsava
چهارشنبه 02 مهر 1393, 21:03 عصر
آخه نه ویندوز بازش می کنه و نه متلب

rahnema1
چهارشنبه 02 مهر 1393, 21:06 عصر
با دو فرمت png و gif http://www.sharefile.ir/uploads/1411629391.zip

mahsava
چهارشنبه 02 مهر 1393, 21:13 عصر
این درسته. مرسی

tiger1978
پنج شنبه 23 شهریور 1396, 19:59 عصر
سلام
من یک مقاله دارم که باید مورفولوژی را روی که تصویر اعمال کنه ان تصویر باید نویز و پس زمینه ان جدا بشه بعد روی تصویر اصلی کار اصلی مقاله انجام بشه قسمت اول را کدش را پیدا کردم اما نمی دونم چطور باید در برنامه اجراش کنم
30 lines (206 sloc) 6.71 KB
function ML = perform_mca(M, components, options)


% perform_mca - perform MCA decomposition
%
% ML = perform_mca(M, components, options);
%
% ML(:,:,i) is the layer optained by sparse decomposition in
% dictionary Di described by components{i}.
%
% components is a cell array of structure.
% cpt = components{i) discribe the ith transform used.
%
% It must contains:
% cpt.callback: a function of the type
% y = function(x,dir,options);
% for instance you can set cpt.callback=@callback_atrou
%
% It can contains:
% cpt.options: the options given to the callback
% cpt.threshold_factor: an amplification factor for the thresholding.
% cpt.tv_correction and cpt.tv_weight: the MCA will perform an
% additional TV minimization (usefull for the cartoon layer).
%
% options contains options for the MCA process such as:
% options.niter: number of iterations.
% options.saverep: directory to save iterations
% options.Tmax and options.Tmin: maximum and minimum threshold
% values. Set Tmin=0 if there is no noise in the problem
% (decomposition will be exact i.e. M=sum(ML,3)
% Set Tmax to approximately the maximum value of the
% coefficients of all the transforms of M.
%
% The references for the Morphological Components Analysis are
%
% J. Bobin, Y. Moudden, J.-L. Starck and M. Elad,
% "Morphological Diversity and Source Separation",
% IEEE Transaction on Signal Processing , Vol 13, 7, pp 409--412, 2006.
%
% M. Elad, J.-L Starck, D. Donoho and P. Querre,
% "Simultaneous Cartoon and Texture Image Inpainting using Morphological Component Analysis (MCA)",
% Journal on Applied and Computational Harmonic Analysis ACHA , Vol. 19, pp. 340-358, November 2005.
%
% J.-L. Starck, M. Elad, and D.L. Donoho,
% "Image Decomposition Via the Combination of Sparse Representation and a Variational Approach",
% IEEE Transaction on Image Processing , 14, 10, 2005.
%
% J.-L. Starck, M. Elad, and D.L. Donoho,
% "Redundant Multiscale Transforms and their Application for Morphological Component Analysis",
% Advances in Imaging and Electron Physics , 132, 2004.
%
% See also: perform_iterative_thresholding.
%
% Copyright (c) 2007 Gabriel Peyre

tiger1978
پنج شنبه 23 شهریور 1396, 19:59 عصر
options.null = 0;
if isfield(options, 'niter')
niter = options.niter;
else
niter = 20;
end
if isfield(options, 'Tmax')
Tmax = options.Tmax;
else
Tmax = 0.2*max(abs(M(:)));
end
if isfield(options, 'Tmin')
Tmin = options.Tmin;
else
Tmin = 0;
end
if isfield(options, 'threshold')
threshold = options.threshold;
else
threshold = 'hard';
end
if isfield(options, 'saverep')
saverep = options.saverep;
else
saverep = [];
end
if isfield(options, 'InpaintingMask')
InpaintingMask = options.InpaintingMask;
else
InpaintingMask = [];
end


s = length(components);




% init the residual
n = size(M,1);
ML = zeros(n,n,s);
if not(isempty(InpaintingMask))
q = sum(InpaintingMask(:)==Inf);
for k=1:s
Mk = ML(:,:,k);
Mk(InpaintingMask==Inf) = rand( q,1 ) * max( M(InpaintingMask~=Inf) );
ML(:,:,k) = Mk;
end
end




MLsave = [];
for i=1:niter
progressbar(i,niter);
% current threshold
T0 = Tmax + (i-1)/(niter-1)*(Tmin-Tmax);
for k=1:s

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% current component
cpt = components{k};
% callback function
callback = cpt.callback;
% options
clear opt; opt.null = 0;
if isfield(cpt, 'options')
opt = cpt.options;
end
% threshold factor amplification
threshold_factor = 1;
if isfield(cpt, 'threshold_factor')
threshold_factor = cpt.threshold_factor;
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% compute residual
T = T0 * threshold_factor;
opt.T = T;
% compute residual
sel = 1:s; sel(k) = [];
R = M - sum( ML(:,:,sel), 3);
if not(isempty(InpaintingMask))
% enforce known values only outside
Mk = ML(:,:,k);
R(InpaintingMask==Inf) = Mk(InpaintingMask==Inf);
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% perform forward transform
RW = feval(callback, R,+1,opt);
% perform thresholding
if strcmp(cpt.name, 'wav')
% do not threshold the low frequency
RW1 = perform_thresholding({RW{1:end-1}},T, threshold);
RW = {RW1{:}, RW{end}};
else
RW = perform_thresholding(RW,T, threshold);
end
% perform backward transform
ML(:,:,k) = feval(callback, RW,-1,opt);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% TV additional sparsening
if isfield(cpt, 'tv_correction') && cpt.tv_correction==1
if isfield(options, 'tv_weight')
tv_weight = options.tv_weight;
else
tv_weight = 2.5*max(abs(M(:)))/256;
end
ML(:,:,k) = perform_tv_correction(ML(:,:,k),tv_weight);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% save result
if not(isempty(saverep))
MLsave(:,:,:,i) = ML;
end
end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% save all the data
if not(isempty(saverep))
% normalize the evolution
vmax = max(max(max(MLsave,[],1),[],2),[],4);
vmax = repmat(vmax, [n n 1 niter]);
vmin = min(min(min(MLsave,[],1),[],2),[],4);
vmin = repmat(vmin, [n n 1 niter]);
MLsave = (MLsave-vmin) ./ (vmax-vmin);

for k=1:s
cpt = components{k};
for i=1:niter
if isfield(cpt, 'name')
str = cpt.name;
else
str = ['layer' num2str(k)];
end
str = [str '-iter' num2string_fixeddigit(i,2)];
warning off;
imwrite( MLsave(:,:,k,i), [saverep str '.png'], 'png' );
warning on;
end
end
end








%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%
function y = perform_hard_tresholding(x,t)


if iscell(x)
for i=1:length(x)
y{i} = perform_hard_tresholding(x{i},t);
end
return;
end


y = x .* (abs(x) > t);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%
function y = perform_soft_tresholding(x,t)


if iscell(x)
for i=1:length(x)
y{i} = perform_soft_tresholding(x{i},t);
end
return;
end


s = abs(x) - t;
s = (s + abs(s))/2;
y = sign(x).*s;