MeanShift와 CamShift로 물체를 추적할 수 있다. 배경을 제거하기 위해 backprojection을 어떻게 사용하는지 알아야 했다.
back projection은 배경 등 변화가 없는 이미지를 마스킹하기 위해 사용한다. 다음 동영상을 보면 알기 쉽다. cv2.imshow는 여러 창을 보여주지 못한다. matplot.pyplot을 사용했다. opencv의 색과 matplot.pyplot 색이 다르기 때문에 변경해야 제대로 표시된다.
class BackProjection(object):
def __init__(self):
self._imgPath = "./20160910_134843_2.jpg"
self._img = cv2.imread("./20160910_134843_2.jpg",cv2.IMREAD_COLOR)
self._roi = cv2.imread("./roi2.jpg")
scale_percent = 40 # percent of original size
self._width = int(self._img.shape[1] * scale_percent / 100)
self._height = int(self._img.shape[0] * scale_percent / 100)
self._dim = (self._width, self._height)
self._hsv = cv2.cvtColor(self._img, cv2.COLOR_BGR2HSV)
self._roi_hsv = cv2.cvtColor(self._roi, cv2.COLOR_BGR2HSV)
self._roi_hist = cv2.calcHist([self._roi_hsv],[0,1], None, [180,256],[0,180,0,256])
self._mask = cv2.calcBackProject([self._hsv], [0,1], self._roi_hist, [0, 180, 0, 256],1)
#kernel
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
self._mask = cv2.filter2D(self._mask, -1, kernel)
_, self._mask = cv2.threshold(self._mask, 50, 255, cv2.THRESH_BINARY)
self._mask = cv2.merge((self._mask, self._mask, self._mask))
self._result = cv2.bitwise_and(self._img, self._mask)
def run(self):
cv2.resize(self._img,self._dim,interpolation=cv2.INTER_AREA)
plt.figure(1)
plt.imshow(self._mask)
plt.figure(2)
#matplot으로 표시하면 BRG을 RGB로 바꿔야 됨
plt.imshow(cv2.cvtColor(self._img, cv2.COLOR_BGR2RGB))
plt.figure(3)
plt.imshow(cv2.cvtColor(self._result, cv2.COLOR_BGR2RGB))
plt.show()
if __name__ == '__main__':
BackProjection().run()




결과를 보면 배경을 깔끔하게 지우지 못했다. 이미지 어느 부분을 roi_hsv로 설정하냐에 배경을 어떻게 지울지 결정한다. 더 나가 camshift로 물체를 추적할 수 있다. 그러나 값을 어떻게 넣고 배경이 어떤지에 따라 많은 영향을 받는다. 결국은 노가다..