Opencv

Anaconda OpenCV 및 imutils 설치와 웹캠에 의한 컴퓨터 비전

coding art 2020. 2. 7. 16:17
728x90

파이선 코딩 초보자를 위한 텐서플로우∙OpenCV 머신 러닝 2차 개정판 발행

http://blog.daum.net/ejleep1/1175

 

파이선 코딩 초보자를 위한 텐서플로우∙OpenCV 머신 러닝 2차 개정판 (하이퍼링크) 목차 pdf 파일

본서는 이미 2021년 11월 초부터 POD코너에서 주문 구입이 가능합니다. 참고로 책 목차에 따른 내용별 학습을 위한 코드는 이미 대부분 다음(Daum)블로그에 보관되어 있으며 아래에서 클릭하면 해당

blog.daum.net

 

윈도우즈10에서 TensoFlow 가상환경을 설정한 후 기본적으로 필요한 라이브러리들로서 Panda, Keras, Matplotlib, Scikit-learn 들을 설치하였다.

 

한편 윈도우즈10 Anaconda에서 컴퓨터 비전 파이선 코드를 다루기 위해서는 opencv-python imutils 라이브러리를 추가로 설치해야 한다. 아울러 카메라로서는 라즈베리파이나 Jetson Nano에서 사용하는 Pi Camera 대신 비슷한 가격대의 로지텍사의 USB C270 웹캠 설치를 추천한다. C270 설치는 로지텍사의 홈페이지에서 드라이버를 다운받아 설치하면 끝나는 간단한 작업이다. 설치가 되었으면 드라이버 소프트웨어로 웹캠을 실행시킬 수 있으며 한편으로는 윈도우즈10의 시작 바의 카메라 아이콘을 사용하여 실행이 가능하기도 하다. 이와 같이 카메라 설치가 된 상태에서 아나콘다가 OpenCV 와 함께 설치되었다면 자동적으로 웹캠 인식이 가능해진다.

OpenCV 라이브러리 설치는 앞서 언급했던 라이브러리들과는 달리 다음과 같이 좀 다른 명령을 사용한다. 추가로 imutils 라이브러리도 함께 설치해야 한다.

pip install opencv-python

pip install imutils

 

 

설치된 OpenCV를 확인 실행해 보기 위해서는 라즈베리 파이 분야에서 선도적으로 파이선 코드를 게재하는 Adrian의 블로그 오픈소스 파이선 코드를 사용해 보도록 하자. 다음 URL 주소를 참조하자.

https://www.pyimagesearch.com/2015/09/14/ball-tracking-with-opencv/

  

가상환경에 설치한 imutils 라이브러리에 의해 윈도우즈10 시스템에 설치된 웹캠의 비데오 데이터를 VideoCapture 명령을 사용하여 읽어 들이게 된다. 파이선 라이브러리인 argparsecommand line 명령 방식에 의한 파이선 실행 명령을 지원한다. RUN + 파일명 구조의 간단한 파이선 실행 명령 외에도 입력 파일과 출력 파일을 추가하여 구성되는 즉 RUN + 파일명 + 입력 파일 + 출력파일 형태의 command line 명령을 읽어서 분석 지원해 주는 라이브러리이다.

 

이어지는 While True: 문은 매 초당 지정된 frame 수만큼 비데오를 캡츄어해서 imshow 명령에 의해 가시적으로 보여준다. frame 수는 최소 30 이상이며 매 frame 별로 컬러 오브젝트에 대한 머신 러닝이 이루어진다. 한편 자판에서 q를 입력하면 비데오 카메라 기능이 멈춰지게 된다.

 

Adrian의 블로그 본문에서 블록별로 설명하는 코드를 복사하여 조합해서 실행하면 된다.

준비해야 할 컬러 오브젝트로서 테니스 공이나 초록빛 나는 공이 하나 필요하며 실제 웹캠 앞에서 시연할 경우 웹캠과 공과의 적당한 초점 거리를 유지해야 한다.

빨간색 꼬리는 컬러 오브젝트의 중심의 궤적이다. 조명 상태와 웹캠의 초점 거리의 영향으로 Hue에 의해 검출되는 컬러 볼과 원형 경계선이 정확하게 일치하지 않는 현상이 나타나기도 한다.

 

