Matlab video reader - draw disk on objects - matlab

i try to draw a disk on objects in video (the object are cars are move on road from left to right).
my code:
obj = VideoReader('Cars.avi');
get(obj)
im = read(obj,71);
nframes = get(obj,'NumberOfFrames');
sedisk = strel('disk',10);
im_new = imopen(im,sedisk);
stats = regionprops(im_new);
area_array = [stats.Area];
im2 = read(obj,1);
figure,imagesc(im2);
for i=1:nframes-1
stats(i).Centroid
frame = read(obj,i);
imshow(frame);
end
i see the frames but not the disk on the cars, why it's not working?
maybe something in the logic is wrong?
thank's everyone

You need to put the regionprops code into the for loop, and plot the regions over the image.
Start by following MATLAB regionprops documentation
I built a sample code with traffic.avi as input file.
traffic.avi file comes with my MATLAB installation (in folder toolbox/images/imdata/).
Here is a code sample (please read the comments):
clear
close all
%obj = VideoReader('Cars.avi');
obj = VideoReader('traffic.avi');
nframes = get(obj, 'NumberOfFrames');
%sedisk = strel('disk', 10);
sedisk = strel('disk', 2); %Smaller disk fits traffic.avi (you can keep sedisk = strel('disk', 10))
%Read first image (assume no cars). In your code you can keep: im = read(obj,71);
im1 = read(obj,1);
for i = 2:nframes
im = read(obj, i);
imshow(im); %Show the frame
%Subtract frame form the first frame - assume the cars will pop up in the difference image.
diff_im = uint8(abs(double(im) - double(im1)));
I = rgb2gray(diff_im); %Convert to grayscale image
BW = imbinarize(I); %Convert to binary image.
im_new = imopen(BW, sedisk);
stats = regionprops('table', im_new, 'Centroid', 'MajorAxisLength', 'MinorAxisLength'); %MATLAB documentation code sample
%imshow(im_new);
if (~isempty(stats))
%stats(i).Centroid
centers = stats.Centroid; %Get centers (MATLAB documentation code sample)
%Get radius of the circles (MATLAB documentation code sample).
diameters = mean([stats.MajorAxisLength stats.MinorAxisLength],2);
radii = diameters/2;
%Plot the circles on the displayed video frame.
hold on
viscircles(centers,radii);
hold off
end
pause(0.1); %Pause 0.1 seconds
end
The code is not marking the cars accurately (just demonstrates the stages).
Here is a sample frame:

Related

Create a loop in order to create freehand ROIs

I have the following code done whereby I import a frame from a film, convert to grayscale and draw by freehand the region of interest. I then use Chan-Vese region fill to get my region of interest and create a mask based on this. I can finally get the binary image I'm looking for which is called BW3 in the code. Now this is the silly part. How do I create a loop such that the code will run (load frames 1 to 58), present me with the grayscale image for frame 1, allow me to draw the region of interest and then create and save the final binary image BW3?
Regards,
J
% Select Initial Image
for n = 5:87
frame = read(obj,n);
%Isolate the Blade
imggray = rgb2gray(frame);
h_im=imshow(imggray);
%Region of interest
% r = imrect(gca,[646,188,18,-648]);
% BW2 = createMask(r,h_im);
hROI = imfreehand(gca);
Position = getPosition(hROI);
BW2 = createMask(hROI);
%Get blade Binary
BW3 = activecontour(imggray, BW2, 1000, 'Chan-Vese');
% Fill Holes
BW3 = imfill(BW3, 'holes');
% Form masked image from input image and segmented image.
maskedImage = h_im;
maskedImage(~BW3) = 0;
%Save binary frame
filename = sprintf('C:..........\\binaryimage%d.png', n);
imwrite(BW3,filename,'png');
end
Assuming that you have a limited number of frames (ie up to 58) you could just use a for loop to accomplish this. In your code, you will have to change the initial image code so that it iterates up with the loop.
for counter=1:58
frame=read(obj,counter);
imwrite(frame,strcat('frame',num2str(counter),'.png'))
.....% the remainder of your code likely remains unchanged.
end
When writing your results, you would likely need to drop it into a struct of some sort so that you can loop through unless you write your results to a file in each loop.

Wrong number of objects being returned

