How to find peaks in an image using matlab? - matlab

I am trying to outline all peaks in an image. The brightest lines are the peaks. I am using Matlab. This is what I have so far....
Any help will be greatly appreciated. Here is the image.
a = imread('duneLiDARs.png');
%b = imregionalmax(a);
%a = rgb2gray(a);
c = edge(a,'Sobel');
b = edge(a,'log',.0006);
d = edge(a,'log');
c= imfuse(a,d);
d= d-b;
subplot(2,2,1), imshow(a)
subplot(2,2,2), imshow(b)
subplot(2,2,3), imshow(c)
subplot(2,2,4), imshow(d)
%imshow(b);
%c = imadd(a,b);
%imshow(b);

you need to define what do you consider as peaks - what is the desired output for your image.
however, there are some general 2D peaks finding function, the following code uses FEX's extrema2:
% load image and remove extreme noise
im = medfilt2( im2double(imread('dune.png')));
% find peaks using extrema2
[XMAX,IMAX,XMIN,IMIN] = extrema2(im);
% eliminate peaks under minimum threshold
underThresh = XMAX < 0.15;
IMAX(underThresh) = [];
XMAX(underThresh) = [];
% plotting
subplot(121);
surf(im,'EdgeColor','none');
hold on;
[y,x] = ind2sub(size(im),IMAX);
scatter3(x,y,XMAX,'r','filled');
axis square
subplot(122);
imshow(im,[]);
hold on;
scatter(x,y,'r','filled');

Related

coloring 3D plots on MATLAB

I made two 3D plots on the same axis. now I desire to give them different colors for easy identification. How do I do this coloring? The MATLAB code is shown below.
tic
Nx = 50;
Ny = 50;
x = linspace(0,1,Nx);
y = linspace(0,0.5,Ny);
[X,Y] = meshgrid(x,y);
[M,N] = size(X);
for m=1:M
for n=1:N
%get x,y coordinate
x_mn = X(m,n);
y_mn = Y(m,n);
%%% X=D2 and Y=D1
%Check if x_mn and y_mn satisfy requirement
if(x_mn >= y_mn)
%evaluate function 1
Z(m,n) = (x_mn^2 - 2*x_mn*y_mn + y_mn^2);
Z_1(m,n) = (x_mn^2);
elseif(x_mn < y_mn)
%evaluate function 2
Z(m,n) = 0;
Z_1(m,n) = (x_mn^2);
%% Z(m,n) = 2*(2*x_mn*y_mn + y_mn - y_mn^2 - 2*x_mn);
else
Z(m,n) = 0;
end
end
end
%Plot the surface
figure
surf(X,Y,Z) %first plot
surfc(X,Y,Z)
hold on
surf(X,Y,Z_1) %second plot
xlabel('Dm');
ylabel('D');
zlabel('pR');
grid on
shading interp
toc
disp('DONE!')
How can I create two differently colored surfaces?
figure
surf(X,Y,Z) %first plot
surfc(X,Y,Z)
hold on
surf(X,Y,Z_1)
Your surfc() call actually overwrites your surf() call, is this intended?
As to your colour: the documentation is a marvellous thing:
surfc(X,Y,Z,C) additionally specifies the surface color.
In other words: just specify the colour as you want it. C needs to be a matrix of size(Z) with the desired colours, i.e. set all of them equal to create an monocoloured surface:
x = 1:100;
y = 1:100;
z = rand(100);
figure;
surfc(x,y,z,ones(size(z)))
hold on
surfc(x,y,z+6,ones(size(z))+4)
Results in (MATLAB R2007b, but the syntax is the same nowadays)

Ploting a simple binaryThresholding function graph in matlab as shown in image and figure

How can I correct this code, I have been trying to do it from 2 day but unable to do it still. Please help.
function BinaryThresholding(I)
%Reading minimum and maximum intensity values of Image I.
Min = min(I(:));
Max = max(I(:));
%Finding the middle value (thresholding) A.K.A m below.
m = (Min+Max)/2;
%For ploting the thresholding tranformation function we will also
%define X and Y (Ranges) parameters based upon min and max range and the
%process them according to our transformation algoritm as below.
x = (Min/Max):(Max/Max); %input range.
y = x;
% Now we will apply alogithm to threshold the threshold I at
% the middle intensity,thresholdingValue, of its dynamic
% range [minValue maxValue]. G is our processed image.
[Rows, Columns, Channels] = size(I);
%First we will check if the image is gray-scale and conver it if not.
if(Channels==3)
I = rgb2gray(I);
end
%Processing Image.
for i=1:1:Rows
for j=1:1:Columns
if( I(i,j)< m)
G(i,j) = 0;
else
G(i,j) = 1;
end
end
end
% Algorithm works great :D --> Testingw with : figure, imshow(G);
%Displaying image on a new figure window.
figure('Name','Image Thresholding','NumberTitle','on'),
subplot(1,3,1); imshow(I); title(['Input Image - Dynamic Range: [',num2str(Min),' ',num2str(Max),']']);
subplot(1,3,2); imshow(G); title(['Output Image - Threshold:' num2str(m)]);
subplot(1,3,3); plot(x,y); title('Plot of Thresholding Transformation Function');
%Let pixel info to be shown on the figure.
impixelinfo;
%Writing the image G as a .png file to the current folder (Drive D:/).
% imwrite(G,'D:/G.png');
endDesired output
Actual output
From the title of outputs I think you want to fix this line
subplot(1,3,3); plot(x,y); title('Plot of Thresholding Transformation Function');
which means only correct these couple of lines
x = (Min/Max):(Max/Max); %input range.
y = x;
that means: x is equally spaced from min to max... and Y is also equally spaced from min to max (as you can see from your actual output). Try something like:
x = (Min/Max):(Max/Max); %input range.
y = zeros(length(x));
for i=1:length(x)
if (x > m)
y(i) = 1;
end
end

