2014-11-25 94 views
0

我必須用Matlab創建一個算法,通過手的圖像可以通過凸起手指的數量和拇指是否存在來了解手的形狀。到目前爲止,該算法幾乎完成,但我不知道我能做些什麼,可以找到代表手指的峯值。我們嘗試了很多東西,但沒有任何效果。這個想法是要找到突然增加的時間,但像素從未完全對齊,沒有任何我們嘗試過的。有人有任何想法?這是目前的代碼。使用MATLAB手指峯值檢測

,他正在閱讀的圖像是這個:

要知道,如果手指是相關與否,我們已經有了一個想法,可能工作......但我們需要找到手指先。

clear all 
close all 

image=imread('mao2.jpg'); 

YCBCR = rgb2ycbcr(image); 
image=YCBCR; 

cb = image(:,:,2); 
cr = image(:,:,3); 
imagek(:,1) = cb(:); 
imagek(:,2) = cr(:); 
imagek = double(imagek); 

[IDX, C] = kmeans(imagek, 2, 'EmptyAction', 'singleton'); 

s=size(image); 
IDX= uint8(IDX); 
C2=round(C); 
imageNew = zeros(s(1),s(2)); 
temp = reshape(IDX, [s(1) s(2)]); 
for i = 1 : 1 : s(1) 
for j = 1 : 1 : s(2) 
    imageNew(i,j,:) = C2(temp(i,j)); 
end 
end 
imageNew=uint8(imageNew); 

[m,n]=size(imageNew); 

for i=1:1:m 
    for j = 1:1:n 
     if(imageNew(i,j)>=127) 
      pretobranco(i,j)=0; 
     else 
      pretobranco(i,j)=1; 
     end 
    end 
end 

I2=imfill(pretobranco); 

imshow(I2); 
imwrite(I2, 'mao1trab.jpg'); 


[m,n]=size(I2); 

B=edge(I2); 
figure 
imshow(B); 
hold on; 

stats=regionprops(I2,'BoundingBox'); 

rect=rectangle('position', [stats(1).BoundingBox(1), stats(1).BoundingBox(2), stats(1).BoundingBox(3), stats(1).BoundingBox(4)], 'EdgeColor', 'r'); 
stats(1).BoundingBox(1) 
stats(1).BoundingBox(2) 
stats(1).BoundingBox(3) 
stats(1).BoundingBox(4) 
figure 
Bound = B(stats(1).BoundingBox(2): stats(1).BoundingBox(2)+stats(1).BoundingBox(4)-1, stats(1).BoundingBox(1):stats(1).BoundingBox(1)+stats(1).BoundingBox(3)-1); 
imshow(Bound) 

y1 = round(stats(1).BoundingBox(2)) 
y2 = round(stats(1).BoundingBox(2)+stats(1).BoundingBox(4)-1) 
x1 = round(stats(1).BoundingBox(1)) 
x2 = round(stats(1).BoundingBox(1)+stats(1).BoundingBox(3)-1) 

% Bounding box contida em imagem[M, N]. 

[M,N] = size(Bound) 
vertical=0; 
horizontal=0; 
if M > N 
    vertical = 1 %imagem vertical 
else 
    horizontal = 1 %imagem horizontal 
end 

%Find thumb 

MaoLeft = 0; 
MaoRight = 0; 
nPixelsBrancos = 0; 

if vertical==1 
for i = x1:1:x2 
    for j= y1:1:y2 
     if I2(j,i) == 1 
      nPixelsBrancos = nPixelsBrancos + 1; %Numero de pixels da mão 
     end 
    end 
end 

for i=x1:1:x1+30 
    for j=y1:1:y2 
     if I2(j,i) == 1 
      MaoLeft = MaoLeft + 1; %Number of pixels of the hand between the 30 first colums 
     end 
    end 
end 

for i=x2-30:1:x2 
    for j=y1:1:y2 
     if I2(j,1) == 1 
      MaoRight = MaoRight + 1; %Number of pixels of the hand between the 30 last colums 
     end 
    end 
end 

TaxaBrancoLeft = MaoLeft/nPixelsBrancos 
TaxaBrancoRight = MaoRight/nPixelsBrancos 

