Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing wrist-cropping procedure for hand-forearm segmentation (Matlab)

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: enter image description here 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:

enter image description here

Using Miki's solution, some outputs on more test images:

enter image description here enter image description here

Original images:

enter image description here enter image description here

enter image description here

like image 627
user3019612 Avatar asked Aug 02 '15 08:08

user3019612


1 Answers

A simple approach would be to:

  1. Rotate the image according to the principal axis
  2. Compute the difference of the points on the contour row-wise
  3. Find the peaks in the difference vector, and keep the last.

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

enter image description here enter image description here enter image description here enter image description here

like image 195
Miki Avatar answered Sep 29 '22 16:09

Miki