Features for Image containing many objects - matlab

If I have an image that contains many objects and I want to get for example the first image moments for the entire image as result from bwlabel, which is stored in Ilabel, how would I do that?
[Ilabel num] = bwlabel(Ibw);
stats = regionprops(Ilabel,'BoundingBox');

Assuming Ibw in your example is numeric (not logical) and contains only integers 0 and 1 (or 0 and some other consistent integer value), you should be able to use it directly as a label matrix:
stats = regionprops(Ibw,'BoundingBox');
This will treat every non-zero pixel in the image as part of a single component. Alternatively , you can take the label matrix from bwlabel and change all of the labels to 1:
[Ilabel num] = bwlabel(Ibw);
Ilabel(find(Ilabel)) = 1;
stats = regionprops(Ilabel,'BoundingBox');

Related

How to apply median filter in all images and store in a directory?

f = 'C:\Users\HP\Desktop\images';
d = ls(f);
d(1,:)=[]
d(1,:)=[]
mkdir('New_images')
for i=1:size(d)
I=imread(fullfile(f,d(i,:)));
Kmedian = I;
for i = 1:3
Kmedian(:,:,i) = medfilt2(Kmedian(:,:,i));
end
Kmedian=imresize(Kmedian,[227 227]);
imshow(Kmedian)
imwrite(Kmedian,fullfile('New_images',strcat(num2str(i),'.jpeg')));
end
How to use median filter at once.
Errors:
In resize (line 5)
Index in position 3 exceeds array bounds (must not exceed 1).
Error in resize (line 10)
Kmedian(:,:,i) = medfilt2(Kmedian(:,:,i));
The medfilt2 function only works on 1 channel at the time. If you have a color image, you will have a 3rd dimension to your pixel "matrix" for red, green, blue channels respectively.
You can still use the medfilt2 function by either converting your image to grayscale, or apply it to each channel individually.
Kmedian = I;
for i = 1:size(Kmedian,3) % Iterate over all the channels in the image
Kmedian(:,:,i) = medfilt2(Kmedian(:,:,i));
end
Updated to account for both single and multi channel images

how to sum the number of objects in different images in Matlab?

this is my entire code. What i did here is to try to find matching points between an image and a template i substracted from the image.
The first loop and second loop extract all the card from the original image(first image with set of card)
The next part of the code is just finding the matching point between extracted card and the template.
The last for loop i created, is based on range of the matching points count I selected to discard cards that have less matching with the template.(selectCard)
Then I created the for loop to (selectCard) and I applied connected components to count the objects remaining on the card when They pass the selection criteria.
So I need to get the total number of object of all the card that pass the selection criteria I have made. Basically, I got a result of each card. Not all the card. I need to compute the result of All those cards.
for j=1:max(max(LabeledImage))
[row, col] = find(LabeledImage==j);
len=max(row)-min(row)+2;
breadth=max(col)-min(col)+2;
Img=uint8(zeros([len breadth 3] ));
sy=min(col)-1;
sx=min(row)-1;
for i=1:size(row,1)
x=row(i,1)-sx;
y=col(i,1)-sy;
Img(x,y,:)=grayImage(row(i,1),col(i,1),:);
end
mytitle=strcat('Card Number:',num2str(j));
% figure,imshow(Img);title(mytitle);
Img=rgb2gray(Img);
pointsForSpade1 = detectHarrisFeatures(Img);
pointsForSpade2 = detectHarrisFeatures(Template_for_spade);
%extract neighborhood features
[featuresForSpade1,valid_pointsForSpade1] =
extractFeatures(Img,pointsForSpade1);
[featuresForSpade2,valid_pointsForSpade2] =
extractFeatures(Template_for_spade,pointsForSpade2);
%Match the features
indexPairs = matchFeatures(featuresForSpade1,featuresForSpade2);
%retrieve the locations of the corresponding points for each image.
matchedPointsForSpade1 = valid_pointsForSpade1(indexPairs(:,1),:);
matchedPointsForSpade2 = valid_pointsForSpade2(indexPairs(:,2),:);
% visualize the corresponding points.
figure,subplot(5,5,j)
showMatchedFeatures(Img,Template_for_spade,matchedPointsForSpade1,.....
matchedPointsForSpade2, 'montage');
count1 = matchedPointsForSpade1.Count;
%disp(matchedPoints1);
selectCard4 = find(count1>10);
Total = 0;
for e4= 1: selectCard4
figure, subplot(5,5,j)
showMatchedFeatures(Img(e4),Template_for_spade,matchedPointsForSpade1,...
matchedPointsForSpade2, 'montage');
title(Name);
% eliminate not needed hole on the card.
level = 0.57;
Img2 = imbinarize(Img, level);
%Morphological operation
ImgComp = imcomplement(Img2);
se = strel('disk', 10);
Iopened = imopen(ImgComp, se);
%figure;
%imshow(Iopened);
[Label3, numObject4] = bwlabel(Iopened);
TotalSpade = sum(numObject4);
s = sprintf('\n card number: of this set has #%s spades',j,
num2str(TotalSpade));
disp(s);
end
end
I want to display the sum of connected objects based on selected card.
Thank you.
There are three main problems here. First, you initialize Total = 0; and then change the variable name to TotalSpade. Change the initialization to:
TotalSpade = 0;
Second, the assignment to TotalSpade is overwriting the previous value. In order to accumulate the total, you need to add to TotalSpade instead. Also, numObject4 is a scalar, so sum doesn't do anything.
TotalSpade = TotalSpade + numObject4;
Finally, if you only want to print the total of the objects, you need to take your print statement outside the loop. You can also use fprintf instead of sprintf+disp since fprintf prints to the console if you don't specify a file descriptor.
for e4 = 1:selectCard4
...
end
fprintf('\n card number: of this set has #%s spades', j,
num2str(TotalSpade));