if TaxaBrancoLeft <= (7/100) 
    if TaxaBrancoRight <= (7/100) 
     Thumb = 0 %Thumb in both borders is defined as no Thumb. 
    else 
     ThumbEsquerdo = 1 %Thumb on left 
    end 
end 

if TaxaBrancoRight <= (7/100) && TaxaBrancoLeft >= (7/100) 
    ThumbDireito = 1 %Thumb on right 
end 
end 

if horizontal==1 
for i = x1:1:x2 
    for j= y1:y2 
     if I2(i,j) == 1 
      nPixelsBrancos = nPixelsBrancos + 1; %Numero de pixels da mão 
     end 
    end 
end 

for i=x1:1:x2 
    for j=y1:1:y1+30 
     if I2(i,j) == 1 
      MaoLeft = MaoLeft + 1; %Numero de pixels da mão entre as 30 primeiras colunas 
     end 
    end 
end 

for i=x1:1:x2 
    for j=y2-30:1:y2 
     if I2(j,1) == 1 
      MaoRight = MaoRight + 1; %Numero de pixels da mão entre as 30 ultimas colunas 
     end 
    end 
end 
TaxaBrancoLeft = MaoLeft/nPixelsBrancos 
TaxaBrancoRight = MaoRight/nPixelsBrancos 

if TaxaBrancoLeft <= (7/100) 
    if TaxaBrancoRight <= (7/100) 
     Thumb = 0 %Polegar nas duas bordas. Definimos como sem polegar. 
    else 
     ThumbEsquerdo = 1 %Polegar na borda esquerda 
    end 
end 

if TaxaBrancoRight <= (7/100) && TaxaBrancoLeft >= (7/100) 
    ThumbDireito = 1 %Polegar na borda direita 
end 
end 
figure 
imshow(I2); 

%detecção da centroid 
Ibw = im2bw(I2); 

Ilabel = bwlabel(Ibw); 
stat = regionprops(Ilabel,'centroid'); 
figure 
imshow(I2); hold on; 

for x = 1: numel(stat) 
    plot(stat(x).Centroid(1),stat(x).Centroid(2),'ro'); 
end 

centroid = [stat(x).Centroid(1) stat(x).Centroid(2)] %coordenadas x e y da centroid 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
+0

你甚至嘗試了谷歌搜索?這是我想出的一篇論文:http://www.enggjournals.com/ijcse/doc/IJCSE12-04-03-092.pdf – rayryeng 2014-11-25 01:34:58

+0

其實,我嘗試過。我們也將算法基於一篇論文,但它只是說突然增加時峯值被認爲是手指,但我們不知道我們能做些什麼來正確地找到增加。但是,無論如何感謝紙張 – 2014-11-25 20:16:50

回答

2

看起來像一個有趣的問題,所以我給了它一個鏡頭。基本上,您首先使用索貝爾過濾器來查找圖像中的邊緣(輕微去噪後)。然後清理生成的線條,使用它們分離手部二進制蒙版內的區域,使用分水嶺變換找到手腕,進行一段距離變換以找到其他地標,然後移除手掌。你留下的是每個手指和拇指分開的區域。你可以很容易地計算這些區域,或者找出它們指向哪個方向,或者任何你想要的。

imgURL = 'https://encrypted-tbn2.gstatic.com/imgs?q=tbn:ANd9GcRQsqJtlrOnSbJNTnj35Z0uG9BXsecX2AXn1vV0YDKodq-zSuqnnQ'; 

imgIn=imread(imgURL); 

gaussfilt = fspecial('gaussian', 3, .5); % Blur starting image 
blurImg = imfilter(double(img(:,:,1)), gaussfilt); 

edgeImg = edge(blurImg, 'sobel'); % Use Sobel edge filter to pick out contours of hand + fingers 
% Clean up contours 
edgeImg = bwmorph(edgeImg, 'close', 1); 
edgeImg = bwmorph(edgeImg, 'thin', Inf); 

% Clean up rogue spots in corners 
edgeImg([2 end-1], 2) = 0; 
edgeImg([2 end-1], end-1) = 0; 

