Преобразование изображения RGB в черно-белое распознавание рук PIL - PullRequest
2 голосов
/ 22 сентября 2019

Я пытался написать то же самое, что написано здесь, на python, но мой код не дает хороших результатов.Моя цель - взять RGB-изображение, изменить его размер и преобразовать в YCbCr, а затем установить значение фонового пикселя равным 0, а значение пикселя руки равным 1. Может ли кто-нибудь помочь мне написать этот код на python с использованием PIL, пожалуйста?

(код, который я пытаюсь воспроизвести, у меня возникли проблемы с шагами 3-6)

function image_out = processSkinImage(filename)
    Step 1...
    % Read the image
    original = imread(filename);
    ...
    Step 2...
    % Resize the image to 50x50
    image_resized = imresize(original, scale);
    [M N Z] = size(image_resized);

    % Initialize the output image
    image_out = zeros(height,width);
    image_out = zeros(M,N);
    ...
    Step 3...
    % Convert the image from RGB to YCbCr
    img_ycbcr = rgb2ycbcr(image_resized);
    Cb = img_ycbcr(:,:,2);
    Cr = img_ycbcr(:,:,3);
    ...
    Step 4...
    % Get the central color of the image
    % Expected the hand to be in the central of the image
    central_color = img_ycbcr(int32(M/2),int32(N/2),:);
    Cb_Color = central_color(:,:,2);
    Cr_Color = central_color(:,:,3);
    % Set the range
    Cb_Difference = 15;
    Cr_Difference = 10;
    ...
    Step 5...
    % Detect skin pixels
    [r,c,v] = find(Cb>=Cb_Color-Cr_Difference & Cb<=Cb_Color+Cb_Difference & Cr>=Cr_Color-Cr_Difference & Cr<=Cr_Color+Cr_Difference);
    ...
    Step 6...
    % Mark detected pixels
    for i=1:match_count
        image_out(r(i),c(i)) = 1;
    end
end

это код, который я написал:

from PIL import Image as im

image = im.open('/Users/eitan/Desktop/eell.jpg')
image = image.resize((50,50), im.NEAREST)
grayScale = image.convert(mode='L')

width, height = grayScale.size
mid_pixel=grayScale.getpixel((width/2,height/2))
print (mid_pixel)

pixels = grayScale.load()

for i in range(grayScale.size[0]):    # for every col:
    for j in range(grayScale.size[1]):    # For every row

        if grayScale.getpixel((i,j)) < mid_pixel+40 and grayScale.getpixel((i,j)) > mid_pixel-15:
            pixels[i,j] = 255

        else:
            pixels[i, j] = 0

grayScale.show()

Этопример изображения, которое получит код

И вот как должен выглядеть результат

Было бы здорово, если бы кто-то мог помочь мне написать этот кодв питоне!

1 Ответ

2 голосов
/ 23 сентября 2019

Вы можете подойти к этому следующим образом, где я использовал цветовое пространство HSV, а не YCbCr:

#!/usr/bin/env python3

import numpy as np
from PIL import Image

# Open image and convert to HSV colourspace
im = Image.open('hand.png').convert('HSV')

# Convert to Numpy array
ni = np.array(im)

# Get H, S and V of central pixel - consider taking a median of a larger area here
h,s,v = ni[int(ni.shape[0]/2), int(ni.shape[1]/2)]

# Separate each channel to own array
H = ni[:,:,0]
S = ni[:,:,1]
V = ni[:,:,2]

# Permissible +/- tolerances on each channel
deltah = 20
deltas = 80
deltav = 50

# Make masks of pixels with acceptable H, S and V
hmask = np.where((H > h-deltah) & (H < h+deltah), 255, 0).astype(np.uint8)
smask = np.where((S > s-deltas) & (S < s+deltas), 255, 0).astype(np.uint8)
vmask = np.where((V > v-deltav) & (V < v+deltav), 255, 0).astype(np.uint8)

# Save as images for inspection
Image.fromarray(hmask).save('hmask.png')
Image.fromarray(smask).save('smask.png')
Image.fromarray(vmask).save('vmask.png')

Результирующая маска оттенка:

enter image description here

Результирующая маска насыщения:

enter image description here

Маска результирующего значения:

enter image description here

Затем вы можете И или ИЛИ маски, чтобы получить более сложные комбинации масок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...