Компьютерное зрение: маскировка человеческой руки

Я хотел бы обнаружить свою руку из потокового видео потока и создать маску моей руки. Однако я достигаю довольно низкого результата, как вы можете видеть из картины.

Моя цель - отслеживать движение руки, поэтому я сделал преобразование видеопотока из BGR в цветовое пространство HSV, затем я создал изображение, чтобы изолировать цвет моей руки, а затем попытался найти контуры моей руки, хотя конечный результат не совсем то, чего я хотел достичь.

Как я могу улучшить конечный результат?

import cv2
import numpy as np

cam = cv2.VideoCapture(1)
cam.set(3,640)
cam.set(4,480)
ret, image = cam.read()

skin_min = np.array([0, 40, 150],np.uint8)
skin_max = np.array([20, 150, 255],np.uint8)    
while True:
    ret, image = cam.read()

    gaussian_blur = cv2.GaussianBlur(image,(5,5),0)
    blur_hsv = cv2.cvtColor(gaussian_blur, cv2.COLOR_BGR2HSV)

#threshould using min and max values
    tre_green = cv2.inRange(blur_hsv, skin_min, skin_max)
#getting object green contour
    contours, hierarchy = cv2.findContours(tre_green,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

#draw contours
    cv2.drawContours(image,contours,-1,(0,255,0),3)

    cv2.imshow('real', image)
    cv2.imshow('tre_green', tre_green)   

    key = cv2.waitKey(10)
    if key == 27:
        break

Here the link with the pictures: https://picasaweb.google.com/103610822612915300423/February7201303. New link with image plus contours, mask, and original. https://picasaweb.google.com/103610822612915300423/February7201304

И вот примерная картина сверху:

Sample picture of a torso with arms ... and a hand

11
nl ja de
Вероятно, поток live , я думаю.
добавлено автор Lev Levitsky, источник
Я добавил одно из изображений (меньшее).
добавлено автор unwind, источник
Это не вопрос типа SO; вы заблуждаетесь в лес сложных вопросов алгоритма.
добавлено автор Katriel, источник
@mmgp Я не понимаю, почему запись была бы полезна.
добавлено автор Katriel, источник
@ user1979084 в прямом эфире, вы имеете в виду, что вы записываете его с помощью какой-либо камеры? Вы можете легко создать видео с помощью opencv. Сделайте это и включите ссылку на него.
добавлено автор mmgp, источник
@ user1979084 лучше, чем ничего, но я не понимаю, почему вы просто не записываете его и не публикуете ссылку для этого. Если это связано с тем, что вы не знаете, как использовать VideoWriter в opencv, проверьте stackoverflow.com/a/14439455/1832154 (он почти решает эту проблему с записью, единственное различие заключается в том, что вы будете читать фреймы, а затем писать как в этом связанном ответе).
добавлено автор mmgp, источник
@katrielalex да? Это полезно, поскольку я (или любой, кто интересуется дачей ответа) имеет фактические данные, это совершенно полезно.
добавлено автор mmgp, источник
@ user1979084 ... то, что я вам говорю, это записать его ...
добавлено автор mmgp, источник
@ user1979084 ссылка не работает, страница не найдена.
добавлено автор mmgp, источник
Я не знаю, что это такое, просто включите образец того, с чем вы работаете.
добавлено автор mmgp, источник
Просто включите ссылку. И включить ссылку на/video /, а не отдельные кадры.
добавлено автор mmgp, источник
Включите образец видео, с которым вы столкнулись, в противном случае бессмысленно пытаться угадать, с чем вы на самом деле работаете.
добавлено автор mmgp, источник
@mmgp, извините, мой плохой, пожалуйста, попробуйте сейчас ...
добавлено автор wind85, источник
@mmgp и btw, вы правы, я не знаю, как использовать VideoWriter :(
добавлено автор wind85, источник
@mmgp Я добавил ссылку на изображение origina, изображение + контуры, маску
добавлено автор wind85, источник
@mmgp Я могу опубликовать фотографии, если вам нравится с оригиналом (not_modified)? это будет полезно?
добавлено автор wind85, источник
@katrielalex Я не прошу лучшего алгоритма, я просто не знаю, какой из них следует использовать, чтобы получить лучшую маску ... или, возможно, лучшие значения HSV для распознавания цветов кожи в opencv.
добавлено автор wind85, источник
@mmgp Я не записываю, что это сделано на лету ...
добавлено автор wind85, источник
Большое спасибо @unwind
добавлено автор wind85, источник
К сожалению, это была опечатка, которую я только что установил ссылку с изображениями.
добавлено автор wind85, источник
Это живой эфир. Вам нужен образец?
добавлено автор wind85, источник
Я не могу загрузить фотографии, так как у меня недостаточно очков репутации :(
добавлено автор wind85, источник

2 ответы

Существует много способов выполнить пиксельный порог, чтобы отделить «пиксели кожи» от «не-скиновых пикселей», и есть документы, основанные практически на любом цветовом пространстве (даже с RGB). Таким образом, мой ответ просто основан на бумаге Face Segmentation с использованием карты цвета кожи в приложениях для видеофонов Chai и Ngan. Они работали с цветовым пространством YCbCr и получили неплохие результаты, в документе также упоминается порог, который хорошо подходит для них:

(Cb in [77, 127]) and (Cr in [133, 173])

The thresholds for the Y channel are not specified, but there are papers that mention Y > 80. For your single image, Y in the whole range is fine, i.e. it doesn't matter for actually distinguishing skin.

Вот вход, двоичное изображение в соответствии с указанными порогами и результирующее изображение после отбрасывания небольших компонентов.

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

import sys
import numpy
import cv2

im = cv2.imread(sys.argv[1])
im_ycrcb = cv2.cvtColor(im, cv2.COLOR_BGR2YCR_CB)

skin_ycrcb_mint = numpy.array((0, 133, 77))
skin_ycrcb_maxt = numpy.array((255, 173, 127))
skin_ycrcb = cv2.inRange(im_ycrcb, skin_ycrcb_mint, skin_ycrcb_maxt)
cv2.imwrite(sys.argv[2], skin_ycrcb) # Second image

contours, _ = cv2.findContours(skin_ycrcb, cv2.RETR_EXTERNAL, 
        cv2.CHAIN_APPROX_SIMPLE)
for i, c in enumerate(contours):
    area = cv2.contourArea(c)
    if area > 1000:
        cv2.drawContours(im, contours, i, (255, 0, 0), 3)
cv2.imwrite(sys.argv[3], im)         # Final image

Наконец, есть довольно приличное количество бумаг, которые не полагаются на индивидуальную поэтапную классификацию для этой задачи. Вместо этого они начинаются с базы помеченных изображений, которые, как известно, содержат либо пиксели кожи, либо пиксели без кожи. Из этого они обучают, например, SVM, а затем различают другие входы, основанные на этом классификаторе.

14
добавлено
@mmpg ничего себе это действительно работает удивительно хорошо! Благодарю. У меня была небольшая проблема при использовании cv2.inRange() , но это было решено с помощью min_YCrCb = numpy.array ([0,133,77], numpy.uint8) и max_YCrCb = numpy.array ([255,173,127], numpy.uint8)
добавлено автор samkhan13, источник
@mmpg большое спасибо! Поразительно !!
добавлено автор wind85, источник

Простым и мощным вариантом является обратная проекция гистограммы . Например, создайте двумерную гистограмму с использованием H и S (из цветового пространства HSV) или * и b * (из цветового пространства La * b *), используя пиксели из разных изображений training вашей руки. Затем используйте [cv2.calcBackProject] [1], чтобы классифицировать пиксели в вашем потоке. Это очень быстро, и вы должны получить от 25 до 30 fps легко, я думаю. Обратите внимание, что это способ узнать распределение цветов вашего объекта интереса. Тот же метод может использоваться и в других ситуациях.

3
добавлено
@ TH.thanks для вас ответ, я постараюсь найти некоторые ресурсы по этому вопросу ...
добавлено автор wind85, источник
Python
Python
7 654 участник(ов)

Уютный чат для профессионалов, занимающихся поиском питоньих мудростей. Как не получить бан: https://t.me/ru_python/577926

Python beginners
Python beginners
4 449 участник(ов)

Вопросы про Python для чайников. Cпам и троллинг неприемлем. Не злоупотребляйте стикерами. Частозадаваемые вопросы: https://github.com/ru-python-beginners/faq/blob/master/README.md Статистика тут: https://grstats.me/chat/x4qym2k5uvfkr3al6at7

pro.python
pro.python
1 090 участник(ов)

Сообщество разработчиков под Python Создатель: @rodgelius

Rude Python
Rude Python
971 участник(ов)

Python без „девочек”, здесь матерятся и унижают Django. Not gay friendly. Правила: t.me/rudepython/114107 @rudepython | t.me/rudepython

rupython
rupython
509 участник(ов)

Группа создана с целью оперативного получения ответов на возникающие вопросы по разработке на яп python, смежные темы, а также человеческого общения. Приветствую!

Python-programming
Python-programming
266 участник(ов)

Чат группы вконтакте https://vk.com/python_community