From: Rahul on
ImageAnalyst <imageanalyst(a)mailinator.com> wrote in news:3e5d76f2-24fb-
48c3-a870-2df873fbf78e(a)o35g2000vbi.googlegroups.com:

> What do you consider the "peak"? Just the apex, or the complete peak
> out to the background level of 1? Here is some code to calculate it
> both ways. It will work for your simple case but probably isn't
> robust for real world cases with complicated peaks and noise:


> I have no idea how your data look like. Usually experimental data will
>contains noise, and it will introduce many maxima that you need to filter
>out after detection based on the expected amplitude of the peak.

Thanks. I hadn't realized the complications. Well, let me try to explain
better what my original problem was. I have stm scans that are (x,y,z)
files. If I do a representation they look like the photo here:

http://dl.getdropbox.com/u/118481/peaks.jpg

Let's assume the colors are proportional to the z values. So the problem is
to detect the heights of each of the "peaks". I'd consider the highest
point in each "peak region" as the peak.

Like I said I should probably do some noise filtering before to prevent
each small blip from registering as a peak.

Of course, I'm pretty clueless to image processing so if there are any tips
I'd greatly appreciate them!

Is Bruno's approach the right one? Or the code by ImageAnalyst? Maybe both
work!



--
Rahul
From: ImageAnalyst on
On Sep 28, 1:16 pm, Rahul <nos...(a)nospam.invalid> wrote:
[snip]
>
> Is Bruno's approach the right one? Or the code by ImageAnalyst? Maybe both
> work!
>
> --
> Rahul
-------------------------------------------------------------------------------------------------------
Why don't you just try something like the following:
(Be sure to fix any line breaks introduced by the newsreader)

clc;
close all;
workspace;
originalImage = imread('stm_peaks.jpg');
subplot(3,3,1);
imshow(originalImage);
set(gcf, 'Position', get(0, 'ScreenSize')); % Maximize figure.
monoImage = rgb2gray(originalImage);
% Smooth the image a bit.
monoImage = medfilt2(monoImage, [3 3]);
subplot(3,3,2);
imshow(monoImage);
thresholdValue = 112;
binaryImage = monoImage > thresholdValue;
subplot(3,3,3);
imshow(binaryImage, []);
% Label the image
labeledImage = bwlabel(binaryImage, 8); % Label each blob so we
can make measurements of it
coloredLabels = label2rgb (labeledImage, 'hsv', 'k', 'shuffle'); %
pseudo random color labels

subplot(3, 3, 4); imagesc(labeledImage); title('Labeled Image, from
bwlabel()'); axis square;
subplot(3, 3, 5); imagesc(coloredLabels); title('Pseudo colored
labels, from label2rgb()'); axis square;

% Get all the blob properties. Can only pass in originalImage in
version R2008a and later.
blobMeasurements = regionprops(labeledImage, monoImage, 'all');
numberOfBlobs = size(blobMeasurements, 1);

fprintf(1,'Blob # Mean Intensity Max Intensity\n');
for k = 1 : numberOfBlobs % Loop through all blobs.
% Find the mean of each blob.
thisBlobsPixels = blobMeasurements(k).PixelIdxList; % Get list of
pixels in current blob.
meanGL = mean(monoImage(thisBlobsPixels)); % Find mean intensity
(in original image!)
maxGL = max(monoImage(thisBlobsPixels)); % Find max intensity (in
original image!)
fprintf(1,'#%d %18.1f %13.1f \n', k, meanGL, maxGL);
end
uiwait(msgbox('Check out the command window for measurements'));

I used the median filter - you can try other noise reduction methods
if you like. I think this might be sufficiently accurate for your
needs, but correct me if I'm wrong.
-ImageAnalyst



From: Rahul on
ImageAnalyst <imageanalyst(a)mailinator.com> wrote in news:b5284157-7b36-
42e1-86f4-425fc6c9352b(a)d23g2000vbm.googlegroups.com:

> clc;
> close all;
> workspace;
> originalImage = imread('stm_peaks.jpg');
>

Thanks! I am going to try that now.

Actually, I do have the numeric data from which the jpg image was made.
Would it be better to process that? Might preclude artifacts and noise from
the lossy transformation of raw numbers to the jpg.

The raw data is just (x,y,z) values. I had given the jpeg in my last post
just becasue it made the issues clearer.

--
Rahul
From: ImageAnalyst on
On Sep 28, 2:27 pm, Rahul <nos...(a)nospam.invalid> wrote:
> ImageAnalyst <imageanal...(a)mailinator.com> wrote in news:b5284157-7b36-
> 42e1-86f4-425fc6c93...(a)d23g2000vbm.googlegroups.com:
>
> > clc;
> > close all;
> > workspace;
> > originalImage = imread('stm_peaks.jpg');
>
> Thanks! I am going to try that now.
>
> Actually, I do have the numeric data from which the jpg image was made.
> Would it be better to process that? Might preclude artifacts and noise from
> the lossy transformation of raw numbers to the jpg.
>
> The raw data is just (x,y,z) values. I had given the jpeg in my last post
> just becasue it made the issues clearer.
>
> --
> Rahul

----------------------------------------------------------
Of course using the original image data would be better than using
some jpg with annotation on it and a colormap applied.
Hopefully by "z" you mean intensity rather than a coordinate, unless
your intensity actually corresponds to a height (I'm not really
familiar with stm images).
Regards,
ImageAnalyst
From: Bruno Luong on
>
> ----------------------------------------------------------
> Of course using the original image data would be better than using
> some jpg with annotation on it and a colormap applied.
> Hopefully by "z" you mean intensity rather than a coordinate, unless
> your intensity actually corresponds to a height (I'm not really
> familiar with stm images).

No, as I understand he OP has 3D array I(x,y,z) with

x=1:nx;
y=1:ny;
z=1:nz;

and he wanted to find the local maxima. The same technique for 2D should work for 3D as well, filtering then detect local maxima.

Bruno