Error on Extract hog Features from image sets of different dimensions in Matlab. ''Subscripted assignment dimension mismatch'' - matlab

How could I perform hog feature extraction from image set of different dimensions? I am getting this error on last section.
''Subscripted assignment dimension mismatch.''
%% Change Directory
cd('C:\Users\inquisitive\Documents\MATLAB\hog_test');
%% Root Folder
rootFolder = fullfile('D:\HGDatabase');
%% Load Imagesets Database Directory
imgSets = imageSet(rootFolder,'recursive');
%%
{ imgSets.Description } % display all labels on one line
[imgSets.Count] % show the corresponding count of images
%% determine the smallest amount of images in a category
minSetCount = min([imgSets.Count]);
imgSets = partition(imgSets, minSetCount, 'randomize');
[imgSets.Count]
%% partioning into training and testing sets
[trainingSet, testSet] = partition(imgSets, 0.2, 'randomize');
*%%CAN'T I SKIP THIS SECTION AND DEFINE hog_16x16 ON LOOP ITSELF WHY I NEED TO PERFORM THIS AT FIRST WITH ONE IMAGE*
img = read(trainingSet(3), 4);
[hog_16x16, vis16x16] = extractHOGFeatures(img,'CellSize',[16 16]);
cellSize = [16 16];
hogFeatureSize = length(hog_16x16);
%%Extracting Hog Features
trainingFeatures = [];
trainingLabels = [];
for hand = 1:numel(trainingSet)
numImages = trainingSet(hand).Count;
features = zeros(numImages, hogFeatureSize, 'single');
for i = 1:numImages
img = read(trainingSet(hand), i);
% Apply pre-processing steps
lvl = graythresh(img);
img = im2bw(img, lvl);
features(i, :) = extractHOGFeatures(img, 'CellSize', cellSize);
end
labels = repmat(trainingSet(hand).Description, numImages, 1);
trainingFeatures = [trainingFeatures; features];
trainingLabels = [trainingLabels; labels ];
end
Other Query:
Which image format work best .jpg or .png? I thought .png would be better? Am i right?
I took some pictures and resize them by thinking that it may train in better way? Am i thinking right or wrong? Or is there nothing to do with different size of input. What would you suggest either to perform in same size or image sets with different dimensions.
CAN'T I SKIP FOLLOWING SECTION AND DEFINE hog_16x16 ON LOOP ITSELF WHY I NEED TO PERFORM THIS AT FIRST WITH ONE IMAGE? If i can skip how to deal with that case
img = read(trainingSet(3), 4);
[hog_16x16, vis16x16] = extractHOGFeatures(img,'CellSize',[16 16]);
cellSize = [16 16];
hogFeatureSize = length(hog_16x16);

You should ensure the dimensions of the image are the same as all images, then your extracted hog_16x16 features will have the same dimensions.

Related

What is the better way to change the percentages of the training and the testing during the splitting process?

