how can i save the image and roi to train classifier - matlab

i use this code
axes(handles.axes1)
h=imrect;
position = round(wait(h));
curImg=1;
I=imread(strcat(pathname, filename{k}));
[rows, columns, numberOfColorBands] = size(I);
% Crop image
I2 = imcrop(I,position);
figure;
imshow(I2);
data(curImg).imageFilename = I;
data(curImg).objectBoundingBoxes = position;
curImg = curImg + 1;
i select roi than i extract the position and i save the pathname and the position of the roi, when i use the struct data to train classifier it dosen't work, here is the code:
trainCascadeObjectDetector('Detector.xml',data,negativeFolder,'FalseAlarmRate',0.2,'NumCascadeStages',5);
hope to get a response.

Use trainingImageLabeler app to label your images. Then export the ROIs to your workspace, and pass them to trainCascadeObjectDetector.

Related

Matlab video reader - draw disk on objects

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:

How to smoothen the edges from an image obtained from imagesc function

I have an RGB image obtained from saving the imagesc function as shown below. how to refine/smoothen the edges present in the image.
It consists of sharper edges, where I need to smoothen them. Im not able to find a solution for performing this for an RGB image. Instead of the staircase effect seen in the image I'd like to even out the edges. Please help thanks in advance.
maybe imresize will help you:
% here im just generating an image similar to yours
A = zeros(20);
for ii = -2:2
A = A + (ii + 3)*diag(ones(20-abs(ii),1),ii);
end
A([1:5 16:20],:) = 0;A(:,[1:5 16:20]) = 0;
subplot(121);
imagesc(A);
title('original')
% resizing image with bi-linear interpolation
B = imresize(A,100,'bilinear');
subplot(122);
imagesc(B);
title('resized')
EDIT
here I do resize + filtering + rounding:
% generates image
A = zeros(20);
for ii = -2:2
A = A + (ii + 3)*diag(ones(20-abs(ii),1),ii);
end
A([1:5 16:20],:) = 0;A(:,[1:5 16:20]) = 0;
subplot(121);
imagesc(A);
title('original')
% resizing
B = imresize(A,20,'nearest');
% filtering & rounding
C = ceil(imgaussfilt(B,8));
subplot(122);
imagesc(C);
title('resized')
solution
use imfilter and fspecial to perform a convolution of you image with gaussian.
I = imread('im.png');
H = fspecial('gaussian',5,5);
I2 = imfilter(I,H);
change 'blurlevel' parameter (which determines the gaussian kernel size) to make the image smoother or sharper.
result
If you are just looking for straighter edges, like an elevation map you can try contourf.
cmap = colormap();
[col,row] = meshgrid(1:size(img,2), 1:size(img,1));
v = linspace(min(img(:)),max(img(:)),size(cmap,1));
contourf(col,row,img,v,'edgecolor','none');
axis('ij');
This produces the following result using a test function that I generated.

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.

Extract elliptical region and crop it with with manually in Matlab

I have many face images, I want to extract an elliptical region from the images by manually and crop and save it automatically(like imcrop but not a rectangle).
Could you help me about this?
Thanks for your help
You can use the imellipse function.
%This is what you would do after creating the mask to get the coordinates.
structBoundaries = bwboundaries(binaryImage);
xy=structBoundaries{1}; % Get n by 2 array of x,y coordinates.
x = xy(:, 2); % Columns.
y = xy(:, 1); % Rows.
However a better way would be to use the code below. Essentially, it asks the user to select an image and then the user crops the image manually and then it saves to the location of where the original image is.
[FileName,PathName] = uigetfile({'*.jpg;*.tif;*.png;*.gif','All Image Files'},'Please Select an Image');
image = imread([PathName FileName]);
imshow(image) %needed to use imellipse
user_defined_ellipse = imellipse(gca, []); % creates user defined ellipse object.
wait(user_defined_ellipse);% You need to click twice to continue.
MASK = double(user_defined_ellipse.createMask());
new_image_name = [PathName 'Cropped_Image_' FileName];
new_image_name = new_image_name(1:strfind(new_image_name,'.')-1); %removing the .jpg, .tiff, etc
new_image_name = [new_image_name '.png']; % making the image .png so it can be transparent
imwrite(image, new_image_name,'png','Alpha',MASK);
msg = msgbox(['The image was written to ' new_image_name],'New Image Path');
waitfor(msg);