1. Learning OpenCV 4 Computer Vision with Python 3 - Third Edition (저자 : Joseph Howse, Joe Minichino)

github.com/PacktPublishing/Learning-OpenCV-4-Computer-Vision-with-Python-Third-Edition

 

 

[참고]

  • 파이썬과 OpenCV를 이용한 컴퓨터 비전 학습 / 에이콘 출판 / 알렉세이 스피퀘보이, 알렉산드르 류브니코프 저 / T4 역
  • OpenCV Python 강좌 - 영상 이진화 (티스토리 멈춤보단 천천히라도) : https://webnautes.tistory.com/1254

1.Otsu 알고리즘을 사용한 이미지 이진화

  • 입력된 이미지(or 영상)를 GRAY로 변환해야 Otsu 알고리즘 적용 가능
import cv2
import numpy as np 
import matplotlib.pyplot as plt

img = cv2.VideoCapture(0)

ret, frame = img.read()

gray_img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
       
otsu_thr, otsu_mask = cv2.threshold(gray_img, -1, 1, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
print('Estimated threshold (Otsu): ', otsu_thr)
    
plt.figure()
plt.subplot(121)
plt.axis('off')
plt.title('original')
plt.imshow(frame, cmap='gray')
plt.subplot(122)
plt.axis('off')
plt.title('Otsu threshold')
plt.imshow(otsu_mask, cmap = 'gray')
plt.tight_layout()
plt.show()

[결과]

 

2. Otsu + 가우시안 필터 

import cv2
import numpy as np 

img = cv2.VideoCapture(0)

while True:
    ret, frame = img.read()

    gray_img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    ret, img_result1 = cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY)
    ret, img_result2 = cv2.threshold(gray_img, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
    
    img_blur = cv2.GaussianBlur(gray_img, (5,5), 0)
    ret, img_result3 = cv2.threshold(img_blur, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    
    k = cv2.waitKey(3) & 0xFF

    if k == 27:
        break
    
    cv2.imshow('BINARY', img_result1)
    cv2.imshow('THRESH_OTSU', img_result2)
    cv2.imshow('THRESH_OTSU + Gaussian filtering', img_result3)

img.release()
cv2.destroyAllWindows()

[결과]

 

[참고]

1. USB 카메라 영상(컬러) 

#UBS 카메라 실시간 영상 스트리밍
#Windows10, PC 사용

import numpy as np 
import cv2

img = cv2.VideoCapture(0)

while True:
    ret, frame = img.read()
    
    k = cv2.waitKey(3) & 0xFF

    if k == 27:
        break

    cv2.imshow('frame', frame)

img.release()
cv2.destroyAllWindows()

 

2. USB 카메라 영상(흑백)

import numpy as np 
import cv2

img = cv2.VideoCapture(0)

while True:
    ret, frame = img.read()
    
    gray_img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    k = cv2.waitKey(3) & 0xFF

    if k == 27:
        break

    # cv2.imshow('frame', frame)
    cv2.imshow('gray_img', gray_img)

img.release()
cv2.destroyAllWindows()

 

3. THRESHOLD

import numpy as np 
import cv2

img = cv2.VideoCapture(0)

while True:
    ret, frame = img.read()
    
    gray_img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    ret, thr1 = cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY)
    ret, thr2 = cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY_INV)
    ret, thr3 = cv2.threshold(gray_img, 127, 255, cv2.THRESH_TRUNC)
    ret, thr4 = cv2.threshold(gray_img, 127, 255, cv2.THRESH_TOZERO)
    ret, thr5 = cv2.threshold(gray_img, 127, 255, cv2.THRESH_TOZERO_INV)
    
    k = cv2.waitKey(3) & 0xFF

    if k == 27:
        break

    # cv2.imshow('frame', frame)
    cv2.imshow('gray_img', gray_img)
    cv2.imshow('BINARY', thr1)
    cv2.imshow('BINARY_INV', thr2)
    cv2.imshow('TRUNC', thr3)
    cv2.imshow('TOZERO', thr4)
    cv2.imshow('TOZERO_INV', thr5)

