[태그:] meanshift

  • Learning OpenCV 4 Computer Vision with Python 3, object detecion

    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()
    원본 이미지
    masking 이미지
    roi 히스트그램, hsv
    결과 이미지

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

    https://docs.opencv.org/4.4.0/d7/d00/tutorial_meanshift.html
    https://docs.opencv.org/3.4/da/d7f/tutorial_back_projection.html
    https://stackoverflow.com/questions/44598124/update-frame-in-matplotlib-with-live-camera-preview