I'm trying to create a gesture recognition system for static poses. I'm currently trying to implement a wrist-cropping procedure, before moving onto feature extraction.
I came across an algorithm (referenced here: http://admin.csie.ntust.edu.tw/IEET/syllabus/course/961_CS5014702_65_aGlnaDIucGRm.pdf), but I'm not sure of it's technical implementation (the paper referenced another source which I could not locate). 2 methods were described, demonstrated in the image below:
The first is based on the wrist length, the 2nd on changes in the contour of the image. I'm not really sure how to implement this and would appreciate any help.
I have a simple idea (for the 1st method) where you would scan through the pixels (starting from the bottom of the image), counting the no. of pixels on each row, until you encounter a row which has more pixels than the previous row (indicating the start of the palm area). However, this would assume that the positioning of the hand is always vertical. Any ideas to improve upon that so that the hand doesn't always have to be vertical or how to implement the contour-based approach (where you would detect a sharp turn in the contour, indicating the wrist)? I'm quite new to Matlab. Thanks.
An example input:
Using Miki's solution, some outputs on more test images:
Original images:
A simple approach would be to:
Here the code (Version 2):
% Read the image
img = imread(path_to_image);
% Binarize the image
bw = img > 127;
% Compute principal component orientation and rotate
orientation = regionprops(bw, 'Orientation');
centroid = regionprops(bw,'centroid');
% Correct rotation according to centroid
rotationAngle = -90 - orientation.Orientation;
if(centroid.Centroid(1) < size(img,2)/2)
rotationAngle = 90 - orientation.Orientation;
end
rotated = imrotate(bw, rotationAngle);
rows = size(rotated,1);
dist = zeros(rows, 1); % vector of distances of contour points
imshow(rotated);
hold on;
% Compute the distances
for r=1:rows
s = find(rotated(r,:), 1, 'first');
e = find(rotated(r,:), 1, 'last');
if(~isempty(s) && ~isempty(e))
dist(r) = e - s;
plot(s, r, 'xg');
plot(e, r, 'xr');
end
end
% Smooth for cleaner peaks
%dist = smooth(dist, 15);
% Find peaks
[pks, locs] = findpeaks(-dist);
% Select the peak carefully...
th = 20; % A threshold on the distance among peaks
loc = locs(end);
for i = length(locs)-1 : -1 : 1
if(abs(locs(i) - loc) > th)
break;
else
loc = locs(i);
end
end
% Keep best
ycut = loc;
plot([1, size(rotated,2)], [ycut, ycut], 'b');
hold off;
figure();
plot(dist);
hold on;
plot(locs, -pks, 'vg');
hold off;
Result
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With