Commit 3bae513c authored by Travis Llado's avatar Travis Llado

init, added old HW assignments

parents
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% classifyImage
% Receives an image and eigenface data for several classes. Returns the class in
% which the image fits.
% written by Travis Llado
% last edited 2017.09.15
% travisllado@utexas.edu
function supposedClass = classifyImage(image, eigendigits, meanVectors)
norms = zeros(10, 1);
for thisDigit = 1:10
reconstructedImage = reconstructImage(image, eigendigits(:, :, thisDigit), meanVectors(:, thisDigit));
norms(thisDigit) = norm(squareToVector(image) - squareToVector(reconstructedImage));
end
[~, supposedClass] = min(norms);
supposedClass = mod(supposedClass, 10);
end
\ No newline at end of file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% getTestImages
% Receives a filename. Opens that file and returns an array of test images and
% their labels. Assumes file is in a specific format.
% written by Travis Llado
% last edited 2017.09.15
% travisllado@utexas.edu
function [testImages, testLabels] = getTestImages(filename)
images = open(filename);
testImages = squeeze(images.testImages);
testLabels = images.testLabels;
end
\ No newline at end of file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% getTrainingImages
% Receives a filename. Opens that file and returns an array of training images
% sorted by label.
% written by Travis Llado
% last edited 2017.09.15
% travisllado@utexas.edu
function sortedTrainingImages = getTrainingImages(filename)
images = open(filename);
imageRes = size(images.trainImages, 1);
numberImages = size(images.trainImages, 4);
sortedTrainingImages = zeros(imageRes, imageRes, numberImages, 10);
smallestClassSize = numberImages;
for digitNumber = 1:10
numberImagesFound = 0;
for imageNumber = 1:numberImages
if images.trainLabels(imageNumber) == mod(digitNumber, 10)
numberImagesFound = numberImagesFound + 1;
sortedTrainingImages(:, :, numberImagesFound, digitNumber) = images.trainImages(:, :, 1, imageNumber);
end
end
if numberImagesFound < smallestClassSize
smallestClassSize = numberImagesFound;
end
end
sortedTrainingImages = sortedTrainingImages(:, :, 1:smallestClassSize, :);
end
\ No newline at end of file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% hw1FindEigendigits
% Classifies numerical characters using the Eigenface method
% written by Travis Llado
% last edited 2017.09.15
% travisllado@utexas.edu
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear variables
dataFilename = 'digits.mat';
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% User Settings
numberTrainingImages = 400; % # training images per digit
numberEigendigitsToUse = 20; % # "best" eigendigits to use
numberTests = 2000; % # of images to classify
drawPictures = 0; % Do you want to draw pictures?
drawPlot = 0; % Do you want to draw a frequency plot?
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Open data file, extract and sort training data
trainingImages = getTrainingImages(dataFilename);
[testImages, testLabels] = getTestImages(dataFilename);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create eigendigits from training data
w = waitbar(0, 'Calculating Eigendigits');
% Initialize data structures
imageRes = size(trainingImages, 1);
eigendigits = zeros(imageRes^2, numberTrainingImages, 10);
meanVectors = zeros(imageRes^2, 10);
selectedTrainingImages = zeros(imageRes, imageRes, numberTrainingImages, 10);
% Randomly select training images
for thisDigit = 1:10
for thisImage = 1:numberTrainingImages
trainingImageNumber = randi([1 size(trainingImages, 3)]);
selectedTrainingImages(:, :, thisImage, thisDigit) = trainingImages(:, :, trainingImageNumber, thisDigit);
end
end
% Computer one set of eigendigits for each digit
for thisDigit = 1:10
[eigendigits(:, :, thisDigit), meanVectors(:, thisDigit)] = makeEigendigits(selectedTrainingImages(:, :, :, thisDigit));
waitbar((thisDigit/10));
end
% Only keep the "best" eigendigits
eigendigits = eigendigits(:, 1:numberEigendigitsToUse, :);
close(w)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Classify images
if ~drawPictures
w = waitbar(0, 'Classifying Testing Images');
end
% Initialize data structure
classificationResults = zeros(10, 10);
% Classify randomly selected test images one at a time
for testNumber = 1:numberTests
testImageNumber = randi([1 size(testImages, 3)]);
supposed = classifyImage(testImages(:, :, testImageNumber), eigendigits, meanVectors);
actual = testLabels(testImageNumber);
classificationResults(supposed + 1, actual + 1) = classificationResults(supposed + 1, actual + 1) + 1;
if drawPictures
imshow(mat2gray(testImages(:, :, testImageNumber)));
title(num2str(supposed));
pause(0.5);
else
waitbar(testNumber/numberTests);
end
end
if ~drawPictures
close(w);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Display results
% Print total success rate
fprintf(strcat('\nSuccess Rate:', num2str(sum(diag(classificationResults))/numberTests), '\n\n'));
if drawPlot
% Normalize results
for columnNumber = 1:10
classificationResults(:, columnNumber) = classificationResults(:, columnNumber)/sum(classificationResults(:, columnNumber));
end
% Draw plot
figure
hold on
for digit = 0:9
plot3(linspace(digit, digit, 10), 0:9, classificationResults(:, digit + 1), 'LineWidth', 3);
end
xlabel('Actual Number');
ylabel('Gets Classified As');
zlabel('With Frequency');
hold off
end
\ No newline at end of file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% makeEigendigits()
% Receives an array of training images. Returns their combined eigenvectors and
% mean.
% written by Travis Llado
% last edited 2017.09.15
% travisllado@utexas.edu
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [eigendigits, meanDigit] = makeEigendigits(trainingImages)
numImages = size(trainingImages, 3);
imageRes = size(trainingImages, 1);
% Combine images into matrix
A = zeros(imageRes^2, numImages);
for imageNum = 1:numImages
A(:, imageNum) = squareToVector(trainingImages(:, :, imageNum));
end
% Calculate mean image vector
meanDigit = mean(A, 2);
% Calculate eigendigits
[V, D] = eig((A - meanDigit)'*(A - meanDigit));
V = A*V;
% Normalize eigendigits
for columnNum = 1:size(V, 2)
V(:, columnNum) = normc(V(:, columnNum));
end
% Sort eigendigits
[~, sortOrder] = sort(diag(D), 'descend');
eigendigits = V;
for columnNum = 1:size(sortOrder, 1)
eigendigits(:, columnNum) = V(:, sortOrder(columnNum));
end
end
\ No newline at end of file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% reconstructImage
% Receives an image and eigenface data for a class of images. Returns the image
% created by projecting the original across the eigendata.
% written by Travis Llado
% last edited 2017.09.15
% travisllado@utexas.edu
function reconstructedImage = reconstructImage(originalImage, eigendigits, meanVector)
k = normc((normc(squareToVector(originalImage) - meanVector)'*eigendigits)');
reconstructedImage = vectorToSquare(eigendigits*k + normc(meanVector));
end
\ No newline at end of file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% function squareToVector()
% Converts a square matrix into a vector.
% written by Travis Llado
% last edited 2017.09.15
% travisllado@utexas.edu
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function vector = squareToVector(square)
resolution = size(square, 1);
vector = zeros(resolution^2, 1);
for columnNum = 1:resolution
indexStart = (columnNum - 1)*resolution + 1;
indexEnd = columnNum*resolution;
vector(indexStart:indexEnd) = square(columnNum, :);
end
end
\ No newline at end of file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% function vectorToSquare()
% Converts a vector into a square matrix
% written by Travis Llado
% last edited 2017.09.15
% travisllado@utexas.edu
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function square = vectorToSquare(vector)
resolution = sqrt(size(vector, 1));
square = zeros(resolution);
for columnNum = 1:resolution
indexStart = (columnNum - 1)*resolution + 1;
indexEnd = columnNum*resolution;
square(columnNum, :) = vector(indexStart:indexEnd);
end
end
\ No newline at end of file
[01 eigendigits 1-16.bmp.jpg]
backuphash=65245
[02 eigendigits 2-17.bmp.jpg]
backuphash=44664
[03 eigendigits 3-18.bmp.jpg]
backuphash=30532
[04 eigendigits 9001-9016.bmp.jpg]
backuphash=30714
[05 eigendigits 1-100.bmp.jpg]
backuphash=61422
[07 reconstruction 2-2.bmp.jpg]
backuphash=50244
[08 reconstruction 2-7824.bmp.jpg]
backuphash=62673
[09 reconstruction 2-9999.bmp.jpg]
backuphash=62333
[10 classification1-7.bmp.jpg]
backuphash=1204
[06 means.bmp.jpg]
backuphash=49407
[11 classification2.bmp.jpg]
backuphash=36952
[01 eigendigits 1-16.bmp]
filters=crop64=1,215f1075e750e3f5;
crop=rect64(215f1075e750e3f5)
moddate=0000a916e2d50000
width=560
height=420
textactive=0
[02 eigendigits 2-17.bmp]
filters=crop64=1,22491075e83ae359;
crop=rect64(22491075e83ae359)
moddate=0000b716e2d50000
width=560
height=420
textactive=0
[03 eigendigits 3-18.bmp]
filters=crop64=1,21d411ade6dbe359;
crop=rect64(21d411ade6dbe359)
moddate=0000c116e2d50000
width=560
height=420
textactive=0
[04 eigendigits 9001-9016.bmp]
filters=crop64=1,22be1075e83ae2bd;
crop=rect64(22be1075e83ae2bd)
moddate=0000cc16e2d50000
width=560
height=420
textactive=0
[05 eigendigits 1-100.bmp]
filters=crop64=1,1abe10eaedabe688;
crop=rect64(1abe10eaedabe688)
moddate=0000d916e2d50000
width=1704
height=1347
textactive=0
[07 reconstruction 2-2.bmp]
filters=crop64=1,1ea11f16eb6dd555;
crop=rect64(1ea11f16eb6dd555)
moddate=0000e816e2d50000
width=560
height=420
textactive=0
[08 reconstruction 2-7824.bmp]
filters=crop64=1,1f161f16ea83d41c;
crop=rect64(1f161f16ea83d41c)
moddate=0000f616e2d50000
width=560
height=420
textactive=0
[09 reconstruction 2-9999.bmp]
filters=crop64=1,1ea11e7aeaf8d41c;
crop=rect64(1ea11e7aeaf8d41c)
moddate=00000117e2d50000
width=560
height=420
textactive=0
[10 classification1-7.bmp]
filters=crop64=1,1af907ecef8aeaaa;
crop=rect64(1af907ecef8aeaaa)
moddate=00001517e2d50000
width=560
height=420
textactive=0
[06 means.bmp]
filters=crop64=1,20ea22beea0ed5f1;
crop=rect64(20ea22beea0ed5f1)
moddate=00002a17e2d50000
width=560
height=420
textactive=0
[11 classification2.bmp]
filters=crop64=1,23331075e666e0e9;
crop=rect64(23331075e666e0e9)
moddate=00003817e2d50000
width=560
height=420
textactive=0
This diff is collapsed.
easy = [ 400 1 0.591;
400 2 0.612;
400 5 0.690;
400 10 0.753;
400 20 0.744;
400 25 0.762;
400 30 0.752;
400 50 0.731;
400 100 0.679;
400 200 0.625;
400 400 0.425;
200 25 0.703;
200 50 0.680;
200 100 0.603;
200 200 0.549;
100 25 0.687;
100 50 0.692;
100 100 0.555;
50 25 0.657;
50 50 0.546;
25 25 0.531; ];
hard = [ 400 1 0.655;
400 2 0.698;
400 5 0.791;
400 10 0.861;
400 20 0.864;
400 25 0.864;
400 30 0.864;
400 50 0.830;
400 100 0.794;
400 200 0.771;
400 400 0.530;
200 25 0.837;
200 50 0.797;
200 100 0.797;
200 200 0.697;
100 25 0.820;
100 50 0.822;
100 100 0.736;
50 25 0.781;
50 50 0.699;
25 25 0.688; ];
both = [ 400 1 0.624;
400 2 0.661;
400 5 0.747;
400 10 0.789;
400 20 0.807;
400 25 0.811;
400 30 0.809;
400 50 0.793;
400 100 0.714;
400 200 0.681;
400 400 0.442;
200 25 0.760;
200 50 0.735;
200 100 0.713;
200 200 0.605;
100 25 0.739;
100 50 0.745;
100 100 0.644;
50 25 0.717;
50 50 0.658;
25 25 0.588; ];
hold on
for i=1:size(easy, 1)
plot3(easy(i, 1), easy(i, 2), easy(i, 3), 'o', 'MarkerSize', 20*easy(i, 3)^2, 'MarkerEdgeColor', 'k', 'MarkerFaceColor', [0 1 0]);
plot3(hard(i, 1), hard(i, 2), hard(i, 3), 'o', 'MarkerSize', 20*hard(i, 3)^2, 'MarkerEdgeColor', 'k', 'MarkerFaceColor', [1 0 0]);
plot3(both(i, 1), both(i, 2), both(i, 3), 'o', 'MarkerSize', 20*both(i, 3)^2, 'MarkerEdgeColor', 'k', 'MarkerFaceColor', [1 1 0]);
end
xlabel('# Training Images');
ylabel('# Eigendigits');
zlabel('Classification Success Rate');
legend('Easy', 'Hard', 'All');
code @ 365ba3cd
Subproject commit 365ba3cd2caa6ee07dd03f0c10ecbc7d1a257182
[02compare2x100.bmp]
backuphash=12901