Проблема с BackProjection и Opencv

Я пытаюсь реализовать алгоритм обратного проецирования с opencv для обнаружения рук. Этот алгоритм состоит из нескольких источников. Я попробовал несколько методов, таких как морфология и добавление backgroundSubtraction к проекции, чтобы попытаться получить лучший результат. Я тоже смотрел онлайн. Тем не менее, я продолжаю получать фото ниже. У кого-нибудь есть предложения по поводу того, что я, возможно, делаю неправильно?

-Спасибо

Вот мой код только с обратной проекцией:

import cv2
import numpy as np

#module for esc keyMap on my computer
import keyMappings as kM

#set up webcam
cap = cv2.VideoCapture(0)
cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 1000) 
cap.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 600)

#read a picture of a hand from my desktop
Hand = cv2.imread('/home/lie/Desktop/handPic.jpg')

#convert HSV and calc Histogram of this Pic
hsvHand = cv2.cvtColor(Hand, cv2.COLOR_BGR2HSV)
h,s,v = cv2.split(hsvHand)
roihist = cv2.calcHist([hsvHand], [0,1], None, [180,256],[0,180,0,256])
cv2.normalize(roihist,roihist,0,255,cv2.NORM_MINMAX)

#while not pressing esc
while cv2.waitKey(30) != kM.esc:

  #take pic convert HSV
  _,frame = cap.read() 
  hsvt = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

  #backproject
  dst = cv2.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256],1)


  #filtering
  disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
  cv2.filter2D(dst,-1,disc,dst)



  #threshold
  ret,thresh = cv2.threshold(dst,50,255,0)


   #find contours in thresholded pic
   contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)


   ci =0
   max_area =0

   if len(contours)!=0:
      #find max contour
      for i in range(len(contours)):
        cnt = contours[i]
        area = cv2.contourArea(cnt)
        if(area>max_area):
            max_area = area
            ci =i
      #create hull around contour
      cnt = contours[ci]
      hull = cv2.convexHull(cnt)

 #Code to draw contours and show pic is ommited

Это изображение используется для распознавания руки:Изображение читается как изображение руки

Это изображение с порогом:

На снимке явно не много руки и много шума.

1 ответ

Решение

После этого поста прошло очень и очень много времени, и, честно говоря, я немного удивлен, что никто не ответил вам. Хотя я совершенно уверен, что вы нашли ответ / альтернативное решение, для блага других я отвечу на это.

То, что вы наблюдаете, напрямую связано с количеством бинов, которые вы используете в своей гистограмме HS. Большее количество бинов означает, что вы будете более точно представлять скин, а это означает, что ваша возможная гистограмма не сможет создать "тренд" кожи. Вы должны абсолютно уменьшить количество корзин. По моему опыту, все, что между 8 и 12 для каналов Hue и Saturation работает хорошо.

Однако выполнение этого не гарантирует очень хорошее изображение с обратной проекцией. У вас все еще есть серьезная проблема, и вы используете весь шаблон руки для создания своей гистограммы. Как таковой, шаблон содержит много кожи, но много области вокруг руки, которая не является кожей. Конечная гистограмма, которую вы сгенерируете, также будет представлять фон. По моему опыту с этим (и у меня его много), даже относительно небольшое количество фильтрации шума в возможной гистограмме вызовет большое количество шума в вашем обратно спроецированном изображении. Ключевым является поддержание фона в вашей гистограмме до минимума. Так что лучше подумайте о том, чтобы взять небольшую область внутри своего шаблона руки и генерировать свою гистограмму только на этом. Я изменил ваш код, как показано ниже, и он работает как сон в моей конфигурации.

Обратите внимание, что я сделал несколько изменений, например, для выхода просто используется кнопка "q", изменен путь к шаблону и т. Д. Он в основном такой же.

import cv2
import numpy as np


#set up webcam

cap = cv2.VideoCapture(0)
#cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 640)
#cap.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 480)

#read a picture of a hand from my desktop
Hand = cv2.imread('handPic.jpg')
hh,hw, __ = Hand.shape
#convert HSV and calc Histogram of this Pic
hsvHand = cv2.cvtColor(Hand[220:292, 110:220], cv2.COLOR_BGR2HSV)
h,s,v = cv2.split(hsvHand)
roihist = cv2.calcHist([hsvHand], [0,1], None, [12,12],[0,181,0,256])
#cv2.normalize(roihist,roihist,0,255,cv2.NORM_MINMAX)

#while not pressing esc
while cv2.waitKey(30) & 0xFF != ord('q'):

  #take pic convert HSV
  _,frame = cap.read()
  hsvt = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

  #backproject
  dst = cv2.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256],1)


  #filtering

  # ret, dst = cv2.threshold(dst,0,255,cv2.THRESH_OTSU)

  disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
  cv2.filter2D(dst,-1,disc,dst)


  cv2.imshow("Skin Areas", dst)
Другие вопросы по тегам