I have this MATLab code to count the number of objects in the image. There are two objects in the image I am choosing (a car and a cyclist). However, the program is returning a wrong output saying there are 0 objects. Can someone find the error in the code? Thanks.
The logic behind the code is:
1. Take two input images are given, one without objects and one with objects.
2. Convert the input images from RGB to Gray scale.
3. Compare the two images and find the difference.
4. Convert the image obtained to binary.
5. In the image, only open the blobs whose area is greater than 4000.
6. Display the count and density.
clc;
MV = imread('car.png'); %To read image
MV1 = imread('backgnd.png');
A = double(rgb2gray(MV)); %convert to gray
B= double(rgb2gray(MV1)); %convert 2nd image to gray
[height, width] = size(A); %image size?
h1 = figure(1);
%Foreground Detection
thresh=11;
fr_diff = abs(A-B);
for j = 1:width
for k = 1:height
if (fr_diff(k,j)>thresh)
fg(k,j) = A(k,j);
else
fg(k,j) = 0;
end
end
end
subplot(2,2,1) , imagesc(MV), title ({'Orignal Frame'});
subplot(2,2,2) , imshow(mat2gray(A)), title ('converted Frame');
subplot(2,2,3) , imshow(mat2gray(B)), title ('BACKGND Frame ');
sd=imadjust(fg); % adjust the image intensity values to the color map
level=graythresh(sd);
m=imnoise(sd,'gaussian',0,0.025); % apply Gaussian noise
k=wiener2(m,[5,5]); %filtering using Weiner filter
bw=im2bw(k,level);
bw2=imfill(bw,'holes');
bw3 = bwareaopen(bw2,5000);
labeled = bwlabel(bw3,8);
cc=bwconncomp(bw3);
Densityoftraffic = cc.NumObjects/(size(bw3,1)*size(bw3,2));
blobMeasurements = regionprops(labeled,'all');
numberofcars = size(blobMeasurements, 1);
subplot(2,2,4) , imagesc(labeled), title ({'Foreground'});
hold off;
disp(numberofcars); % display number of cars
disp(Densityoftraffic); %display number of vehicles
An empty image(of a road) with no objects(vehicles) in it
An image of the same road but with 2 objects(car and cyclist) in it
Try This it will help you in an optimize manner
clc
clear all
close all
im1 = imread('image1.png');
im2 = imread('image2.png');
gray1 = double(rgb2gray(im1));
gray2 = double(rgb2gray(im2));
absDif = mat2gray(abs(gray1 - gray2));
figure,imshow(absDif,[])
absDfbw = im2bw(absDif,0.9*graythresh(absDif));
figure,imshow(absDfbw,[])
absDfbw = bwareaopen(absDfbw,25);
absDfbw = imclose(absDfbw,strel('disk',5));
figure,imshow(absDfbw,[])
Results are:
Thank You

extracting leaf after watershed segmentation in matlab

after I applied watershed segmentation, I want to extract remained leaf from image,and only I want to get without background like image-2. Please can you help me. Thanks a lot. I attach below also my code.
I'm new at stackoverflow, therefore I'm not allowed to post images.I asked the same qustion in mathworks, you can check the images from there if you will.
Thanks a lot in advance.
http://www.mathworks.com/matlabcentral/answers/237106-extracting-leaf-from-background
image-1: after watershed segmentation(colored version):
image-2:image to be ;
my code:
% I -- intensity image
% Gmag -- gradient mag.
se = strel('disk', 30);
Ie = imerode(I, se);
Iobr = imreconstruct(Ie, I);
figure
imshow(Iobr), title('Opening-by-reconstruction (Iobr)')
Iobrd = imdilate(Iobr, se);
Iobrcbr = imreconstruct(imcomplement(Iobrd), imcomplement(Iobr));
Iobrcbr = imcomplement(Iobrcbr);
figure
imshow(Iobrcbr), title('Opening-closing by reconstruction (Iobrcbr)')
fgm = imregionalmax(Iobrcbr);
figure
imshow(fgm), title('Regional maxima of opening-closing by reconstruction (fgm)')
% modify area
I2 = I;
I2(fgm) = 255;
figure
imshow(I2), title('Regional maxima superimposed on original image (I2)')
se2 = strel(ones(10,10));
fgm2 = imclose(fgm, se2);
fgm3 = imerode(fgm2, se2);
fgm4 = bwareaopen(fgm3, 100);
I3 = I;
I3(fgm4) = 255;
figure
imshow(I3)
title('Modified regional maxima superimposed on original image (fgm4)')
% background markers
bw = im2bw(Iobrcbr, graythresh(Iobrcbr));
figure
imshow(bw), title('Thresholded opening-closing by reconstruction (bw)')
D = bwdist(bw);
DL = watershed(D);
bgm = DL == 0;
figure
imshow(bgm), title('Watershed ridge lines (bgm)')
gradmag2 = imimposemin(Gmag, bgm | fgm4);
L = watershed(gradmag2);
I4 = I;
I4(imdilate(L == 0, ones(3, 3)) | bgm | fgm4) = 255;
figure
imshow(I4)
title('Markers and object boundaries superimposed on original image (I4)')
Lrgb = label2rgb(L, 'jet', 'w', 'shuffle');
figure
imshow(Lrgb)
title('Colored watershed label matrix (Lrgb)')
figure
imshow(I)
hold on
himage = imshow(Lrgb);
himage.AlphaData = 0.3;
title('Lrgb superimposed transparently on original image')
props = regionprops(L);
[~,ind] = max([props.Area]);
imshow(L == ind);
It's not possible to extract the leaf according to the segmented image, because the yellow component cuts the leaf in different parts.
Moreover, according to the source code, I understand that you use a basic watershed that produces an over segmentation. Use a watershed constrained, also known as watershed with markers.
Find a way to share the original image and the image after processing.
I confirm that you certainly have an issue with the watershed you use. I ran your code on my own library, and I used: one inner marker (biggest component, consequently the leaf on the corner is discarded), one outer (dilation of the inner), the gradient image.
And here is my result: www.thibault.biz/StackOverflow/ResultLeaf.png. So only one component, because I use only one inner marker. It's not perfect, but already closer and easier to post-process.

