我正在尝试为静态姿势创建一个手势识别系统。我目前正在尝试实现手腕裁剪程序,然后再进行特征提取。
我遇到了一个算法(此处引用:http://admin.csie.ntust.edu.tw/IEET/syllabus/course/961_CS5014702_65_aGlnaDIucGRm.pdf),但我不确定它的技术实现(该论文引用了我无法找到的另一个来源)。描述了 2 种方法,如下图所示:
第一个基于手腕长度,第二个基于图像轮廓的变化。我不太确定如何实现这一点,希望得到任何帮助。
我有一个简单的想法(对于第一种方法),您可以扫描像素(从图像底部开始),计算编号。每行的像素数,直到遇到比前一行像素更多的行(表示手掌区域的开始)。然而,这将假设手的位置始终是垂直的。有什么改进的想法,这样手就不必总是垂直的,或者如何实现基于轮廓的方法(你会检测到轮廓的急转弯,表示手腕)?我对 Matlab 很陌生。谢谢。
示例输入:
使用 Miki 的解决方案,在更多测试图像上进行一些输出:
原始图片:
最佳答案
一个简单的方法是:
- 根据主轴旋转图像
- 逐行计算轮廓上的点差
- 在差值向量中找到峰值,保留最后一个。
这里是代码(版本 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;
结果
关于matlab - 为手-前臂分割实现手腕裁剪程序(Matlab),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31769944/