How can I count no. of holes in an image and measure their diameter using matlab morphological operators?

So I have a graylevel image that demonstrates an electronic circuit card and I'm supposed to inspect the number of holes and the diameter of the holes, and I'm also allowed to use morphology operators in Matlab. The image is as follows:
I could wrote some codes that can count number of holes, but I don't know how to measure their diameters!
clear; close all; clc; warning off
im = imread('input\pcb.jpg');
im1 = im2bw(im,0);
% im1 = ~im2bw(im,0);
figure; imshow(im1);
strel1 = strel('disk',2);
im2 = imclose(im1,strel1);
figure; imshow(im2);
im3 = imfill(im2,'holes');
figure; imshow(im3);
im4 = im3 & ~im1;
figure; imshow(im4);
strel2 = strel('disk',3);
im5 = imopen(im4,strel2);
figure; imshow(im5);
[~,numCC] = bwlabel(im5);
fprintf('Number of holes equals:\t%d\n',numCC);
I appreciate any comments in advance!
Finally I just wrote some code, and it seems that it's working somehow perfect!
Actually the number of holes are counted as 4 and their diameters are not precise ones but they're approximated using built-in MATLAB functions. The thing is that one of the holes is not separated distinctly! and it makes the results estimated ...
clear; close all; clc; warning off
im = imread('input\pcb.jpg');
level = graythresh(im);
imBin = im2bw(im,level);
figure(1); imshow(imBin); title('Binarized Original Image');
imBinInv = ~imBin;
figure(2); imshow(imBinInv); title('Inverted Binarized Original Image');
imInvHolSep = imdilate(imerode(imBinInv,strel('disk',21)),strel('disk',23));
figure(3); imshow(imInvHolSep); title('Inverted Holes Separated');
imInHolSepBound = imInvHolSep & ~imerode(imInvHolSep,strel('disk',2));
figure(4); imshow(imInHolSepBound); title('Inverted Holes Boundaries');
imInvHolSepFill = imfill(imInHolSepBound,'holes');
figure(5); imshow(imInvHolSepFill); title('Inverted Holes Filled After Setting Boundaries');
imInvHolSepDist = imerode(imInvHolSepFill,strel('disk',1));
figure(6); imshow(imInvHolSepDist); title('Inverted Holes Eroded Just For The Case of Indistinct Hole');
imInvHolSepMinus = imInvHolSepDist & ~imBin;
figure(7); imshow(imInvHolSepMinus); title('Inverted Holes Minus The Inverted Binarized Image');
imInvHolSepSmooth = imdilate(imInvHolSepMinus,strel('disk',2));
figure(8); imshow(imInvHolSepSmooth); title('Final Approximated Inverted Holes Smoothed');
[~,numCC] = bwlabel(imInvHolSepSmooth);
fprintf('Number of holes equals:\t%d\n',numCC);
stats = regionprops(imInvHolSepSmooth);
centroid = zeros(length(stats),2);
area = zeros(length(stats),1);
for c1 = 1:length(stats)
centroid(c1,:) = stats(c1).Centroid;
area(c1) = stats(c1).Area;
fprintf('Diameter of the hole with centroid coordinates [%.2f, %.2f] is:\t%.2f\n',centroid(c1,1),centroid(c1,2),sqrt(area(c1)/pi));
end

Plotting a 3D graph of normalized prices in MatLab

