OpenCV: Лукас Канаде применяется в определенной области (для обнаружения черт лица)

Я пытаюсь выполнить отслеживание лица с помощью алгоритма Лукаса Канаде с каскадной классификацией Хаара. Lucas Kanade успешен и может отслеживать пользователя, но, к сожалению, некоторые из хороших функций для обнаружения точек тратятся впустую на углах на заднем плане. Я хочу использовать способность Haar Cascade обнаруживать факт, чтобы получить координаты обнаруженного лица и применить Lucas Kanade только к этой ограниченной области.

По сути, я хочу использовать каскад Хаара для обнаружения фактов, получения значений x, y, w и h и использования этих координат для применения Лукаса Канаде в этой ограниченной области (чтобы ничто не тратилось впустую на назначение хороших функций фону и только распознаются черты лица)

Строка кода, выполняющая алгоритм Лукаса Канаде, выглядит следующим образом:

p0 = cv2.goodFeaturesToTrack(old_gray, mask = None, **feature_params)

Как я могу это сделать?

Код:

from matplotlib import pyplot as plt
import numpy as np

import cv2

rectangle_x = 0

face_classifier = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_default.xml')

cap = cv2.VideoCapture(0)


# params for ShiTomasi corner detection
feature_params = dict( maxCorners = 200,
                       qualityLevel = 0.01,
                       minDistance = 10,
                       blockSize = 7 )

# Parameters for lucas kanade optical flow
lk_params = dict( winSize  = (15,15),
                  maxLevel = 2,
                  criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))

# Create some random colors
color = np.random.randint(0,255,(100,3))

# Take first frame and find corners in it
ret, old_frame = cap.read()

cv2.imshow('Old_Frame', old_frame)
cv2.waitKey(0)
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)
restart = True
face = face_classifier.detectMultiScale(old_gray, 1.2, 4)

if len(face) == 0:
    print "This is empty"

for (x,y,w,h) in face:
    focused_face = old_frame[y: y+h, x: x+w]



cv2.imshow('Old_Frame', old_frame)

face_gray = cv2.cvtColor(old_frame,cv2.COLOR_BGR2GRAY)

gray = cv2.cvtColor(focused_face,cv2.COLOR_BGR2GRAY)

corners_t = cv2.goodFeaturesToTrack(gray, mask = None, **feature_params)
corners = np.int0(corners_t)




for i in corners:
    ix,iy = i.ravel()
    cv2.circle(focused_face,(ix,iy),3,255,-1)
    cv2.circle(old_frame,(x+ix,y+iy),3,255,-1)

    print ix, " ", iy

plt.imshow(old_frame),plt.show()


##########

#############################
p0 = cv2.goodFeaturesToTrack(old_gray, mask = None, **feature_params)
#############################
# Create a mask image for drawing purposes
mask = np.zeros_like(old_frame)

print "X: ", x
print "Y: ", y

while(1):
    ret,frame = cap.read()
    frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # calculate optical flow
    p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)

    # Select good points
    good_new = p1[st==1]
    good_old = p0[st==1]

    # draw the circles
    for i,(new,old) in enumerate(zip(good_new,good_old)):
        a,b = new.ravel()
        c,d = old.ravel()
        cv2.circle(frame,(a, b),5,color[i].tolist(),-1)
        if i == 99:
            break

    cv2.imshow('frame',frame)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break

    # Now update the previous frame and previous points
    old_gray = frame_gray.copy()
    p0 = good_new.reshape(-1,1,2)

cv2.destroyAllWindows()
cap.release()

person user3377126    schedule 15.01.2015    source источник
comment
если цель состоит в том, чтобы получить черты лица - почему бы не использовать библиотеку вроде flandmark - cmp.felk.cvut.cz/~uricamic/flandmark/index.php ? Есть ли причина предпочесть Haar+LK?   -  person kiranpradeep    schedule 15.01.2015
comment
Одна из причин заключается в том, что я программирую его на Python, и я не знаю, совместим ли он вообще. И это также потому, что я делаю это как опыт обучения, я не хочу, чтобы библиотека делала это за меня.   -  person user3377126    schedule 15.01.2015
comment
вместо mask = None просто используйте маску в области, где вы обнаружили лицо... например. маска = нарисуйте белый прямоугольник для каждого лица, которое вы обнаружили на черном изображении того же размера, что и входное изображение (один канал).   -  person Micka    schedule 15.01.2015
comment
Какой будет синтаксис для этого? У меня возникли проблемы с назначением атрибута маски с моими обнаруженными координатами лица (я продолжаю получать ошибки)   -  person user3377126    schedule 15.01.2015


Ответы (1)


Вот фрагмент кода:

p0 = np.array([[[x,y]], [[x0,y0]]], np.float32)

просто замените p0 в исходном коде и назначьте x, x0... желаемыми точками - убедитесь, что это двумерный массив - и тип float 32 для одинарной точности

person Abhijeet Sinha    schedule 25.09.2016
comment
Я не уверен, как это решает проблему. Могли бы вы объяснить? - person James K; 26.09.2016
comment
В учебниках cv2.goodFeaturesToTrack используется для назначения p0 (старый кадр) углов, вместо этого линия, упомянутая выше, назначает p0 с желаемыми пользователем конкретными точками (например, x, y координаты центроида обнаружения лица), поэтому теперь, когда когда-либо рассчитывается p1 (новая точка) он принял во внимание p0, указывающий на x и y. Итак, в конце концов, процесс остается прежним, просто вместо этого мы указываем на желаемое место. Я пробовал этот код, и он отлично работает! - person Abhijeet Sinha; 27.09.2016
comment
вместо [200,200] просто добавьте точку интереса пользователя как [x,y], все как в p0 = np.array([[[x,y]], [[x0,x1]]], np.float32) - person Abhijeet Sinha; 27.09.2016