Skip to content

Preprocessing #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Nov 26, 2014
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
You'll need octave 3.8.1+ to run the included packages. They won't
work on ohaton, since the server's missing some required libraries
(well -- something's broken, I dunno).

Run the the following once, since it will install the packages for
you:

> pkg install packages/*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are Octave-specific packages? We run this on the Octave command line?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are octave-specific. I doubt they'll work on Matlab.

Just install them once on the command line and they'll stay installed. My driver has a line to ensure the image package is loaded.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How long is this supposed to take? I think octave is hanging...

FYI for anyone else installing the packages, it takes several minutes with no feedback whatsoever.


You can ensure it is all installed with:

> pkg list

9 changes: 9 additions & 0 deletions driver.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
function driver

pkg load image;

image = imread('smile.png');

preprocess(image);

end
Binary file added packages/control-2.6.6.tar.gz
Binary file not shown.
Binary file added packages/general-1.3.4.tar.gz
Binary file not shown.
Binary file added packages/image-2.2.2.tar.gz
Binary file not shown.
Binary file added packages/signal-1.3.0.tar.gz
Binary file not shown.
60 changes: 60 additions & 0 deletions preprocess.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
function features = preprocess(image)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So are we conciously choosing to use Octave for all our code? I was looking into PyBrain for implementing neural nets in Python. Will mixing languages be a problem for anyone?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured we would use octave at least for image management (since it's very easy). I have no problem mixing languages, just be sure to update the .gitignore first.

% PREPROCESS takes an image and produces a vector with
% found features

features = struct('width', {},
'height', {},
'pixels', {},
'midpoint', zeros(1,2),
'x', {},
'y', {});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The result of this function is a varying-length vector of structs. How do you propose to convert this into a fixed-length feature vector?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could have a feature vector that assumes an upper-bound number of features, and zero out the unused ones.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't 100% sure how we wanted to use the features. Your idea sounds fine to me.

I'll change the function to accept the max number of features as a parameter


% 1. Threshold the image
img = rgb2gray(image);
img = im2bw(img, graythresh(img));

% 2. Find boundaries
[B,L] = bwboundaries(img);

% 3. Extract features
for k=2:numel(B),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2? Is this because of the issue you showed me in class?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. It always starts the boundary checking with the top-left pixel. Since none of our inputs will be clipping the boundaries, this eliminates the outer-boundary problem.

(For those who don't know, bwboundaries will count the surrounding boundary of the image as a section as well, since it includes holes).

[features(k-1).width, features(k-1).height] = calcDim(B{k});
features(k-1).x = min(B{k}(:,1));
features(k-1).y = min(B{k}(:,2));
features(k-1).pixels = calcSize(B{k},L);
[features(k-1).midpoint(1), features(k-1).midpoint(2)] = calcMedian(B{k}, L);
endfor

end

function showImageBounds(img, B)
figure; imshow(img); hold on;
for k=2:numel(B),
plot (B{k}(:,2), B{k}(:,1), 'r', 'linewidth', 2);
endfor
hold off
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not used. Is this for debugging/visualization?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it is. This outlines the found boundaries on the image.


function [width, height] = calcDim(bounds)
width = max(bounds(:,1))-min(bounds(:,1));
height = max(bounds(:,2))-min(bounds(:,2));
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Appears to be reversed, based on my testing.


function pixels = calcSize(bounds, labels)
label = labels(bounds(1,1), bounds(1,2));
pixels = sum(sum(labels == label));
end

function [x,y] = calcMedian(bounds, labels)
label = labels(bounds(1,1), bounds(1,2));
y = findWeightCentre(sum(labels==label));
x = findWeightCentre(sum(labels'==label));
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also seems to be reversed. I believe the first dimension will always be y/height and the second will be x/width. This is consistent with matrix indexing, where row number precedes column number.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. Nice catch.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it shouldn't really affect our learning algorithm, but having the right feature names may make it easier to debug if something goes wrong.


function index = findWeightCentre(array)
values = zeros(size(array));
for k=2:(length(array)-1),
values(k) = sum(array(1:k-1))-sum(array(k+1:end));
end
[tmp, index] = min(abs(values(2:end-1)));
end
Binary file added smile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.