Storing image data as a row vector

I have multiple images in a folder, and for each image, I want to store the data(pixel values) as a row vector. After I store them in a row vector I can combine these row vectors as one multi dimensional array. e.g. the data for the first image will be stored in row 1, the data for the second image will be stored in row 2 and so on. And any time I want to access a particular image data, let us say I want the third image, I can do something like this race(3,:).
I am currently getting the error:
Dimensions of matrices being concatenated are not consistent.
The error occurs here race = [race; imagevec] I am lost in how to correct this, unless imagevec = I(:)' is not converting the matrix to a row vector .
race = []; % to store all row vector
imagevec = []; % to store row vector
path = 'C:\Users\User_\somedir\'; % directory
pathfile = dir('C:\Users\User_\somedir\*.jpg'); % image file extension in directory
for i = 1 : length(path)
filename = strcat(path,pathfile(i).name); % get the file
I = imread(filename); % read file
imagevec = I(:)'; % convert image data to row vector
race = [race; imagevec]; % store row vector in matrix
end
Using a cell array instead of a matrix will allow you to index in this way even if your images are of different sizes.
You don't even have to turn them into a row vector to store them all in the same structure. You can do something like this:
path = 'C:\Users\User_\somedir\'; % directory
pathfile = dir([path,*.jpg']); % image file extension in directory
race = cell(length(pathfile),1);
for i = 1 : length(pathfile)
filename = strcat(path,pathfile(i).name); % get the file
I = imread(filename); % read file
race{i} = I; % store in cell array
end
Then when you want to perform some operation, you can simply index into the cell array. You could even turn it into a row vector, if you wanted to, as follows.
thisImage = race{3}(:)';
If you are using a matrix to store the results, all rows of a matrix must be the same length.
Cell arrays are similar to arrays except the elements need not be the same type / size.
You can accomplish what you are looking for using a cell array. First, initialize race to:
race = {};
Then try:
race = {race{:}, imagevec};

Rangefilt implementation

I am given an assignment to implement Range filter. Here is my code for that:
I=imread('cameraman.tif');
I=im2double(I);
mkdir('./output_images/');
%Salt and pepper
SP= imnoise(I,'salt & pepper',0.004);
stemName='Salt&pepper';
OutputFileName = ['./output_images/' stemName '_noise.tif'];
imwrite( SP,OutputFileName);
[row col]=size(SP);
%SP=padarray(SP,[3 2],'replicate','both');
for i=2:row-1
for j=2:col-1
neigbours=[0 0 0; 0 0 0;0 0 0];
neibours(1,1)=SP(i-1,j-1);
neibours(1,2)=SP(i-1,j);
neibours(1,3)=SP(i-1,j+1);
neibours(2,1)=SP(i,j-1);
neibours(2,3)=SP(i,j+1);
neibours(3,1)=SP(i+1,j-1);
neibours(3,2)=SP(i+1,j);
neibours(3,3)=SP(i+1,j+1);
neibours(2,2)=SP(i,j);
maxi= max(neibours(:));
mini= min(neibours(:));
newvalue= maxi-mini;
SP(i,j)=newvalue;
end
end
OutputFileName = ['./output_images/' stemName '_filtered.tif'];
imwrite( SP,OutputFileName);
Noise is applied to image I and then saved to SP. A new array is created neibours in which all the neighbors including current pixel is added. Then the difference between max and min is calculated and stored to current pixel. Problem is that when I compare the image generated from this code and the one generated from builtin function rangefilt() results are different.
I was updating same matrix SP. When I created a new matrix S and stored values in that one, it produced the same results as that of built in one.

normalize values for imadjust

I am trying to use imadjust, and in order to do that I have to normalize the values in my image (grayscale image) to 0~1. I have tried the following:
for getting min/max values:
minValue = min(I(:));
maxValue = max(I(:));
than I tried using imadjust in some ways:
Iadjusted = imadjust(I,[lowestValue/highestValue; highestValue/highestValue] ,[0 1]);
Iadjusted = imadjust(I,[lowestValue/255; highestValue/255] ,[]);
Iadjusted = imadjust(I,[double(lowestValue/highestValue); double(highestValue/highestValue)] ,[]);
but none of them worked. Each of them shows error/ shows the original image without any change. When I displayed min/max values the results were right, but when I am trying to display to normalization it always shows 0 or 1. What am I doing wrong?
In MATLAB images are stored using uint8 by default, therefore in [0 1] you can only have two integer number (i.e. 0 and 1). To do what you want between and get an image with range [0, 1] you have to use doubles.
Therefore if you want to use imadjust:
I = double(I)/255;
J = imadjust(I,[min(I(:)); max(I(:))],[0.0; 1.0]);
(Imadjust with doubles wants everything to be between 0 and 1. This is true in general for images expressed with doubles).
This function adjusts a signal (can be image) to the range [0,1]
function normsig = normalize(sig)
sig = double(sig);
normsig = (sig-min(sig(:))) / (max(sig(:))-min(sig(:))) ;
end
usage for an image signal:
img = imread('xxxx.jpg','jpg');
figure; imshow(img);
normalizedimg = normalize(img);
figure; imshow(normalizedimg);