[태그:] opencv

  • 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
  • Learning OpenCV 4 Computer Vision with Python 3, Chapter2, Modue2

    삽질로 video로 들어오는 입력을 필터링 했다. cv2.waitKey(delay)가 없으면 프레임을 업데이트 하지 않는다. windowmanager에서 callback 함수를 만들어, 웹캠 캡쳐 -> 파일로 변환 -> 프레임으로 표시 -> 대기 -> 입력을 받음 …반복 이런 식으로 잘~~(노가다 대박) 했다.

    2장부터 각 예제를 따라할 수 있다. 알고리즘을 이해한다기 보다는 이런식으로 사용한다는 느낌이다.

  • Learning OpenCV 4 Computer Vision with Python 3, chapter1

    Learning OpenCV 4 Computer Vision with Python 3, chapter1

    isbn: 978-1789531619

    opencv를 배우려 인터넷을 헤메기 전 적당한 책을 보기로 했다. 역시 찾아보면 인터넷에 있다.

    책에 실린 예제를 실행했다. 객체지향 방식으로 프로그램 하라는데, 기본 개념이 없는 난 잘 못하겠다. 내가 복잡한 프로그램을 작성하지도 않을 듯 하다. callback을 활용하여 window manager를 사용했는데, 찾아보면 알겠지만 일단 그냥 넘어갔다. 이 책이 객체지향을 설명하지 않으니까.

    python은 call by refrence로 값을 전달하는데, 형식이 맞지 않으면 무시되나 보다. 입력으로 보낸 dimension이 100, 100, 3인데 내부에서 계산한 값 dimension이 100, 100, 1이면 값을 써 주질 못한다. 이를 모르고 한참 해맸다. 이미지를 비디오 캡쳐 장치나 파일로 color를 입혀 읽으면 width, height, color = 3 형식을 갖는다. 이 이미지를 edge detection 함수를 통과시키면 width, height, color = 1로 변경된다. filter를 적용하기 전 강제로 틀을 맞춰줬다. 다른 능력자가 쓴 코드를 쓰려니 힘들다.

    docker로 xhost로 실행했는데, cv2.imshow에 좀 문제가 있는 듯 하다. matplot으로 그래프를 바꿀려고 했지만, 나중에 결국 숫자로만 인식할 것 같아 시간을 아끼려 그냥 두었다.

    https://dejavuqa.tistory.com/120
  • face detection 예제

    https://www.analyticsvidhya.com/blog/2018/12/introduction-face-detection-video-deep-learning-python/

    그대로 따라하면 된다. python이 이래서 좋다. 100라인도 안되는 코드로 구현 가능하다!

    https://github.com/ageitgey/face_recognition

  • opencv 시작하기

    유명한 opencv를 시작했다. docker python 이미지를 찾아 쉽게 시작했다. python 3.7, opencv4를 설치한 이미지다.

    docker pull jjanzic/docker-python3-opencv

    몇 번 시행착오를 거쳤으나 여러 사이트를 참조하여 결과만 남긴다. 먼저 docker 내용을 host에 넘기기 위해 xhost +를 실행했다. 그 뒤 sudo 명령어로 docker를 실행했다. 여기에 좋은 내용이 있다. docker run 옵션은 다음과 같다.

    sudo docker run --device=/dev/video0:/dev/video0 -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=$DISPLAY -p 5000:5000 -p 8888:8888 -it -v /home/now0930/codeForPython3/opencv:/home/code  --env QT_X11_NO_MITSHM=1 jjanzic/docker-python3-opencv_modified /bin/bash

    중간에 –env QT_X11_NO_MITSHM=1 를 넣어 시작하지 않으면 다음 에러가 난다.

    cv2.error: OpenCV(4.1.1) /opencv-4.1.1/modules/highgui/src/window.cpp:627: error: (-2:Unspecified error) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Cocoa support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function 'cvShowImage'

    시작 후 docker 내부에서 pip로 opencv-python 모듈을 설치한다. opencv-python를 설치하지 않으면 video를 사용하여 이미지를 저장할 수 없다.

    python -m pip install opencv-python

    root 권한으로 libget2.0-dev, pkg-config를 설치했는데 영향을 모르겠다. 일단 되니 고.

    apt reinstall libgtk2.0-dev pkg-config

    여기 코드를 그대로 사용하여 실행 됨을 확인한다.

    sudo로 docker를 실행하면 보안 문제가 있다고 한다. video를 사용할 수 있도록 host에 권한을 할당했다.

    sudo usermod -a -G video now0930

    다음을 실행하면, 윈도우가 무한대로 뜬다. cv2.imshow를 하나만 사용해야 된다. 여러 개를 사용하면 무엇이 문제인지 모르겠으나, 안된다. matplot으로 창을 띄워도 되나 너무 느리다. 찾아보면 해결 방법을 찾겠지만, 그냥 cv2.imshow로 가기로 했다.

    import cv2
    import numpy as np
    import matplotlib.pyplot as plt  
    cap = cv2.VideoCapture(0)
    
    #while(1):
    #videocapture로 들어오는 이미지를 matplot으로 실시간 표시
    #plt.ion()
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
    
    while cap.isOpened():
    
        # Take each frame
        _, frame = cap.read()
        # Our operations on the frame come here
        #gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    
        # Convert BGR to HSV
        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
        #hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
        # define range of blue color in HSV
        lower_blue = np.array([110,50,50])
        upper_blue = np.array([130,255,255])
    
        # Threshold the HSV image to get only blue colors
        mask = cv2.inRange(hsv, lower_blue, upper_blue)
    
        # Bitwise-AND mask and original image
        res = cv2.bitwise_and(frame,frame, mask= mask)
    
        #cv2.imshow("frame",frame)
        #cv2.imshow("mask",mask)
        cv2.imshow("res",res)
    
    
        #plt.subplot(2,2,1),plt.imshow(frame)
        #plt.subplot(2,2,2),plt.imshow(mask)
        #plt.subplot(2,2,3),plt.imshow(res)
        #plt.pause(0.001)
        #plt.show()
    
        if cv2.waitKey(10) & 0xFF == ord('q'):
            break
    cv2.destroyAllWindows()