Extraction of Plankton using Segmentation with Matlab - matlab

I am trying to extract plankton from a scanned image.
I segmented the plankton using the technique I found here, http://www.mathworks.com/help/images/examples/detecting-a-cell-using-image-segmentation.html
The outline is not bad, however, now I am not sure how to extract the images so each individual plankton can be saved individually. I tried to use labels but there is a lot of noise and it labels every single spec. I am wondering if there is a better way to do this.
Here is my code:
I = imread('plankton_2.jpg');
figure, imshow(I), title('original image');
[~, threshold] = edge(I, 'sobel');
fudgeFactor = .5;
BWs = edge(I,'sobel', threshold * fudgeFactor);
figure, imshow(BWs), title('binary gradient mask');
se90 = strel('line', 3, 90);
se0 = strel('line', 3, 0);
BWsdil = imdilate(BWs, [se90 se0]);
figure, imshow(BWsdil), title('dilated gradient mask');
BWdfill = imfill(BWsdil, 'holes');
figure, imshow(BWdfill);
title('binary image with filled holes');
BWnobord = imclearborder(BWdfill,1);
figure, imshow(BWnobord), title('cleared border image');
seD = strel('diamond',1);
BWfinal = imerode(BWnobord,seD);
BWfinal = imerode(BWfinal,seD);
figure, imshow(BWfinal), title('segmented image');
BWoutline = bwperim(BWfinal);
Segout = I;
Segout(BWoutline) = 0;
figure, imshow(Segout), title('outlined original image');
label = bwlabel(BWfinal);
max(max(label))
for j = 1:max(max(label))
[row, col] = find(label == j);
len = max(row) - min(row)+2;
breadth = max(col)-min(col) +2;
target = uint8(zeros([len breadth]));
sy = min(col)-1;
sx = min(row)-1;
for i = 1:size(row,1)
x = row(i,1)-sx;
y = col(i,1) - sy;
target(x,y)=I(row(i,1),col(i,1));
end
mytitle =strcat('Object Number:',num2str(j));
figure, imshow(target);mytitle;
end
for j = 1:max(max(label))
[row, col] = find(label == j);
len = max(row) - min(row)+2;
breadth = max(col)-min(col) +2;
target = uint8(zeros([len breadth]));
sy = min(col)-1;
sx = min(row)-1;
for i = 1:size(row,1)
x = row(i,1)-sx;
y = col(i,1) - sy;
target(x,y)=I(row(i,1),col(i,1));
end
mytitle =strcat('Object Number:',num2str(j));
figure, imshow(target);mytitle;
end

You should use the regionprops function to filter the detected objects by size and/or shape characteristics.

Related

how to find the corners of rotated object in matlab?