이와 같이 컬러 볼 추적이 가능하다는 것은 OpenCV에서 제공하는 머신 러닝 기능들 사용이 가능하다는 뜻이며 특히 Haarcascade 방식에 의한 안면인식(Face recognition)도 가능해진다.

 

첨부된 코드의 배경설명은 2019년에 라즈베리파이 보드에서 실행했던 다음 URL 주소를 참조하기 바란다.

https://steemit.com/kr/@codingart/6-19-green-and-blue-ball-tracking-in-opencv

 

웹캠을 설치하고 녹색 공을 준비한 후 첨부된 스크립트 파일을 다운받아 실행해 보자.

opencv_ball_tracking_01.py
0.00MB

또는 아래 코드를 복사하여 실행해도 무방하다.

 

#opencv_ball_tracking_01.py


from collections import deque
from imutils.video import VideoStream
import numpy as np
import argparse
import cv2
import imutils
import time

# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video",
 help="path to the (optional) video file")
ap.add_argument("-b", "--buffer", type=int, default=64,
 help="max buffer size")
args = vars(ap.parse_args())

# define the lower and upper boundaries of the "green"
# ball in the HSV color space, then initialize the
# list of tracked points
greenLower = (29, 86, 6)
greenUpper = (64, 255, 255)
pts = deque(maxlen=args["buffer"])

# if a video path was not supplied, grab the reference
# to the webcam
if not args.get("video", False):
 vs = VideoStream(src=0).start()

# otherwise, grab a reference to the video file
else:
 vs = cv2.VideoCapture(args["video"])

# allow the camera or video file to warm up
time.sleep(2.0)

# keep looping
while True:
 # grab the current frame
 frame = vs.read()

 # handle the frame from VideoCapture or VideoStream
 frame = frame[1] if args.get("video", False) else frame

 # if we are viewing a video and we did not grab a frame,
 # then we have reached the end of the video
 if frame is None:
  break

 # resize the frame, blur it, and convert it to the HSV
 # color space
 frame = imutils.resize(frame, width=600)
 blurred = cv2.GaussianBlur(frame, (11, 11), 0)
 hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV)

 # construct a mask for the color "green", then perform
 # a series of dilations and erosions to remove any small
 # blobs left in the mask
 mask = cv2.inRange(hsv, greenLower, greenUpper)
 mask = cv2.erode(mask, None, iterations=2)
 mask = cv2.dilate(mask, None, iterations=2)
   
    #frame :
 # find contours in the mask and initialize the current
 # (x, y) center of the ball
 cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
  cv2.CHAIN_APPROX_SIMPLE)
 cnts = imutils.grab_contours(cnts)
 center = None

 # only proceed if at least one contour was found
 if len(cnts) > 0:
  # find the largest contour in the mask, then use
  # it to compute the minimum enclosing circle and
  # centroid
  c = max(cnts, key=cv2.contourArea)
  ((x, y), radius) = cv2.minEnclosingCircle(c)
  M = cv2.moments(c)
  center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))

  # only proceed if the radius meets a minimum size
  if radius > 10:
   # draw the circle and centroid on the frame,
   # then update the list of tracked points
   cv2.circle(frame, (int(x), int(y)), int(radius),
    (0, 255, 255), 2)
   cv2.circle(frame, center, 5, (0, 0, 255), -1)

 # update the points queue
 pts.appendleft(center)

 # loop over the set of tracked points
 for i in range(1, len(pts)):
  # if either of the tracked points are None, ignore
  # them
  if pts[i - 1] is None or pts[i] is None:
   continue

  # otherwise, compute the thickness of the line and
  # draw the connecting lines
  thickness = int(np.sqrt(args["buffer"] / float(i + 1)) * 2.5)
  cv2.line(frame, pts[i - 1], pts[i], (0, 0, 255), thickness)

 # show the frame to our screen
 cv2.imshow("Frame", frame)
 key = cv2.waitKey(1) & 0xFF

 # if the 'q' key is pressed, stop the loop
 if key == ord("q"):
  break

# if we are not using a video file, stop the camera video stream
if not args.get("video", False):
 vs.stop()

# otherwise, release the camera
else:
 vs.release()

# close all windows
cv2.destroyAllWindows()