img.release()
cv2.destroyAllWindows()

[결과]

[참고]

 

[상황]

  • Dlib 란 실제 세계의 문제를 C++의 복잡한 소프트웨어를 만드는 도구와 기계학습 알고리즘을 포함한 현대의 C++ 툴킷이다. 로보틱스, 임베디드 장치, 모바일 폰, 고성능 컴퓨팅 환경을 포함한 산업과 학계에서 사용된다. (여기까지 의역) 이런 라이브러리가 파이썬 예제가 있어서 설치를 진행해 봤다.

[결론]

  • 기존 사용하고 있는 파이썬 3.7(winodws10 환경)을 결국 제거하고 파이썬 3.6 버전을 설치함.
  • 그런데도 설치가 잘 안 됨

[실행]

  • c:\>python -m pip install --user opencv-python (opeCV와 numpy가 설치 됨)
  • c:\>python -m pip install --user dlib (설치 안 됨)

  • dlib를 설치하려면 CMake를 설치해야 한다고? 
  • Sulastri(참고3번째 ) 님의 순서를 따라했더니 설치 된다! 이때 다운로드에 dlib를 설치하면 install이 안 됨. 신기하게 c:\에 다운받아 압출풀고 빌드하면 실행 됨
  • C:\dlib-19.17>python setup.py build
  • C:\dlib-19.17>python setup.py install
  • C:\dlib-19.17>python
  • >>>import dlib      #(확인)
  • 오류 안 뜨면 설치 완료

[참고]

 

[코드]

import cv2

capture = cv2.VideoCapture(0)
capture.set(cv2.CAP_PROP_AUTOFOCUS, 0)  # AUTOFOCUS 끄기

while True:
    has_frame, frame = capture.read()
    if not has_frame:
        print('Can\'t get frame')
        break
    
    cv2.imshow('frame', frame)
    key = cv2.waitKey(3)
    if key == 27:
        print('Pressed ESC')
        break

capture.release()
cv2.destroyAllWindows()

[설명]

  • 코드 한줄만 추가하면 됨
  • python의 간결함에 다시 한번 감탄함

[참고]

 

1. 원, 직선 그리기

 

[코드]

import cv2
import numpy as np 

img = np.zeros((500,500), np.uint8)
cv2.circle(img, (200,200), 50, 255, 3)
cv2.line(img, (100, 400), (400, 350), 255, 3)

cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()

[결과]

원,선 그리기

2. 직선 좌표 구하기

import cv2
import numpy as np 

img = np.zeros((500,500), np.uint8)

cv2.line(img, (100, 400), (400, 350), 255, 3)

lines = cv2.HoughLinesP(img, 1, np.pi/180, 100, 100, 10)[0]

dbg_img = np.zeros((img.shape[0], img.shape[1], 3), np.uint8)
for x1, y1, x2, y2 in lines:
    print('Detected line: ({} {}) ({} {})'.format(x1,y1,x2,y2))
    cv2.line(dbg_img, (x1,y1), (x2,y2), (0,255,0),2)

cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()

[결과]

 

 Detected line: (100 402) (401 349)

 

3. 원 중심, 반지름(raidus) 구하기

 

[코드]

import cv2
import numpy as np 

img = np.zeros((500,500), np.uint8)
cv2.circle(img, (200,200), 50, 255, 3)

circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 15, param1 = 200, param2 = 30)[0]

dbg_img = np.zeros((img.shape[0], img.shape[1], 3), np.uint8)

for c in circles:
    print('Detected circle: center = ({} {}), radius = {}'.format(c[0],c[1],c[2]))
    cv2.circle(dbg_img, (c[0], c[1]), c[2], (0,255,0), 2)

cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()

[결과]

 

Detected circle: center = (199.5 199.5), radius = 47.29999923706055

 

 

4. 이미지로부터 원의 중심점 찾기

 

[코드]

import cv2
import numpy as np 

img = cv2.imread('do.jpg')
img = cv2.medianBlur(img, 5)
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 15, param1 = 200, param2 = 30)[0]

