Вопрос

I'm working on hand detection and tracking. the problem is i have developed the code(shown below) for detecting hand in an image and its works(shown in image) but the problem is this that when i use a recorded video to run the same code no hand is detected or even tracked(shown in image).

Hand Detected of image snippet of the recorded video

Snippet from video no hand detected

the code for the video is

filename = 'hand_2.wmv';
video = vision.VideoFileReader(filename);
player = vision.DeployableVideoPlayer('Location', [10,100],'FrameRate',60);

while ~isDone(video)
    img_orig = step(video);

    % Capture the dimensions
    height = size(img_orig,1);
    width = size(img_orig,2);

    %Initialize the output images
    out = img_orig;
    bin = zeros(height,width);

    %Convert the image from RGB to YCbCr
    img_uint8 = uint8(img_orig);
    img_ycbcr = rgb2ycbcr(img_uint8);
    Cb = img_ycbcr(:,:,2);
    Cr = img_ycbcr(:,:,3);

    %Detect Skin
    [r,c,v] = find(Cb>=67 & Cb<=137 & Cr>=133 & Cr<=173);
    numind = size(r,1);

    %Mark Skin Pixels
    for i=1:numind
        out(r(i),c(i),:) = [0 0 255];
        bin(r(i),c(i)) = 1;
    end

    % Detect radius
    [x1,y1] = find(out(:,:,3) == 255, 1,'first');
    [x2,y2] = find(out(:,:,3) == 255, 1, 'last');
    if isempty(y1) && isempty(y2)
        y1 = 2; y2 = 0;
    end

    % Detect Hand Center
    hits = 0;
    hitsArr = zeros(1,height);
    for i = 1:height
        hits = numel(find(bin(i,:) == 1));
        hitsArr(i) = hits;
    end
    maxHitr = max(hitsArr);
    y =  find(hitsArr == maxHitr,1,'first');

    hitsArr = zeros(1,width);
    for i = 1:width
        hits = numel(find(bin(:,i) == 1));
        hitsArr(i) = hits;
    end
    maxHitc = max(hitsArr);
    x = find(hitsArr == maxHitc,1,'first');

    label = 'Hand';
    position = [x y abs(y2-y1)/2; x y 1];
    img_out = insertObjectAnnotation(img_orig,'Circle',position,label);
    step(player, img_out);

end

release(video);
release(player);

and for detecting a single image the code is:

%Read the image, and capture the dimensions
tic;
img_orig = imread('65.png');
height = size(img_orig,1);
width = size(img_orig,2);

%Initialize the output images
out = img_orig;
bin = zeros(height,width);

%Convert the image from RGB to YCbCr
img_ycbcr = rgb2ycbcr(img_orig);
Cb = img_ycbcr(:,:,2);
Cr = img_ycbcr(:,:,3);


%Detect Skin
[r,c,v] = find(Cb>=67 & Cb<=137 & Cr>=133 & Cr<=173);
numind = size(r,1);
numcol = size(r,2);

%Mark Skin Pixels
for i=1:numind
    out(r(i),c(i),:) = [0 0 255];
    bin(r(i),c(i)) = 1;
end

% Detect radius
[x1,y1] = find(out(:,:,3) == 255, 1,'first');
[x2,y2] = find(out(:,:,3) == 255, 1, 'last');

% Detect Hand Center
hits = 0;
hitsArr = zeros(1,height);
for i = 1:height
    hits = numel(find(bin(i,:) == 1));
    hitsArr(i) = hits;
end
maxHitr = max(hitsArr);
y =  find(hitsArr == maxHitr,1,'first');

hitsArr = zeros(1,width);
for i = 1:width
    hits = numel(find(bin(:,i) == 1));
    hitsArr(i) = hits;
end
maxHitc = max(hitsArr);
x = find(hitsArr == maxHitc,1,'first');

label = 'Hand';
position = [x y abs(y2-y1)/2; x y 1];
img_out = insertObjectAnnotation(img_orig,'Circle',position,label);
imshow(img_orig);
figure; imshow(img_out);title('Detected hand');
imwrite(img_out,'hand_detect.jpg');
% viscircles([x y],abs(y2-y1)/2,'EdgeColor','r');
% viscircles([x y],1,'EdgeColor','r');
% figure; imshow(out);
figure; imshow(bin);
toc;

I first thought that it was because the frame rate of the video but changing it doesn't help either. and as said above when i run the video to do the detection and tracking the code fails. Any help will be appreciated.

Это было полезно?

Решение

This is happening because when you read an image from a png file you get a uint8 image with pixels values between 0 and 255. On the other hand, vision.VideoFileReader gives you an image of class single with pixel values normalized to be between 0 and 1. You can fix this by setting 'VideoOutputDataType' to 'uint8':

video = vision.VideoFileReader(filename, 'VideoOutputDataType', 'uint8');

On a different topic, if you want to track the hand you may want to try using vision.HistogramBasedTracker or vision.PointTracker.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top