I want to find the corners of objects.
I tried the following code:
Vstats = regionprops(BW2,'Centroid','MajorAxisLength','MinorAxisLength',...
'Orientation');
u = [Vstats.Centroid];
VcX = u(1:2:end);
VcY = u(2:2:end);
[VcY id] = sort(VcY); % sorting regions by vertical position
VcX = VcX(id);
Vstats = Vstats(id); % permute according sort
Bv = Bv(id);
Vori = [Vstats.Orientation];
VRmaj = [Vstats.MajorAxisLength]/2;
VRmin = [Vstats.MinorAxisLength]/2;
% find corners of vertebrae
figure,imshow(BW2)
hold on
% C = corner(VER);
% plot(C(:,1), C(:,2), 'or');
C = cell(size(Bv));
Anterior = zeros(2*length(C),2);
Posterior = zeros(2*length(C),2);
for i = 1:length(C) % for each region
cx = VcX(i); % centroid coordinates
cy = VcY(i);
bx = Bv{i}(:,2); % edge points coordinates
by = Bv{i}(:,1);
ux = bx-cx; % move to the origin
uy = by-cy;
[t, r] = cart2pol(ux,uy); % translate in polar coodinates
t = t - deg2rad(Vori(i)); % unrotate
for k = 1:4 % find corners (look each quadrant)
fi = t( (t>=(k-3)*pi/2) & (t<=(k-2)*pi/2) );
ri = r( (t>=(k-3)*pi/2) & (t<=(k-2)*pi/2) );
[rp, ip] = max(ri); % find farthest point
tc(k) = fi(ip); % save coordinates
rc(k) = rp;
end
[xc,yc] = pol2cart(tc+1*deg2rad(Vori(i)) ,rc); % de-rotate, translate in cartesian
C{i}(:,1) = xc + cx; % return to previous place
C{i}(:,2) = yc + cy;
plot(C{i}([1,4],1),C{i}([1,4],2),'or',C{i}([2,3],1),C{i}([2,3],2),'og')
% save coordinates :
Anterior([2*i-1,2*i],:) = [C{i}([1,4],1), C{i}([1,4],2)];
Posterior([2*i-1,2*i],:) = [C{i}([2,3],1), C{i}([2,3],2)];
end
My input image is :
I got the following output image
The bottommost object in the image is not detected properly. How can I correct the code? It fails to work for a rotated image.
You can get all the points from the image, and use kmeans clustering and partition the points into 8 groups. Once partition is done, you have the points in and and you can pick what ever the points you want.
rgbImage = imread('your image') ;
%% crop out the unwanted white background from the image
grayImage = min(rgbImage, [], 3);
binaryImage = grayImage < 200;
binaryImage = bwareafilt(binaryImage, 1);
[rows, columns] = find(binaryImage);
row1 = min(rows);
row2 = max(rows);
col1 = min(columns);
col2 = max(columns);
% Crop
croppedImage = rgbImage(row1:row2, col1:col2, :);
I = rgb2gray(croppedImage) ;
%% Get the white regions
[y,x,val] = find(I) ;
%5 use kmeans clustering
[idx,C] = kmeans([x,y],8) ;
%%
figure
imshow(I) ;
hold on
for i = 1:8
xi = x(idx==i) ; yi = y(idx==i) ;
id1=convhull(xi,yi) ;
coor = [xi(id1) yi(id1)] ;
[id,c] = kmeans(coor,4) ;
plot(coor(:,1),coor(:,2),'r','linewidth',3) ;
plot(c(:,1),c(:,2),'*b')
end
Now we are able to capture the regions..the boundary/convex hull points are in hand. You can do what ever math you want with the points.
Did you solve the problem? I Looked into it and it seems that the rotation given by 'regionprops' seems to be off. To fix that I've prepared a quick solution: I've dilated the image to close the gaps, found 4 most distant peaks of each spine, and then validated if a peak is on the left, or on the right of the centerline (that I have obtained by extrapolating form sorted centroids). This method seems to work for this particular problem.
BW2 = rgb2gray(Image);
BW2 = imbinarize(BW2);
%dilate and erode will help to remove extra features of the vertebra
se = strel('disk',4,4);
BW2_dilate = imdilate(BW2,se);
BW2_erode = imerode(BW2_dilate,se);
sb = bwboundaries(BW2_erode);
figure
imshow(BW2)
hold on
centerLine = [];
corners = [];
for bone = 1:length(sb)
x0 = sb{bone}(:,2) - mean(sb{bone}(:,2));
y0 = sb{bone}(:,1) - mean(sb{bone}(:,1));
%save the position of the centroid
centerLine = [centerLine; [mean(sb{bone}(:,1)) mean(sb{bone}(:,2))]];
[th0,rho0] = cart2pol(x0,y0);
%make sure that the indexing starts at the dip, not at the corner
lowest_val = find(rho0==min(rho0));
rho1 = [rho0(lowest_val:end); rho0(1:lowest_val-1)];
th00 = [th0(lowest_val:end); th0(1:lowest_val-1)];
y1 = [y0(lowest_val:end); y0(1:lowest_val-1)];
x1 = [x0(lowest_val:end); x0(1:lowest_val-1)];
%detect corners, using smooth data to remove noise
[pks,locs] = findpeaks(smooth(rho1));
[pksS,idS] = sort(pks,'descend');
%4 most pronounced peaks are where the corners are
edgesFndCx = x1(locs(idS(1:4)));
edgesFndCy = y1(locs(idS(1:4)));
edgesFndCx = edgesFndCx + mean(sb{bone}(:,2));
edgesFndCy = edgesFndCy + mean(sb{bone}(:,1));
corners{bone} = [edgesFndCy edgesFndCx];
end
[~,idCL] = sort(centerLine(:,1),'descend');
centerLine = centerLine(idCL,:);
%extrapolate the spine centerline
yDatExt= 1:size(BW2_erode,1);
extrpLine = interp1(centerLine(:,1),centerLine(:,2),yDatExt,'spline','extrap');
plot(centerLine(:,2),centerLine(:,1),'r')
plot(extrpLine,yDatExt,'r')
%find edges to the left, and to the right of the centerline
for bone = 1:length(corners)
x0 = corners{bone}(:,2);
y0 = corners{bone}(:,1);
for crn = 1:4
xCompare = extrpLine(y0(crn));
if x0(crn) < xCompare
plot(x0(crn),y0(crn),'go','LineWidth',2)
else
plot(x0(crn),y0(crn),'ro','LineWidth',2)
end
end
end
Solution

Matlab Neutron image reconstructions

