Sprintf is adding one from categorical data

Hello.
This is incredbly frustrating I dont understand why this is happening but im trying to title my image appending a value from a "catergorical" value and it seems to be adding one to every value.
EDIT: I've uploaded the whole script to help you understand what's been done
clear
close all
clc
% Load training and test data using |imageDatastore|.
Training_Dir = fullfile(toolboxdir('vision'),'visiondata','digits','synthetic');
Testing_Dir = fullfile(toolboxdir('vision'),'visiondata','digits','handwritten');
% imageDatastore recursively scans the directory tree containing the
%
trainingSet = imageDatastore(Training_Dir,'IncludeSubfolders',true,'LabelSource','foldernames');
testingSet = imageDatastore(Testing_Dir,'IncludeSubfolders',true,'LabelSource','foldernames');
%% Show a few of the training and test images
close all
figure('Name','Training Image Examples','NumberTitle','off');
movegui("northwest")
subplot(3,3,1);
imshow(trainingSet.Files{12});
subplot(3,3,2);
imshow(trainingSet.Files{315});
subplot(3,3,3);
imshow(trainingSet.Files{810});
subplot(3,3,4);
imshow(trainingSet.Files{1000});
subplot(3,3,5);
imshow(trainingSet.Files{500});
subplot(3,3,6);
imshow(testingSet.Files{10});
subplot(3,3,7);
imshow(testingSet.Files{35});
subplot(3,3,8);
imshow(testingSet.Files{80});
subplot(3,3,9);
imshow(testingSet.Files{105});
%% Show pre-processing and Feature Extraction results
exTestImage = readimage(testingSet,12);
Gray_IM=im2gray(exTestImage);
Binary_IM = imbinarize(Gray_IM);
figure('Name','Preprocessed Image','NumberTitle','off');
movegui("north")
subplot(1,3,1)
imshow(exTestImage)
subplot(1,3,2)
imshow(Gray_IM)
subplot(1,3,3)
imshow(Binary_IM)
% Extract HOG features from image
img = readimage(trainingSet, 12);
cellSize = [1 1];
[hog_4x4, vis4x4] = extractHOGFeatures(img,'CellSize',cellSize);
figure('Name','Histogram of Gradients','NumberTitle','off')
movegui("northeast")
plot(vis4x4);
figure('Name','Test','NumberTitle','off');
movegui("southwest")
imshow(img, 'InitialMagnification',2000)
hold on
plot(vis4x4,'color', 'b')
%set(gcf,'position',[0,0,800,800])
hold off
%% Extracting HOG Features
% HOG features from each image in training set.
hogFeatureSize = length(hog_4x4);
numImages = numel(trainingSet.Files);
trainingFeatures = zeros(numImages,hogFeatureSize,'single');
for i = 1:numImages
img = readimage(trainingSet,i);
img = im2gray(img); %convertign the specified truecolor The RGB Images to a grayscale intensity image
img = imbinarize(img); % pre-processing step to conver the Imges into black & white
trainingFeatures(i, :) = extractHOGFeatures(img,'CellSize',cellSize);
end
% similar procedure will be used with testing set.
numImages_test = numel(testingSet.Files);
testingFeatures = zeros(numImages_test,hogFeatureSize,'single');
for i = 1:numImages_test
img = readimage(testingSet,i);
img = im2gray(img); %convertign the specified truecolor The RGB Images to a grayscale intensity image
img = imbinarize(img); % pre-processing step to conver the Imges into black & white
testingFeatures(i, :) = extractHOGFeatures(img,'CellSize',cellSize);
end
%% Train and Testing a Decision Tree Classifier
% Get labels for each image.
trainingLabels = trainingSet.Labels;
tree = fitctree(trainingFeatures,trainingLabels);
% Evaluating the the Classifier
% Get labels for each image.
testLabels = testingSet.Labels;
predictedLabels = predict(tree, testingFeatures);
% Tabulate the results using a confusion matrix.
figure("Name","Confusion Matrix",'NumberTitle','off')
movegui("south")
cm = confusionchart(testLabels,predictedLabels,'RowSummary','row-normalized','ColumnSummary','column-normalized');
%confMat = confusionmat(testLabels, predictedLabels);
%% Testing the performance of Trained model on some testing images
M=6;
predicted_Image = predict(tree, testingFeatures(M,:))
figure("Name","Predicted Figure", "NumberTitle","off")
imshow(testingSet.Files{M}, 'InitialMagnification',800);
caption = sprintf('Predicted Digit is: %i', predicted_Image);
title(caption, 'FontSize', 18);
basically in this example M=6 points to the class/ category value of 8 but when its the figure window it equals 9! why is it adding 1 to every output?

1 commentaire

the cyclist
the cyclist le 13 Avr 2022
Are you able to upload the data (or a small subset) that lets us run your code?

Connectez-vous pour commenter.

 Réponse acceptée

Voss
Voss le 13 Avr 2022
Modifié(e) : Voss le 13 Avr 2022
Try using '%s', rather than '%i' or '%d', in sprintf:
c = categorical([1 4 9 16]);
sprintf('digit %i, ',c)
ans = 'digit 1, digit 2, digit 3, digit 4, '
sprintf('digit %s, ',c)
ans = 'digit 1, digit 4, digit 9, digit 16, '
Seems like using '%i' or '%d' gives you the index of the category instead of the category itself.
c = categorical({'ok' 'here' 'are' 'some'});
sprintf('%i ',c)
ans = '3 2 1 4 '
sprintf('%s ',c)
ans = 'ok here are some '

6 commentaires

Richard Harris
Richard Harris le 14 Avr 2022
Modifié(e) : Richard Harris le 14 Avr 2022
%i is not even pointing to an index it's literally adding one to the categorical data value. seems to be only doing it with categorical data.
Also ive editted and uploaded the whole script
But i've %c and it worked! its quite strange isnt %c a char? how come its working with %c and not %i?
%c does not work reliably unless the category name happens to be exactly one character.
c = categorical([1 4 9 16]);
char(c)
ans = 4×2 char array
'1 ' '4 ' '9 ' '16'
sprintf('digit |%c|, ', c)
Error using sprintf
Unable to convert 'categorical' element to exactly one element of type 'char'.
@Richard Harris: If your categories happen to be 0, 1, 2, etc., e.g.:
N_categories = 10;
categories = categorical(0:N_categories-1)
categories = 1×10 categorical array
0 1 2 3 4 5 6 7 8 9
Then sprintf('%i ',categories) will give you each index, which happen to be one more than the category:
sprintf('%i ',categories)
ans = '1 2 3 4 5 6 7 8 9 10 '
since indices start at 1 in MATLAB and the categories start at 0.
Also note that '%c' and '%s' are not the same thing, and as @Walter Roberson points out, '%c' is for a single character only. That's why I suggested using '%s' in my answer.
When you use %c then MATLAB does char() of the categorical. char() of the categorical is defined as returning the name of each category.
When you use %d or %i or %f or %g or %ld or %li then MATLAB uses double() of the categorical. double() of a categorical is defined to return the internal index of the entry.
When you use %u or %lu then MATLAB uses uint64() of the categorical. uint64() of a categorical is defined to return the internal index of the entry.
Then sprintf('%i ',categories) will give you each index, which happen to be one more than the category:
By default the categories are sorted from lowest to highest, and indexed starting from lowest.
categories = categorical(2:3:11)
categories = 1×4 categorical array
2 5 8 11
sprintf('%i ',categories)
ans = '1 2 3 4 '
thank you so much for the explanation.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Get Started with MATLAB dans Centre d'aide et File Exchange

Produits

Version

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by