dbg_img = np.zeros((img.shape[0], img.shape[1], 3), np.uint8)

for c in circles:
    print('Detected circle: center = ({} {}), radius = {}'.format(c[0],c[1],c[2]))
    cv2.circle(dbg_img, (c[0], c[1]), c[2], (0,255,0), 2)

cv2.imshow('img', img)
cv2.imshow('dbg_img', dbg_img)
cv2.waitKey()
cv2.destroyAllWindows()

 

[결과]

Detected circle: center = (319.5 319.5), radius = 57.400001525878906
Detected circle: center = (212.5 55.5), radius = 49.599998474121094

 

 

[참고]

1. cv2.inRange(src, lowerb, upperb[, dst]) -> dst

  • 입력 src의 각 화소가 lowerb(i) ≤ src(i)  ≤ upperb(i) 범위에 있으면 dst(i) = 255, 그렇지 않으면 dst(i) = 0 임
  • lowerb와 upperb는 Scalar도 가능. dst는 src와 같은 크기의 8비트 부호 없는 정수 자료형임
  • src가 다중 채널인 경우, 모든 채널에 대한 범위를 만족해야 함
  • 3-채널 컬러영상에서 HSV 색상으로 변환 후, 색상 범위 지정하면 손, 얼굴 등의 피부 검출할 때 유용함

[참고]

 

1. Color Image

  • Color Image는 pixel 당 24 bit 사용 (총 16,777,216가지 색 표현 가능). 일반적으로 True color image라고 함.
  • pixel은 RGB 각각을 위해 8bit 사용
  • OpenCV에서는 BGR로 표현 (그림판 색선택 이용 시 좌표가 반대(RGB)임)
  • Blue : (255,0,0), Green : (0,255,0), Red : (0,0,255), White : (255,255,255), Black : (0,0,0)
  • 각 pixel 당 3byte를 사용하기 때문에 용량이 큼. 이를 해결하기 위해 lookup table을 사용하여, 해당 pixel에 index만 저장

2. HSV Color-space

  • H(ue) : 색상. 일반적인 색 의미.  (0도 : Red, 120도 : Green, 240도 : Blue)
  • S(aturation) : 채도. 색의 순수성 의미. 일반적으로 짙다, 흐리다로 표현. 중심에서 바깥쪽으로 이동하면 채도가 높음
  • V(alue) : 명도. 색의 밝고 어두운 정도. 수직축의 깊이로 표현. 어둡다 밝다로 표현이 됨

3. Sample Code

# HSV 변환

import cv2
import numpy as np 

src = cv2.imread('lena.jpg')
hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)

cv2.imshow('src', src)
cv2.imshow('hsv', hsv)

cv2.waitKey()
cv2.destroyAllWindows()

 

[결과]

 

#이미지 영역 설정(그림판 사용해서 값 범위 수작업으로 입력해줌)

import cv2
import numpy as np 

src = cv2.imread('lena.jpg')
hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)

lower = np.array([43,43,117])
upper = np.array([211,220,254])

mask = cv2.inRange(hsv, lower, upper)

cv2.imshow('src', src)
cv2.imshow('hsv', hsv)
cv2.imshow('mask',mask)

cv2.waitKey()
cv2.destroyAllWindows()

[결과]

[그림판]-[색선택]-[색편집]-BGR정보 확인

 

#bit 연산자를 통해서 선택한 영역만 남김

import cv2
import numpy as np 

src = cv2.imread('lena.jpg')
hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)

lower = np.array([43,43,117])
upper = np.array([211,220,254])

mask = cv2.inRange(hsv, lower, upper)

res = cv2.bitwise_and(src, src, mask=mask)

cv2.imshow('src', src)
cv2.imshow('hsv', hsv)
cv2.imshow('mask',mask)
cv2.imshow('res', res)

cv2.waitKey()
cv2.destroyAllWindows()

[결과]

 

[의견]

  • 색이 다양하면 깔끔하게 추출하기가 어려움
  • 예쁜 레나님을 괴물로 만들어서 죄송(ㅠㅠ)

+ Recent posts