I am trying to reconstruct an image using the projections from the Neutron image scanner. I am using the following code. I am not able to obtain a meaningful reconstructed image.
Can anybody advise me on where I am going wrong.
much appreciated,
Vani
filename = strcat(' Z:\NIST_Data\2016\SEPT\example reconstructed\carboxylic\carboxylic reconstructed part 3\Coral\',srcFiles(i).name);
I=imread(filename);
P = im2double(I);
if i == 1
array3d = P;
else
array3d = cat(3, array3d, P);
end
end
num = size(array3d,3);
for p = 1:num
PR = double(squeeze(array3d(p,:,:)));
[L,C]=size(PR);
w = [-pi : (2*pi)/L : pi-(2*pi)/L];
Filt = abs(sin(w));
Filt = Filt(1:463);
for i = 1:C,
IMG = fft(PR(:,i));
end
FiltIMG = IMG*Filt; %FiltIMG = filter (b, a, IMG);
% Remove any remaining imaginary parts
FIL = real(FiltIMG);
% filter the projections
%filtPR = projfilter(PR);
%filtPR = filterplus(PR);
filtPR = FIL;
THETA=0:180;
% figure out how big our picture is going to be.
n = size(filtPR,1);
sideSize = n;
% convert THETA to radians
th = (pi/180)*THETA;
% set up the image
m = length(THETA);
BPI = zeros(sideSize,sideSize);
% find the middle index of the projections
midindex = (n+1)/2;
% set up x and y matrices
x = 1:sideSize;
y = 1:sideSize;
[X,Y] = meshgrid(x,y);
xpr = X - (sideSize+1)/2;
ypr = Y - (sideSize+1)/2;
% loop over each projection
%figure
%colormap(jet)
%M = moviein(m);
for i = 1:m
tic
disp(['On angle ', num2str(THETA(i))]);
% figure out which projections to add to which spots
filtIndex = round(midindex + xpr*sin(th(i)) - ypr*cos(th(i)));
% if we are "in bounds" then add the point
BPIa = zeros(sideSize,sideSize);
spota = find((filtIndex > 0) & (filtIndex <= n));
newfiltIndex = filtIndex(spota);
BPIa(spota) = filtPR(newfiltIndex(:),i);
%keyboard
BPI = BPI + BPIa;
toc
%imagesc(BPI)
%M(:,i) = getframe;
%figure(2)
%plot(filtPR(:,i));
%keyboard
end
BPI = BPI./m;
h=figure
imagesc(BPI)
saveas(h,sprintf('filtsli-FIG%d.tif',p));end

How to use the new functions of PDE toolbox in image processing (Matlab R2015a)

I want to use the line new command of PDE toolbox as Matlab R2015 to restore a noisy image with gaussian noise.
The PDE is:
∇.(( ∇u)/(√(1+|∇u|2))) +(f2)/(u2) = 1 in Ω (∂u)/(∂n)=0 in ∂Ω
Where f is the noisy image and u the restored image.
I tried the following code:
clear
close all
clc
img = 'AA.jpg';
mInputImage = double(imread(img));
mInputImage = rgb2gray(mInputImage);
[numRows, numCols] = size(mInputImage);
Var = 0.04;
Mean = 0;
mInputImageNoisy = imnoise((mInputImage(:,:,1)),'gaussian',Mean, Var);
% reshape the input and noisy images to vectors
mInputImageVector = reshape(mInputImage,numRows*numCols,1);
mInputImageNoisyVector = reshape(mInputImageNoisy,numRows*numCols,1);
Residu1 = norm(mInputImageVector-mInputImageNoisyVector)/norm(mInputImageVector)
RegularisationCoefficient = 0.7*ones((numRows-1)*(numCols-1),1);
mOutputImageVector = mInputImageNoisyVector;
%a = (mInputImageNoisyVector.^2) ./ mOutputImageVector.^3;
f = 1;
rtol = 1e-1;
c = '1./sqrt(1+ux.^2+uy.^2)';
% Create a PDE Model with a single dependent variable
numberOfPDE = 1;
pdem = createpde(numberOfPDE);
g = #squareg;
geometryFromEdges(pdem,g);
% Plot the geometry and display the edge labels for use in the boundary
% condition definition.
figure;
pdegplot(pdem, 'edgeLabels', 'on');
%axis([0 numRows 0 numCols]);
axis([-2 2 -2 2]);
title 'Geometry With Edge Labels Displayed'
b2 = applyBoundaryCondition(pdem,'Edge',[1 2 3 4], 'u', 0);
[p,e,t] = poimesh(g,numRows, numCols);
numCols
pdemesh(p,e,t);
axis equal
for iter = 1: numRows*numRows,
mOutputImageVector(iter) = pdenonlin(pdem,c,...
(mInputImageNoisyVector(iter).^2) ./ mOutputImageVector(iter).^3,...
f,'tol',rtol);
SaveImageVector(iter) = mOutputImageVector;
end
mOutputImage = reshape(SaveImageVector,numRows,numRows);
mOutputImage = uint8(mOutputImage);
figure()
imshow(mOutputImage)

generate a matrix image after having all the balck pixel's coordinates with MatLab

I have an Image, converted into binary, i got all the black pixel's coordinates.
The 'matrix' contains the x and y coordinates arranged by columns.
Now i Need to make a Simulation, to see if my Programme works.
I have to generate an Matrix Image with my results.
im=imread('square.jpg');
imshow(im); c=im2bw(im); figure; imshow(c);
dim = size(c) % size of the image
x = [];
y = [];
xdif = [];
newx = [];
matrix = [];
for i = 1:dim(1)
for j = 1:dim(2)
if c(i,j)==0;
x = [x i];
y = [y j];
end
end
end
% show black pixel's coordinates
p = [x;y];
%number of pixels
nr = length(x)
dimp = size(p);
xval = p(1,:);
yval = p(2,:);
j=1;
i=1;
for z = 1:dimp(2)-1
xdif = xval(z+1)-xval(z);
ff=find(xdif > 0);
if ff == 1
i = 1;
else
i=i+1;
end
newx(i,j)= xval(z);
newy(i,j)= yval(z);
if ff == 1
j= j+1;
end
end
xsize = size(newx);
ysize = size(newy);
matrix_size = xsize(2)+ysize(2)
xinc = 1;
yinc = 1;
x=1;
for ct = 1:1:matrix_size/2
x;
matrix(:,x) = newx(:,xinc);
matrix(:,x+1) = newy(:,yinc);
matrix;
xinc = xinc+1;
yinc = yinc+1;
x=x+3;
end
matrix
this is my Programme, now i need to make a simulation, by generating an image with my coordinates.
how can i do that?
thank's

plotting optical flow in matlab using vision tool box

I am trying to plot optical flow using quiver. I can plot the optical flow lines but not the arrows. This code is similar examples on Matlab tutorials.
Following is the code
function display_optical_flow (video_file_name)
vid_reader_obj = vision.VideoFileReader(video_file_name, 'VideoOutputDataType','single');
optical_flow_calculator = vision.OpticalFlow('Method','Lucas- Kanade','TemporalGradientFilter','Derivative of Gaussian', 'MotionVectorImageOutputPort', ...
true, 'OutputValue', 'Horizontal and vertical components in complex form', 'NoiseReductionThreshold',0.02);
screen_size = get(0, 'ScreenSize');
player_window_pos = [20 screen_size(4)-300 400 400];
video_display_originalVideo = vision.VideoPlayer('Name', 'Original Input Video', 'Position', player_window_pos);
player_window_pos(1) = player_window_pos(1) + 500;
video_display_opticalFlow = vision.VideoPlayer('Name','Optical Flow Vector', 'Position',player_window_pos);
player_window_pos(1) = player_window_pos(1) + 500;
video_display_of_image = vision.VideoPlayer('Name','Optical Flow image', 'Position',player_window_pos);
shape_inserter_line = vision.ShapeInserter('Shape','Lines', 'BorderColor','Custom','CustomBorderColor', [255 255 0]);
motion_vector_gain=20;
decimFactorRow = 5;
decimFactorCol = 5;
borderOffset = 5;
flag_first_time = true;
while ~isDone(vid_reader_obj)
cur_rgb_frame = step(vid_reader_obj);
cur_gray_frame = rgb2gray(cur_rgb_frame);
[optical_flow_vector IMV]= step(optical_flow_calculator, cur_gray_frame);
%magnitude of optical flow vectors by dot product
%of_magnitude= optical_flow_vector .* conj(optical_flow_vector);
if true == flag_first_time
flag_first_time = false;
[row col] = size(optical_flow_vector);
rowV = borderOffset:decimFactorRow:(row-borderOffset);
colV = borderOffset:decimFactorCol:(col-borderOffset);
[Y X] = meshgrid(rowV, colV);
end
lines =videooptflowlines(optical_flow_vector, 20);
if ~isempty(lines)
motion_vectors = step(shape_inserter_line, cur_rgb_frame, lines);
step(video_display_opticalFlow, motion_vectors);
end
%Display
step(video_display_originalVideo, cur_rgb_frame);
step(video_display_of_image, IMV);
%
[Xsize Ysize] = meshgrid(1:size(cur_gray_frame, 2), 1:size(cur_gray_frame, 1));
imshow(cur_gray_frame); hold on;
Real_part = real(optical_flow_vector(:));
Imag_part = imag(optical_flow_vector(:));
quiver(Xsize(:), Ysize(:), Real_part(:), Imag_part(:), 0);
pause;
end
release (video_display_opticalFlow);
release (video_display_originalVideo);
release (vid_reader_obj);
This do not show the arrow as I expect to see on each frame image by quiver.
What wrong I should do to correct the code?
nitin