bubble size distribution in bubble column using image processing technique - matlab

I have a video from which I have extracted several frames. I need to analyse them to get the total number and the sizes of the bubbles. The program I have so far can identify a single bubble in the image but has trouble to determine multiple bubbles.
code:
clc;
clear all;
close all;
% ----------------- Select the image -------------------------------
% Double click the image fle to be selected
[FileName,PathName] = uigetfile('*.png','Select the image');
file = fullfile(PathName,FileName);
img=imread(file); % Reads the image
rgb = imcrop(img);
figure,imshow(rgb)
d = imdistline; %to find the appropriate radius range
delete(d);
gray_image = rgb2gray(rgb);
figure, imshow(gray_image);
impixelinfo
[centers, radii] = imfindcircles(rgb,[3 10],'ObjectPolarity','dark')
hold on
[centers, radii] = imfindcircles(rgb,[3 10],'ObjectPolarity','dark', ...
'Sensitivity',0.96)
hold off
figure, imshow(rgb);
h = viscircles(centers,radii);
[centers, radii] = imfindcircles(rgb,[3 10],'ObjectPolarity','dark', ...
'Sensitivity',0.96);
length(centers)
delete(h); % Delete previously drawn circles
h = viscircles(centers,radii);
%second method(2 stage )
[centers, radii] = imfindcircles(rgb,[3 10], 'ObjectPolarity','dark', ...
'Sensitivity',0.96,'Method','twostage');
delete(h);
h = viscircles(centers,radii);
The Frame Given As Input To Code
Output i am getting
I need help to get the correct number of bubbles in the image.
since in output screenshot there is some cluster where algo fails to get the correct number of bubbles.

Related

moving shadow elimination in video