MATLAB - Splitting an image converts the blocks into grayscale

Using MATLAB, I am trying to convert a randomly sized image into four equal blocks. I am working with "for" loops to create blocks. The problem I am facing is that these blocks are being converted into gray scale whereas I want the blocks to retain their original form i.e. RGB channel. Here is the code I am using:
clear all;
img1 = imread('ABC.png');
[rs, cols, colorchan] = size(img1);
rnew = int32(rs/2);
cnew = int32(cols/2);
for i = 1:4
for j = 1:4
imgij = img1((i-1)*rnew+1:i*rnew, (j-1)*cnew+1:j*cnew);
figure();
imshow(imgij);
%do some other stuff here%
end
end
I am new to MATLAB and that's the best I could do myself. Can somebody please tell me how to retain the original form of every block of the parent image? Any help will be highly appreciated.
You have considered only the width and height of the image. But actually for a colour image, colour is the 3rd dimension in Matlab. Try the following code.
img = imread('onion.png');
figure; imshow(img);
w = size(img,2); % width of the original image
h = size(img,1); % height of the original image
wm = floor(w/2); % middle of the width
hm = floor(h/2); % middle of the height
figure;
imgtl = img(1:hm,1:wm,:); % top left image
subplot(2,2,1); imshow(imgtl);
imgtr = img(1:hm,wm+1:w,:); % top right image
subplot(2,2,2); imshow(imgtr);
imgbl = img(hm+1:h,1:wm,:); % bottom left image
subplot(2,2,3); imshow(imgbl);
imgbr = img(hm+1:h,wm+1:w,:); % bottom right image
subplot(2,2,4); imshow(imgbr);
Original image:
Partitioned image:

not able to position the correlated image on top of orginal image using normxcorr2 matlab function

I am trying to locate the exact location of the subimage of an image using normxcorr2 matlab function. It seems to work all well except placing the image at exact location.
The full image is this
The subimage is this
I am find xpeak and ypeak of the correlation of two images and displaying them both using these two coordinates. But for unknown reason, it is not at the location it is supposed to be.
The output looks like this
My code is as follows
clear
clc
%#read & convert the image
imgGray = imread('1.jpg');
imgGray = rgb2gray(imgGray);
obj = rgb2gray(imread('2.jpg'));
%# cross-correlate and find the offset
cor = normxcorr2(obj,imgGray);
[max_cc,indx] = max(abs(cor(:))); %# Modify for multiple instances (generalize)
[yPeak, xPeak] = ind2sub(size(cor),indx(1));
offset = [yPeak - size(obj,1), xPeak - size(obj,2)];
% size(obj,2)
% create a mask
xbegin = offset(1)+1;
xend = offset(1)+size(obj,2);
ybegin = offset(2)+1;
yend = offset(2)+size(obj,1);
mask = uint8(zeros(size(imgGray)));
mask(ybegin:yend,xbegin:xend) = obj;
h1 = imshow(imgGray);
set(h1,'AlphaData',0.7)
hold on
h2= imshow(mask);
set(h2,'AlphaData',0.9)
Please suggest something
You've swapped x and y. offset is defined as [y, x], but you've used it as [x, y]. I've pointed out these lines below:
offset = [yPeak - size(obj,1), xPeak - size(obj,2)];
and then
xbegin = offset(1)+1;
xend = offset(1)+size(obj,2);
ybegin = offset(2)+1;
yend = offset(2)+size(obj,1);