I'm doing Gaussian processes and I calculated a regression per year from a given matrix where each row represents a year , so the code is:
M1 = MainMatrix; %This is the given Matrix
ker =#(x,y) exp(-1013*(x-y)'*(x-y));
[ns, ms] = size(M1);
for N = 1:ns
x = M1(N,:);
C = zeros(ms,ms);
for i = 1:ms
for j = 1:ms
C(i,j)= ker(x(i),x(j));
end
end
u = randn(ms,1);
[A,S, B] = svd(C);
z = A*sqrt(S)*u; % z = A S^.5 u
And I wanna plotting each regression in a Graph 3D as the below:
I know that plot is a ribbon, but I have not idea how can I do that
The desired plot can be generated without the use of ribbon. Just use a surf-plot for all the prices and a fill3-plot for the plane at z=0. The boundaries of the plane are calculated from the actual limits of the figure. Therefore we need to set the limits before plotting the plane. Then just some adjustments are needed to generate almost the same appearance.
Here is the code:
% generate some data
days = (1:100)';
price = days*[0.18,-0.08,0.07,-0.10,0.12,-0.08,0.05];
price = price + 0.5*randn(size(price));
years = 2002+(1:size(price,2));
% prepare plot
width = 0.6;
X = ones(size(price,1),1)*0.5;
X = [-X,X]*width;
figure; hold on;
% plot all 'ribbons'
for i = 1:size(price,2)
h = surf([days,days],X+years(i),[price(:,i),price(:,i)]);
set(h,'MeshStyle','column');
end
% set axis limits
set(gca,'ZLim',[-20,20]);
% plot plane at z=0
limx = get(gca,'XLim');
limy = get(gca,'YLim');
fill3(reshape([limx;limx],1,[]),[flip(limy),limy],zeros(1,4),'g','FaceAlpha',0.2)
% set labels
xlabel('Day of trading')
ylabel('Year')
zlabel('Normalized Price')
% tweak appearance
set(gca,'YTick',years);
set(gca,'YDir','reverse');
view([-38,50])
colormap jet;
grid on;
%box on;
This is the result:
That's a ribbon plot with an additional surface at y=0 which can be drawn with fill3

How to calculate 1D power spectrum from 2D noise power spectrum by radial averaging

guys I am trying to calculate 1D power spectrum from 2D FFT of the image. I did it with horizontal averaging but by looking at a graph it's not making me sense. Can you please suggest how to do radial averaging over 2D data set to reach 1D representation of noise power spectrum. Thank you
I will appreciate your help.
Here is my code
$
fid = fopen('C:\Users\3772khobrap\Desktop\project related\NPS_cal_data_UB\100000006.raw','r');
img = fread(fid,[512 512],'uint16');
roi = zeros(64);
avg = zeros(64);
Ux= 0.0075;% Pixel size
Uy = 0.0075;% Pixel size
%% This block of code is subdividing imaage into smaller ROI and averaging purpose
for r = 1:8
r_shift = (r-1)*64;
for c = 1:8
c_shift = (c-1)*64;
for i = 1:64
for j = 1:64
p = img(i+r_shift,j+c_shift);
roi(i,j) = p;
end
end
avg = avg+roi;
end
end
avg = avg./64;
%%Actual process of NPS calculation
scale = (Ux*Uy)./(64*64);%Scaling fator as per NPS calculation formula
f_x = 1/(2*Ux);%Nyquiest frequecy along x direction
f_y = 1/(2*Ux);%Nyquiest frequecy along y direction
FFT_2d = (fftshift(fft2(avg))).^2;% Power spectrum calculation
NPS = abs(FFT_2d).*scale; %% 2D NPS
f = linspace(-f_x,f_y,64);% x-axis vector for 1D NPS
X_img = linspace(-f_x,f_x,512);% X axis of NPS image
Y_img = linspace(-f_x,f_x,512);% Y axis of NPS image
figure(1)
subplot(2,2,1)
imagesc(X_img,Y_img,img)
colormap gray
xlabel('X [cm]'); ylabel('Y [cm]')
title('noise image')
subplot(2,2,2)
imagesc(f,f,log(NPS))
colormap gray
xlabel('frequency [cm^{-1}]'); ylabel('frequency [cm^{-1}]');
title('2D NPS')
subplot(2,2,3)
plot(f_p,NPS(:,32))
xlabel('frequency [cm^{-2}]'); ylabel('NPS [cm^{-2}]')
title('1D NPS from central slice')
subplot(2,2,4)
plot(f_p,mean(NPS,2))
xlabel('frequency [cm^{-2}]'); ylabel('NPS [cm^2]')
title('1D NPS along X direction')
You can program a function like this :
function profile = radialAverage(IMG, cx, cy, w)
% computes the radial average of the image IMG around the cx,cy point
% w is the vector of radii starting from zero
[a,b] = size(IMG);
[X, Y] = meshgrid( (1:a)-cx, (1:b)-cy);
R = sqrt(X.^2 + Y.^2);
profile = [];
for i = w % radius of the circle
mask = (i-1<R & R<i+1); % smooth 1 px around the radius
values = (1-abs(R(mask)-i)) .* double(IMG(mask)); % smooth based on distance to ring
% values = IMG(mask); % without smooth
profile(end+1) = mean( values(:) );
end
end