I wish to remove moving shadow in video. I followed the steps as mentioned in this article, but getting the same result before and after applying threshold operation on the swt output. didn't get the expected output...Can anyone suggest me what I am doing wrong?
Steps to do for shadow removal:
(i) Read the video.
(ii) After the color conversion split the h s v components
(iii) applying the stationary wavelet transform on on s and v components of frame
(iv) calculate skew value for respective swt output of s and v component
(v) Assign the value 1 and 0 to 's and v' pixel if swt of v is greater than skewness value of v likewise for s too.
(vi) Do inverse swt over the s and v
(vii)Combine the h s and v
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures.
clear; % Erase all existing variables.
workspace; % Make sure the workspace panel is showing.
fontSize = 22;
movieFullFileName = fullfile('cam4v.mp4');
% Check to see that it exists.
if ~exist(movieFullFileName, 'file')
strErrorMessage = sprintf('File not found:\n%s\nYou can choose a new one,
or cancel', movieFullFileName);
response = questdlg(strErrorMessage, 'File not found', 'OK - choose a new
movie.', 'Cancel', 'OK - choose a new movie.');
if strcmpi(response, 'OK - choose a new movie.')
[baseFileName, folderName, FilterIndex] = uigetfile('*.avi');
if ~isequal(baseFileName, 0)
movieFullFileName = fullfile(folderName, baseFileName);
else
return;
end
else
return;
end
end
try
videoObject = VideoReader(movieFullFileName);
% Determine how many frames there are.
numberOfFrames = videoObject.NumberOfFrames;
vidHeight = videoObject.Height;
vidWidth = videoObject.Width;
numberOfFramesWritten = 0;
% Prepare a figure to show the images in the upper half of the screen.
figure;
% screenSize = get(0, 'ScreenSize');
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Ask user if they want to write the individual frames out to disk.
promptMessage = sprintf('Do you want to save the individual frames out to
individual disk files?');
button = questdlg(promptMessage, 'Save individual frames?', 'Yes', 'No',
'Yes');
if strcmp(button, 'Yes')
writeToDisk = true;
% Extract out the various parts of the filename.
[folder, baseFileName, extentions] = fileparts(movieFullFileName);
% Make up a special new output subfolder for all the separate
% movie frames that we're going to extract and save to disk.
% (Don't worry - windows can handle forward slashes in the folder
name.)
folder = pwd; % Make it a subfolder of the folder where this m-file
lives.
outputFolder = sprintf('%s/Movie Frames from %s', folder,
baseFileName);
% Create the folder if it doesn't exist already.
if ~exist(outputFolder, 'dir')
mkdir(outputFolder);
end
else
writeToDisk = false;
end
% Loop through the movie, writing all frames out.
% Each frame will be in a separate file with unique name.
for frame = 1 : numberOfFrames
% Extract the frame from the movie structure.
thisFrame = read(videoObject, frame);
% Display it
hImage = subplot(2, 2, 1);
image(thisFrame);
caption = sprintf('Frame %4d of %d.', frame, numberOfFrames);
title(caption, 'FontSize', fontSize);
drawnow; % Force it to refresh the window.
% Write the image array to the output file, if requested.
if writeToDisk
% Construct an output image file name.
outputBaseFileName = sprintf('Frame %4.4d.png', frame);
outputFullFileName = fullfile(outputFolder, outputBaseFileName);
% Stamp the name and frame number onto the image.
% At this point it's just going into the overlay,not actually
getting written into the pixel values.
text(5, 15, outputBaseFileName, 'FontSize', 20);
% Extract the image with the text "burned into" it.
frameWithText = getframe(gca);
% frameWithText.cdata is the image with the text
% actually written into the pixel values.
% Write it out to disk.
imwrite(frameWithText.cdata, outputFullFileName, 'png');
end
if frame == 1
xlabel('Frame Number');
ylabel('Gray Level');
% Get size data later for preallocation if we read
% the movie back in from disk.
[rows, columns, numberOfColorChannels] = size(thisFrame);
end
% Update user with the progress. Display in the command window.
if writeToDisk
progressIndication = sprintf('Wrote frame %4d of %d.', frame,
numberOfFrames);
else
progressIndication = sprintf('Processed frame %4d of %d.', frame,
numberOfFrames);
end
disp(progressIndication);
% Increment frame count (should eventually = numberOfFrames
% unless an error happens).
numberOfFramesWritten = numberOfFramesWritten + 1;
% Now let's do the differencing
alpha = 0.5;
if frame == 1
Background = thisFrame;
else
% Change background slightly at each frame
% Background(t+1)=(1-alpha)*I+alpha*Background
Background = (1-alpha)* thisFrame + alpha * Background;
end
% Display the changing/adapting background.
subplot(2, 2, 3);
imshow(Background);
title('Adaptive Background', 'FontSize', fontSize);
% Do color conversion from rgb to hsv
x=rgb2hsv(thisFrame);
y=rgb2hsv(Background);
% Split the hsv component to h,s,v value
Hx = x(:,:,1); Hy = y(:,:,1);
Sx = x(:,:,2); Sy = y(:,:,2);
Vx = x(:,:,3); Vy = y(:,:,3);
%Find the absolute diffrence between h s v value of current and
previous frame
dh=(abs(double(Hx) - double(Hy)));
ds1=(abs(double(Sx) - double(Sy)));
dv1=(abs(double(Vx) - double(Vy)));
%Perform the swt2 transformation on difference of s and v value
[as,hs,vs,ds] = swt2(ds1,1,'haar');
[av,hv,vv,dv] = swt2(dv1,1,'haar');
%Compute the skewness value of 'swt of v'
sav=skewness(av(:));
shv=skewness(hv(:));
svv=skewness(vv(:));
sdv=skewness(dv(:));
%Compute the skewness value of 'swt of s'
sas=skewness(as(:));
shs=skewness(hs(:));
svs=skewness(vs(:));
sds=skewness(ds(:));
% Do the shadow detection based on the output of swt and skew of 'v'
value
% Compare swt v output with its skew value if the av >=sav then av is
assigned to one else it becomes zero.This operation continues till variable i
b=(av>=sav); f= (as>=sas);
c=(hv>=shv); g=(hs>=shs);
d=(vv>=svv); h=(vs>=svs);
e=(dv>=sdv); i=(ds>=sds);
% Remove the shadows based on 'and operation
j=(b&f); l=(d&h);
k=(c&g); m=(e&i);
% Do inverse swt operation
recv = iswt2(b,c,d,e,'haar');
recs= iswt2(j,k,l,m,'haar');
%Combine the value of h,s and v
de_shadow=cat(3,dh,recs,recv);
rgb=hsv2rgb(de_shadow);
% Plot the image.
subplot(2, 2, 4);
imshow(rgb);
title('output Image', 'FontSize', fontSize);
end
% Alert user that we're done.
if writeToDisk
finishedMessage = sprintf('Done! It wrote %d frames to
folder\n"%s"', numberOfFramesWritten, outputFolder);
else
finishedMessage = sprintf('Done! It processed %d frames of\n"%s"',
numberOfFramesWritten, movieFullFileName);
end
disp(finishedMessage); % Write to command window.
uiwait(msgbox(finishedMessage)); % Also pop up a message box.
% Exit if they didn't write any individual frames out to disk.
if ~writeToDisk
return;
end
% Ask user if they want to read the individual frames from the disk,
% that they just wrote out, back into a movie and display it.
promptMessage = sprintf('Do you want to recall the individualframes\nback
from disk into a movie?\n(This will take several seconds.)');
button = questdlg(promptMessage, 'Recall Movie?', 'Yes', 'No', 'Yes');
if strcmp(button, 'No')
return;
end
% Create a VideoWriter object to write the video out to a new, different
file.
writerObj = VideoWriter('Newcam4v.mp4');
open(writerObj);
% Read the frames back in from disk, and convert them to a movie.
% Preallocate recalledMovie, which will be an array of structures.
% First get a cell array with all the frames.
allTheFrames = cell(numberOfFrames,1);
allTheFrames(:) = {zeros(vidHeight, vidWidth, 3, 'uint8')};
% Next get a cell array with all the colormaps.
allTheColorMaps = cell(numberOfFrames,1);
allTheColorMaps(:) = {zeros(256, 3)};
% Now combine these to make the array of structures.
recalledMovie = struct('cdata', allTheFrames, 'colormap',allTheColorMaps)
for frame = 1 : numberOfFrames
% Construct an output image file name.
outputBaseFileName = sprintf('Frame %4.4d.png', frame);
outputFullFileName = fullfile(outputFolder, outputBaseFileName);
% Read the image in from disk.
thisFrame = imread(outputFullFileName);
% Convert the image into a "movie frame" structure.
thisFrame=imresize(thisFrame,[452, 231]);
recalledMovie(frame) = im2frame(thisFrame);
% Write this frame out to a new video file.
writeVideo(writerObj, thisFrame);
end
close(writerObj);
% Get rid of old image and plot.
delete(hImage);
% Create new axes for our movie.
subplot(1, 3, 2);
axis off; % Turn off axes numbers.
title('Movie recalled from disk', 'FontSize', fontSize);
% Play the movie in the axes.
movie(recalledMovie);
% Note: if you want to display graphics or text in the overlay
% as the movie plays back then you need to do it like I did at first
% (at the top of this file where you extract and imshow a frame at a
time.)
msgbox('Done this experiment!');
catch ME
% Some error happened if you get here.
strErrorMessage = sprintf('Error extracting movie frames
from:\n\n%s\n\nError: %s\n\n)', movieFullFileName, ME.message);
uiwait(msgbox(strErrorMessage));
end

How to find peaks in an image using 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');

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

Can anyone suggest how do I obtain all the values of the variable bc?

The variable bc is getting overwritten and I am Unable to plot all the values of the variable from the start.
I tried exporting the variable to a csv file but that didn't work.
I'm trying to detect a red, green, blue object and plot its coordinates versus time in matlab.
a = imaqhwinfo;
[camera_name, camera_id, format] = getCameraInfo(a);
% Capture the video frames using the videoinput function
% You have to replace the resolution & your installed adaptor name.
vid = videoinput(camera_name, camera_id, format);
% Set the properties of the video object
set(vid, 'FramesPerTrigger', Inf);
set(vid, 'ReturnedColorspace', 'rgb')
vid.FrameGrabInterval = 5;
%start the video aquisition here
start(vid)
% Set a loop that stop after 100 frames of aquisition
while(vid.FramesAcquired<=100)
% Get the snapshot of the current frame
data = getsnapshot(vid);
% Now to track red objects in real time
% we have to subtract the red component
% from the grayscale image to extract the red components in the image.
diff_im = imsubtract(data(:,:,1), rgb2gray(data));
%Use a median filter to filter out noise
diff_im = medfilt2(diff_im, [3 3]);
% Convert the resulting grayscale image into a binary image.
diff_im = im2bw(diff_im,0.18);
% Remove all those pixels less than 300px
diff_im = bwareaopen(diff_im,300);
% Label all the connected components in the image.
bw = bwlabel(diff_im, 8);
% Here we do the image blob analysis.
% We get a set of properties for each labeled region.
stats = regionprops(bw, 'BoundingBox', 'Centroid');
% Display the image
imshow(data)
hold on
%
% %This is a loop to bound the red objects in a rectangular box.
for object = 1:length(stats)
bb = stats(object).BoundingBox;
bc = stats(object).Centroid;
rectangle('Position',bb,'EdgeColor','r','LineWidth',2)
plot(bc(1),bc(2), '-m+')
x = bc(1);
y = bc(2);
csvwrite('bcx.dat', bc(1));
csvwrite('bcy.dat', bc(2));
a=text(bc(1)+15,bc(2), strcat('X: ', num2str(round(bc(1))), ' Y: ', num2str(round(bc(2)))));
set(a, 'FontName', 'Arial', 'FontWeight', 'bold', 'FontSize', 12, 'Color', 'yellow');
end
hold off
end
% Both the loops end here.
% Stop the video aquisition.
stop(vid);
% Flush all the image data stored in the memory buffer.
flushdata(vid);
% Clear all variables
clear all
%sprintf('%s','That was all about Image tracking, Guess that was pretty easy :) ')

How to set axis for multiple subplots of pictures in Matlab

clear all; close all; clc;
A = im2double(imread('cameraman.jpg'));
figure(1)
imshow(A)
C = chunking(A,400,400) % separates picture;
[m n] = size(C);
k = 1;
figure(1)
for i = 1:m
for j = 1:n
subplot(m,n,k)
imshow(C{i,j})
axis off;
k = k + 1;
end
end
So In the above code, I am trying to separate a picture into 400x400 pixel chunks. Since the image is not a multiple of 400x400, it will have unequal sections on the border and bottom right corner (still a square image). However, when I use subplot, it resizes the last chunk to be the same size. I tried playing around with get and set position but it gives that the width and height for each subplot is the same?![enter image description here][1]
http://imgur.com/2VUYZr1
You want to resize the axes if you have less than 400 pixels to display. You should store the handle to each subplot and then resize it if it needs to be smaller.
Your call to subplot should look like this:
h = subplot(m,n,k);
num_rows = size(C{i,j}, 1);
num_cols = size(C{i,j}, 2);
set(h, 'units', 'pixels')
old_axes_pos = get(h, 'position');
new_axes_pos = old_axes_pos;
if num_cols < 400
new_axes_pos(3) = num_cols; % Make this axes narrower
end
% If the figure cannot be full height
if num_rows < 400
new_axes_pos(4) = num_rows; % Make this axes shorter
new_axes_pos(2) = old_axes_pos(2) + (400 - num_rows); % Move the bottom up
end
set(h, 'position', new_axes_pos) % Change the size of the figure