سؤال

لدي صورة في ماتلاب:

y = rgb2gray(imread('some_image_file.jpg'));

وأريد أن أفعل بعض المعالجة عليه:

pic = some_processing(y);

والعثور على MAXIMA المحلية من الإخراج. وهذا هو، كل النقاط في y هذه أكبر من جميع جيرانهم.

لا أستطيع أن أجد وظيفة Matlab للقيام بذلك بشكل جيد. أفضل ما يمكنني التوصل إليه هو:

[dim_y,dim_x]=size(pic);
enlarged_pic=[zeros(1,dim_x+2);
              zeros(dim_y,1),pic,zeros(dim_y,1);
              zeros(1,dim_x+2)];

% now build a 3D array
% each plane will be the enlarged picture
% moved up,down,left or right,
% to all the diagonals, or not at all

[en_dim_y,en_dim_x]=size(enlarged_pic);

three_d(:,:,1)=enlarged_pic;
three_d(:,:,2)=[enlarged_pic(2:end,:);zeros(1,en_dim_x)];
three_d(:,:,3)=[zeros(1,en_dim_x);enlarged_pic(1:end-1,:)];
three_d(:,:,4)=[zeros(en_dim_y,1),enlarged_pic(:,1:end-1)];
three_d(:,:,5)=[enlarged_pic(:,2:end),zeros(en_dim_y,1)];
three_d(:,:,6)=[pic,zeros(dim_y,2);zeros(2,en_dim_x)];
three_d(:,:,7)=[zeros(2,en_dim_x);pic,zeros(dim_y,2)];
three_d(:,:,8)=[zeros(dim_y,2),pic;zeros(2,en_dim_x)];
three_d(:,:,9)=[zeros(2,en_dim_x);zeros(dim_y,2),pic];

ثم معرفة ما إذا كان الحد الأقصى على طول البعد الثالث يظهر في الطبقة الأولى (أي: three_d(:,:,1)):

(max_val, max_i) = max(three_d, 3);
result = find(max_i == 1);

هل هناك أي طريقة أكثر أناقة للقيام بذلك؟ هذا يبدو وكأنه قليلا من kludge.

هل كانت مفيدة؟

المحلول

bw = pic > imdilate(pic, [1 1 1; 1 0 1; 1 1 1]);

نصائح أخرى

إذا كان لديك معالجة الصور Toolbox., ، يمكنك استخدام imregionalmax. وظيفة:

BW = imregionalmax(y);

المتغير BW سيكون مصفوفة منطقية بنفس حجم y مع تلك التي تشير إلى الحد الأقصى المحلي والأصفار غير ذلك.

ملاحظة: كما تشير، سوف تجد Imregionalmax Maxima أكبر من أو يساوي جيرانهم. إذا كنت ترغب في استبعاد Maxima المجاورة بنفس القيمة (أي العثور على Maxima من وحيد بكسل)، فيمكنك استخدام bwconncomp. وظيفة. يجب أن يزيل ما يلي النقاط BW التي لديها أي جيران، تاركة فقط بكسل واحد:

CC = bwconncomp(BW);
for i = 1:CC.NumObjects,
  index = CC.PixelIdxList{i};
  if (numel(index) > 1),
    BW(index) = false;
  end
end

بدلا من ذلك، يمكنك استخدام nlfilter. وتوفير وظيفتك الخاصة لتطبيقها على كل حي.

هذه "ابحث عن ماكس صارم" ستحقق وظيفة ما إذا كان مركز الحي أكبر بكثير من جميع العناصر الأخرى في هذا الحي، وهو دائما 3 × 3 لهذا الغرض. لذلك:

I = imread('tire.tif');
BW = nlfilter(I, [3 3], @(x) all(x(5) > x([1:4 6:9])) );
imshow(BW)

أو، فقط استخدم ممتاز: extrema2.m.

بالإضافة إلى imdilate, ، والتي هي في Toolbox معالجة الصور، يمكنك أيضا استخدام ordfilt2.

ordfilt2 يفرز القيم في الأحياء المحلية ويحصل على قيمة n. فيمثال الرياضيات يوضح كيفية تطبيق مرشح أقصى.) يمكنك أيضا تطبيق مكتشف الذروة 3x3 ordfilt2 مع المنطق التالي:

  1. تحديد مجال 3x3 ذلك لا يشمل بكسل المركز (8 بكسل).

    >> mask = ones(3); mask(5) = 0 % 3x3 max
    mask =
         1     1     1
         1     0     1
         1     1     1
    
  2. حدد أكبر قيمة (8) مع ordfilt2.

    >> B = ordfilt2(A,8,mask)
    B =
         3     3     3     3     3     4     4     4
         3     5     5     5     4     4     4     4
         3     5     3     5     4     4     4     4
         3     5     5     5     4     6     6     6
         3     3     3     3     4     6     4     6
         1     1     1     1     4     6     6     6
    
  3. قارن هذا الإخراج بالقيمة المركزية لكل حي (فقط A):

    >> peaks = A > B
    peaks =
         0     0     0     0     0     0     0     0
         0     0     0     0     0     0     0     0
         0     0     1     0     0     0     0     0
         0     0     0     0     0     0     0     0
         0     0     0     0     0     0     1     0
         0     0     0     0     0     0     0     0
    
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top