With using the PCA technique and the Yale database, I'm trying to work on face recognition within Matlab by randomly splitting the training process to 20% and the testing process to 80%. It is given an
Index in position 2 exceeds array bounds (must not exceed 29)
error. The following is the code, hoping to get help:
dataset = load('yale_FaceDataset.mat');
trainSz = round(dataset.samples*0.2);
testSz = round(dataset.samples*0.8);
trainSetCell = cell(1,trainSz*dataset.classes);
testSetCell = cell(1,testSz*dataset.classes);
j = 1;
k = 1;
m = 1;
for i = 1:dataset.classes
% training set
trainSetCell(k:k+trainSz-1) = dataset.images(j:j+trainSz-1);
trainLabels(k:k+trainSz-1) = dataset.labels(j:j+trainSz-1);
k = k+trainSz;
% test set
testSetCell(m:m+testSz-1) = dataset.images(j+trainSz:j+dataset.samples-1);
testLabels(m:m+testSz-1) = dataset.labels(j+trainSz:j+dataset.samples-1);
m = m+testSz;
j = j+dataset.samples;
end
% convert the data from a cell into a matrix format
numImgs = length(trainSetCell);
trainSet = zeros(numImgs,numel(trainSetCell{1}));
for i = 1:numImgs
trainSet(i,:) = reshape(trainSetCell{i},[],1);
end
numImgs = length(testSetCell);
testSet = zeros(numImgs,numel(testSetCell{1}));
for i = 1:numImgs
testSet(i,:) = reshape(testSetCell{i},[],1);
end
%% applying PCA
% compute the mean face
mu = mean(trainSet)';
% centre the training data
trainSet = trainSet - (repmat(mu,1,size(trainSet,1)))';
% generate the eigenfaces(features of the training set)
eigenfaces = pca(trainSet);
% set the number of principal components
Ncomponents = 100;
% Out of the generated components, we keep "Ncomponents"
eigenfaces = eigenfaces(:,1:Ncomponents);
% generate training features
trainFeatures = eigenfaces' * trainSet';
% Subspace projection
% centre features
testSet = testSet - (repmat(mu,1,size(testSet,1)))';
% subspace projection
testFeatures = inv(eigenfaces'*eigenfaces) * eigenfaces' * testSet';
mdl = fitcdiscr(trainFeatures',trainLabels);
labels = predict(mdl,testFeatures');
% find the images that were recognised and their respect. labels
correctRec = find(testLabels == labels');
correctLabels = labels(correctRec);
% find the images that were NOT recognised and their respect. labels
falseRec = find(testLabels ~= labels');
falseLabels = labels(falseRec);
% compute and display the recognition rate
result = length(correctRec)/length(testLabels)*100;
fprintf('The recognition rate is: %0.3f \n',result);
% divide the images into : recognised and unrecognised
correctTest = testSetCell(correctRec);
falseTest = testSetCell(falseRec);
% display some recognised samples and their respective labels
imgshow(correctTest(1:8),correctLabels(1:8));
% display all unrecognised samples and their respective labels
imgshow(falseTest(1:length(falseTest)), falseLabels(1:length(falseTest)));
it would be nice, if you provide also the line-number and the full message of the error and if you would strip your code to the essential. I guess, the PCA-stuff is not necessary here, as the error is raised probably in your loop. That is because you are incrementing j by j = j+dataset.samples; and take this in the next loop-set for indexing j:j+trainSz-1, which now must exceed dataset.samples...
Nevertheless, there is no randomness in the indexing. It is easiest if you use the built-in cvpartition-function:
% split data
cvp = cvpartition(Lbl,'HoldOut',.2);
lgTrn = cvp.training;
lgTst = cvp.test;
You may provide the number of classes as first input (Lbl in this case) or the actual class vector to let cvpartition pick random subsets that reflect the original distribution of the individual classes.

Spheroids detction from Images

I need to find the blobs from the below image.
The major problem is background. background doesn't have uniform intensity. I tried couple of things like thresholding and edge detection in MATLAB but couldn't able to find a better ways to segment out all spheroids. I need to extract the blobs and I need to find the area of each blobs. Does anyone know how to work-around with this kind of background?
Edit (07/02/17):
As suggested by Spektre I tried Following things in MATLAB.
Method 1:
img_original = imread('~/my_image.jpg'); %Read image
img_ch = single(img_original(:,:,2)); %Pick one channel( here its green)
g = fspecial('gaussian',200,100); %Kernel matrix to make the img blurr
con_img = conv2(img_ch,g,'same'); %2D convolution, this wil make the img blurr
sub_img = (con_img - img_ch); %Simple matrix subtraction
sub_img(sub_img <= 10) = 0; %Thresholding
sub_img(sub_img ~= 0) = 1;
fil_sub = imfill(sub_img,'holes'); %Fill the regions
imgfilt = imfilter(fil_sub, ones(3)); %run filter using 3by3 matrx
imgfilt(imgfilt < 8) = 0; %Reduce noisy pixels by thresholding
mfilt_img = (medfilt2(imgfilt)); %reduce unwanted pixels
img = img_ch;
img(mfilt_img ~= 0) = 255;
img2 = img_ch;
img2(img2 < 70) = 0; %Threshold for darker pixels which are left out from above methode.
img(img2 ==0) = 255;
disp_img = img_original(:,:,1);
disp_img(img ==255) = 255;
img_original(:,:,1) = disp_img;
figure, imshow(img_original)
I got the segments but still not good enough I think. This method gave good segments in the high intensity background, Even if I reduce the threshold value segments are not clear in the darker background and brightest pixels in the blobs are excluded.
Method 2:
img_original = imread('~/cancer_cells/Snap-10234.jpg'); %Read image
img_ch = single(img_original(:,:,2)); %Pick one channel( here its green)
clear new_matcel cur_img matcel avg_matrx
s=3; % Set size of the square window
mat_img = img_ch; % Working image channel
% resize the working matrix so that the dimensions matches
resize_img = resizem(mat_img,round(size(mat_img)/s)*s);
% convert matrix into small s x s matrix and save each in cells
window_c = ones(1,size(resize_img,1)/s) * s;
window_r = ones(1,size(resize_img,2)/s) * s;
mat_cel = mat2cell(resize_img,window_c,window_r);
new_matcel = cell(size(mat_cel)); % initialize new variable
% get the average value for each window and replace the actual by avg value
for i = 1:size(mat_cel,1)
for j = 1:size(mat_cel,2)
cur_img = mat_cel{i,j};
avg_value = mean(mean(cur_img));
new_matcel{i,j} = ones(s) * avg_value;
end
end
avg_matrx = cell2mat(new_matcel); % convert cells to matrix
image_sub = (abs(resize_img - avg_matrx)); % take the absolute difference
image_sub(image_sub < 7) = 0; % thresholding
image_sub(image_sub~=0) = 1;
image_sub = bwmorph(image_sub,'bridge');% fill gaps
image_sub = imfill(image_sub,'holes'); % fill the bounded regioons
% image_sub(image_sub == 1) = 255;
image_sub = resizem(image_sub,size(img_ch)); % resize to original size
disp_img = img_original(:,:,1);
disp_img(image_sub == 1) = 255;
img_original(:,:,1) = disp_img;
figure, imshow(img_original)
Much better segmented image:
even brighter pixels are included in the segment. Thanks to Spektre.
Is there a way to improve the above code? or any other idea to get more precise segments?
Thanks.

Take a text line in an image file to create a new image file MATLAB

I need to take each line of text from an image file and create a new separate image for each of the lines. i already have a way to count how many lines are in the image file.
if anybody has any suggestions it would be a huge help because i'm not too good with images. im not allowed to use the image processing toolbox.
This is the code:
function out = countLines( imgFile )
% count the number of lines in the image file
im = imread(imgFile);
im = 255 - im;
imbw = uint8(0.33*im(:,:,1) + 0.34*im(:,:,2) + 0.33*im(:,:,3)) > 127;
imwrite(imbw, 'temp.jpg');
rvec = sum(imbw');
rvec1 = [0 rvec 0];
svec = [rvec 0 0];
out = sum(rvec1 == 0 & svec ~= 0);
I tried this method on a test image I found on the internet and it seemed to work alright provided the text is straight. Basically you look for entries in your rvec vector whose neighbouring entries are both smaller than them. That is to say you look for the local maximum entries (first image). After that you group the clusters of lines together to decide where to split the image (second image).
clear; clc;
im = imread('text.png'); % load the image
[Nrows,Ncols,~] = size(im); % get the size
imgray = rgb2gray(im); % convert to grayscale
vec = mean(imgray,2); % average intensities of each row
localMax=[]; % list of local maximum entries
for i = 2:Nrows-1 % accept local max rows that do not have text
hasText = sum( imgray(i,:)<100 )>0;
if vec(i)>vec(i-1) && vec(i)>vec(i+1) && ~hasText
localMax = [localMax;i];
end
end
numMax = length(localMax);
% get distances between local max rows
distances = localMax(2:end) - localMax(1:end-1);
thresh = mean(distances); % the average distance will be our threshold
splitRows = []; % rows where we will split the image
cluster = localMax(1); % start a cluster with the first local max row
for i = 1:numMax-1;
if distances(i) < thresh % if rows are close together, keep them in a cluster
cluster = [cluster;localMax(i+1)];
else % average the cluster to get the row where we split the image
newSplit = round(mean(cluster));
splitRows = [ splitRows ; newSplit ];
cluster = localMax(i+1);
end
end
newSplit = round(mean(cluster)); % add the last cluster as well
splitRows = [ splitRows ; newSplit ];

Dimensions issus

Finding maximum values of wave heights and wave lengths
dwcL01 though dwcL10 is arrays of <3001x2 double> with output from a numerical wave model.
Part of my script:
%% Plotting results from SWASH
% Examination of phase velocity on deep water with different number of layers
% Wave height 3 meters, wave peroid 8 sec on a depth of 30 meters
clear all; close all; clc;
T=8;
L0=1.56*T^2;
%% Loading results tabels.
load dwcL01.tbl; load dwcL02.tbl; load dwcL03.tbl; load dwcL04.tbl;
load dwcL05.tbl; load dwcL06.tbl; load dwcL07.tbl; load dwcL08.tbl;
load dwcL09.tbl; load dwcL10.tbl;
M(:,:,1) = dwcL01; M(:,:,2) = dwcL02; M(:,:,3) = dwcL03; M(:,:,4) = dwcL04;
M(:,:,5) = dwcL05; M(:,:,6) = dwcL06; M(:,:,7) = dwcL07; M(:,:,8) = dwcL08;
M(:,:,9) = dwcL09; M(:,:,10) = dwcL10;
%% Finding position of wave crest using diff and sign.
for ii=1:10
Tp(:,1,ii) = diff(sign(diff([M(1,2,ii);M(:,2,ii)]))) < 0;
Wc(:,:,ii) = M(Tp,1,ii);
L(:,ii) = diff(Wc(:,1,ii))
end
The loop
for ii=1:10
Tp(:,1,ii) = diff(sign(diff([M(1,2,ii);M(:,2,ii)]))) < 0;
Wc(:,:,ii) = M(Tp,1,ii);
L(:,ii) = diff(Wc(:,1,ii))
end
Works fine for ii = 1 Getting the following error for ii = 2
Index exceeds matrix dimensions.
Error in mkPlot (line 19)
Wc(:,:,i) = M(Tp,:,i);
Don't have the same number of wave crests for the different set ups, naturally M(Tp,1,ii) will have different dimensions. How do I work around this issue? Can it be done in a for loop? please feel free to email me or other wise ask for further information.
The problem is that Tp is a three dimensional array. I need to call the Tp(:,:,ii) corresponding to the present scenario. Together with this and defining Wc as a cell I solve my issue.
for ii = 1:10
Tp(:,1,ii) = diff(sign(diff([M(1,2,ii);M(:,2,ii)]))) < 0;
Wc{:,:,ii} = M(Tp(:,:,ii),1,ii);
L{:,ii} = diff(cell2mat(Wc(ii)));
end

Matlab: Check all images in a directory for grayscale?

I want to check all jpg-images in the current directory if they are grayscale or contain coloured pixels... I tried:
figdirectory = pwd;
fullpath = sprintf('%s/*.jpg', figdirectory);
d = dir(fullpath);
% Loop
pages = [];
for i = 1:length(d)
f = d(i).name;
fname_input = sprintf('%s/%s', figdirectory, f);
A = imread(fname_input);
B = rgb2gray(A);
if(A-B == 0)
hascolor = 0;
else
hascolor = 1;
end
pages = [pages; hascolor];
end
but this gives me an error about the matrix dimensions of A and B. Why has A a third dimension?
Thanks!
To do that:
0) Assuming your input is purely an 'image' and not a 'volume'.
1) [r c d] = size(im);
2) if d is larger than 1, then it is a colored image
3) other wise, it has to be a gray-scale image.
EDITS:
You can add one more condition to solidly distinguish grey scale img from color ones. Assuming ur color imgs are of 3 channels,
if d is equal to 3 then check if all 3 channels are equal
im(:,:,1)==im(:,:,2) && im(:,:,1)==im(:,:,3)
Then you have an grayscale image otherwise color img
Here is one simple solution based on IMFINFO:
%# some test images shipped with the Image Processing Toolbox
fNames = {
'circles.png' %# binary
'shadow.tif' %# indexed color
'coins.png' %# gray
'peppers.png' %# RGB
};
isGrayscale = false(size(fNames));
for i=1:numel(fNames)
imgInfo = imfinfo(fNames{i});
if strcmp(imgInfo.ColorType,'truecolor')
isGrayscale(i) = false;
elseif strcmp(imgInfo.ColorType,'grayscale')
isGrayscale(i) = true;
elseif strcmp(imgInfo.ColorType,'indexed')
%# indexed images colormap (the three channels should be all same)
isGrayscale(i) = all(all( diff(imgInfo.Colormap,[],2)==0 ,2),1);
end
end
The first part in your case can be:
dirName = 'C:\path\to\myimages';
files = dir( fullfile(dirName,'*.jpg') );
fNames = {files.name}';
EDIT:
#Adrian: With regards to the image you posed, as far as the image format saved, it IS a color image. Now the fact that all R/G/B channels are all the same is simply a special case...
Anyway if you want to be able to detect such cases, change the 'truecolor' part of the above code to:
#% ...
if strcmp(imgInfo.ColorType,'truecolor')
img = imread(fNames{i});
isGrayscale(i) = isequal(img(:,:,1),img(:,:,2),img(:,:,3));
elseif strcmp(imgInfo.ColorType,'grayscale')
#% ...
You can use IMFINFO for this task, so that you won't have to load the image into memory.
figdirectory = pwd;
fullpath = sprintf('%s/*.jpg', figdirectory);
d = dir(fullpath);
nImages = length(d);
%# imageType is a cell array with either 'grayscale', 'truecolor', or 'indexed',
%# depending on the kind of image you have.
imageType = cell(nImages,1);
for iImg = 1:nImages
info = imfinfo(d(iImg).name);
imageType{iImg} = info.ColorType;
end
%# isGrayscale is true for grayscale images, false otherwise
%# (though note that there might be mapped images that map to a grayscale colormap).
isGrayscale = cellfun(#(x)strcmp(x,'grayscale'),imageType);
EDIT
%# the indexed images have to be loaded in order for you to check
%# for grayscale maps
indexedIdx = find(cellfun(#(x)strcmp(x,'indexed'),imageType));
for iImg = indexedIdx(:)'
[~,map] = imread(fullfile(figDirectory,d(iImg).name));
%# It's a grayscale image if rgb map values are all equal
isGrayscale(iImg) = all(all(bsxfun(#eq,map,map(:,1)),2),1);
end
%# finally, it is possible that the images are *stored* as truecolor
%# but containing, in fact, a grayscale image
truecolorIdx = find(cellfun(#(x)strcmp(x,'truecolor'),imageType));
for iImg = truecolorIdx(:)'
img = imread(fullfile(figDirectory,d(iImg).name));
%# It's a grayscale image if rgb map values are all equal
isGrayscale(iImg) = all(all(all(bsxfun(#eq,img(:,:,1),img),1),2),3);
end
From the manual for imread http://www.mathworks.co.uk/help/techdoc/ref/imread.html
If the file contains a grayscale image, A is an M-by-N array. If the
file contains a truecolor image, A is an M-by-N-by-3 array.
So A will have a third dimension for the coloured images.
If you want to test for greyscale then you could convert the image to hsv.
B = rgb2hsv(A)
from the manual, http://www.mathworks.co.uk/help/techdoc/ref/hsv2rgb.html
When B(:,2) is 0, the colors are unsaturated (i.e., shades of gray).
In the case of a true colour image like the one posted it will be if unique(B(:,:,2)) is zero, hence
A = imread(fname_input);
B = rgb2hsv(A);
%# if saturation levels are zero then it's a greyscale image
if(unique(B(:,:,2)) == 0)
hascolor = 0;
else
hascolor = 1;
end