% Extend lines to edge of image (correct for 'close' operation above 
edgeImg([1 end],:) = edgeImg([2 end-1],:); 
edgeImg(:, [1 end]) = edgeImg(:, [2 end-1]); 

% Remove all but the longest line 
regs = regionprops(edgeImg, 'Area', 'PixelIdxList'); 
regs(vertcat(regs.Area) ~= max(vertcat(regs.Area))) = []; 

lineImg = false(size(edgeImg, 1), size(edgeImg, 2)); 
lineImg(regs.PixelIdxList) = 1; 

fillImg = edgeImg; 

% Close in wrist 

if any(fillImg(1,:)) 
    fillImg(1,:) = 1; 
end 

if any(fillImg(end,:)) 
    fillImg(end,:) = 1; 
end 

if any(fillImg(:,1)) 
    fillImg(:,1) = 1; 
end 

if any(fillImg(:,end)) 
    fillImg(:,end) = 1; 
end 

fillImg = imfill(fillImg, 'holes'); 

fillImg([1 end], :) = 0; 
fillImg(:, [1 end]) = 0; 

fillImg([1 end],:) = fillImg([2 end-1],:); 
fillImg(:, [1 end]) = fillImg(:, [2 end-1]); 

% Start segmenting out hand + fingers 
handBin = fillImg; 
% Set lines in above image to 0 to separate closely-spaced fingers 
handBin(lineImg) = 0; 
% Erode these lines to make fingers a bit more separate 
handBin = bwmorph(handBin, 'erode', 1); 

% Segment out just hand (remove wrist) 
distImg = bwdist(~handBin); 

[cDx, cDy] = find(distImg == max(distImg(:))); 

midWrist = distImg; 
midWrist = max(midWrist(:)) - midWrist; 
midWrist(distImg == 0) = Inf; 
wristWatershed = watershed(imerode(midWrist, strel('disk', 10))); 
whichRegion = wristWatershed(cDx, cDy); 
handBin(wristWatershed ~= whichRegion) = 0; 

regs = regionprops(handBin, 'Area', 'PixelIdxList'); 
regs(vertcat(regs.Area) ~= max(vertcat(regs.Area))) = []; 
handOnly = zeros(size(handBin, 1), size(handBin, 2)); 
handOnly(regs.PixelIdxList) = 1; 

% Find radius of circle around palm centroid that excludes wrist and splits 
% fingers into separate regions. 
% This is estimated as D = 1/3 * [(Centroid->Fingertip) + 2*(Centroid->Wrist)] 
% Find Centroid-> Wrist distance 
dist2w = wristWatershed ~= whichRegion; 
dist2w = bwdist(dist2w); 
distToWrist = dist2w(cDx, cDy); 

% Find Centroid-> Fingertip distance 
dist2FE = zeros(size(handOnly, 1), size(handOnly, 2)); 
dist2FE(cDx, cDy) = 1; 
dist2FE = bwdist(dist2FE).*handOnly; 
distToFingerEnd = max(dist2FE(:)); 

circRad = mean([distToFingerEnd, distToWrist, distToWrist]); % Estimage circle diameter 
% Draw circle 
X = bsxfun(@plus,(1:size(handOnly, 1))',zeros(1,size(handOnly, 2))); 
Y = bsxfun(@plus,(1:size(handOnly, 2)),zeros(size(handOnly, 1),1)); 
B = sqrt(sum(bsxfun(@minus,cat(3,X,Y),reshape([cDx, cDy],1,1,[])).^2,3))<=circRad; 
% Cut out binary mask within circle 
handOnly(B) = 0; 

% Label separate regions, where each now corresponds to a separate digit 
fingerCount = bwlabel(handOnly); 

% Display overlay image 
figure() 
imshow(imgIn) 
hold on 
overlayImg = imshow(label2rgb(fingerCount, 'jet', 'k')); 
set(overlayImg, 'AlphaData', 0.5); 
hold off 

結果: http://imgur.com/ySn1fPy

+0

非常好的工作! +1 – rayryeng 2014-11-26 14:29:27