Computer Vision Day 3

  • 키보드 이벤트 처리
import numpy as np
import cv2
width, height = 512, 512
x, y = width//2, height//2
R = 50
direction = 0  # 0 : right, 1: down, 2: left, 3: up
while True:
    key = cv2.waitKeyEx(30)
    if key == 0x1B:
        break
        
    # 방향키처리    
    elif key == 0x270000: # right
        direction = 0
    elif key == 0x280000: # down
        direction = 1
    elif key == 0x250000: # left
        direction = 2
    elif key == 0x260000: # up
        direction = 3
    
    # 방향에 맞게 x, y 좌표 설정
    
    if direction == 0:
        x += 10
    elif direction == 1:
        y += 10
    elif direction == 2:
        x -= 10
    else:
        y -= 10    
    
    # 경계확인
    if x < R:
        x = R
        direction = 0
    if x > width - R:
        x = width - R
        direction = 2
    
    if y < R:
        y = R
        direction = 1
    if y > height - R:
        y = height - R
        direction = 3
    
    # 지우기, 그리기
    
    img = np.zeros((width, height, 3), np.uint8) + 255
    cv2.circle(img, (x, y), R, (0,0,255), -1)
    cv2.imshow('img', img)
    
cv2.destroyAllWindows()
    
  • 마우스 이벤트 처리
img = np.zeros((512,512,3), np.uint8) + 255

def onMouse(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:
        if flags & cv2.EVENT_FLAG_SHIFTKEY:
            cv2.rectangle(param[0], (x-5, y-5), (x+5, y+5), (255,0,0), 3)
        else:
            cv2.circle(param[0], (x, y), 5, (255,0,0), 3)
        
    elif event == cv2.EVENT_RBUTTONDOWN:
        cv2.circle(param[0], (x, y), 5, (0,0,255), 3)            
        
    elif event == cv2.EVENT_LBUTTONDBLCLK:
        param[0] = np.zeros((512,512,3), np.uint8) + 255
        
    cv2.imshow('img', param[0])

cv2.imshow('img', img)

cv2.setMouseCallback('img', onMouse, [img])
cv2.waitKey()
cv2.destroyAllWindows()
  • 트랙바 이벤트 처리
def onChange(pos):
    global img
    r = cv2.getTrackbarPos('R', 'img')
    g = cv2.getTrackbarPos('G', 'img')
    b = cv2.getTrackbarPos('B', 'img')

    img[:] = (b,g,r)
    cv2.imshow('img', img)    
    
img = np.zeros((512,512,3), np.uint8) + 255
cv2.imshow('img', img)

cv2.createTrackbar('R', 'img', 0, 255, onChange)
cv2.createTrackbar('G', 'img', 0, 255, onChange)
cv2.createTrackbar('B', 'img', 0, 255, onChange)

cv2.setTrackbarPos('B', 'img', 255)

cv2.waitKey()
cv2.destroyAllWindows()
a2 = np.array([[1,2,3],[4,5,6]])
a2[1,1:]
array([5, 6])

OpenCV 기본연산

  • 형상(shape), 자료형(dtype)
img = cv2.imread('./data/lena.jpg') # cv2.IMREAD_COLOR
type(img)
numpy.ndarray
img.ndim
3
img.shape
(512, 512, 3)
img.dtype
dtype('uint8')
img = img.astype(np.int32)
img = np.uint8(img)
img.dtype
dtype('uint8')
  • 모양 변경하기
img = cv2.imread('./data/lena.jpg', cv2.IMREAD_GRAYSCALE)
img.shape
(512, 512)
512 * 512
262144
img = img.flatten()
img.shape
(262144,)
img = img.reshape(512,512)
img.shape
(512, 512)
img = img.flatten()
img = img.reshape(-1, 512, 512)
img.shape
(1, 512, 512)
  • 화소 접근 1 : 그레이 스케일영상
img = cv2.imread('./data/lena.jpg', cv2.IMREAD_GRAYSCALE)

img[100, 200] = 0

img[100:400, 200:500] = 0

cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()
  • 화소 접근 2 : 컬러 영상
img = cv2.imread('./data/lena.jpg', cv2.IMREAD_COLOR)

img[100, 200] = [255,0,0]

img[100:400, 200:300] = [255,0,0]

cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()
  • 화소 접근 3 : 채널 접근
img = cv2.imread('./data/lena.jpg', cv2.IMREAD_COLOR)

img[100:400, 200:300, 0] = 255
img[100:400, 200:300, 1] = 255
img[100:400, 200:300, 2] = 255
 
cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()
  • 마우스로 ROI 영역 지정 : selecROI()
src = cv2.imread('./data/lena.jpg', cv2.IMREAD_GRAYSCALE)
roi = cv2.selectROI(src)

img = src[roi[1]:roi[1]+roi[3], roi[0]:roi[0]+roi[2]]

cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()
roi
(118, 85, 267, 301)
  • 마우스로 다중 ROI 영역 지정: selecROIs()
src = cv2.imread('./data/lena.jpg', cv2.IMREAD_GRAYSCALE)
rois = cv2.selectROIs('src' ,src, True, False)

for r in rois:
    cv2.rectangle(src, (r[0], r[1]), (r[0]+r[2], r[1]+r[3]),255)
    
cv2.imshow('src', src)
cv2.waitKey()
cv2.destroyAllWindows()    
rois
array([[ 58,  64, 171, 200],
       [277,  95, 140, 231],
       [290, 319, 120, 156]], dtype=int32)
  • 블록 평균 영상
src = cv2.imread('./data/lena.jpg', cv2.IMREAD_GRAYSCALE)
dst = np.zeros(src.shape ,dtype=src.dtype)

src.shape

N = 4
height, width = src.shape

h = height // N
w = width // N

for i in range(N):
    for j in range(N):
        x = j*w
        y = i*h
        roi = src[y:y+h, x:x+w]
        dst[y:y+h, x:x+w] = roi.mean()
        
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()        
  • 영상 복사
src = cv2.imread('./data/lena.jpg', cv2.IMREAD_GRAYSCALE)

# dst = src # 참조
dst = src.copy() # 복사

dst[100:400, 200:300] = 0

cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()
src = cv2.imread('./data/lena.jpg', cv2.IMREAD_GRAYSCALE)

shape = src.shape[0], src.shape[1], 3
dst = np.zeros(shape, dtype=np.uint8)

# dst[:, :, 0] = src
# dst[:, :, 1] = src
dst[:, :, 2] = src

cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()
  • 채널 분리
src = cv2.imread('./data/lena.jpg')

dst = cv2.split(src)

cv2.imshow('src', src)
cv2.imshow('blue', dst[0])
cv2.imshow('green', dst[1])
cv2.imshow('red', dst[2])

cv2.waitKey()
cv2.destroyAllWindows()
len(dst)
3
dst[0].shape
(512, 512)
dst[1]
array([[138, 137, 136, ..., 145, 129, 104],
       [137, 137, 137, ..., 150, 132, 102],
       [137, 137, 138, ..., 148, 133, 105],
       ...,
       [ 21,  20,  28, ...,  71,  68,  65],
       [ 18,  19,  32, ...,  69,  71,  72],
       [ 19,  21,  34, ...,  68,  72,  74]], dtype=uint8)
dst[2]
array([[225, 224, 224, ..., 236, 220, 197],
       [224, 224, 224, ..., 235, 217, 189],
       [224, 224, 225, ..., 230, 215, 190],
       ...,
       [ 82,  81,  92, ..., 175, 175, 175],
       [ 80,  81,  96, ..., 177, 181, 183],
       [ 81,  83,  98, ..., 176, 183, 188]], dtype=uint8)
src = cv2.imread('./data/candies.png')

dst = cv2.split(src)

cv2.imshow('src', src)
cv2.imshow('blue', dst[0])
cv2.imshow('green', dst[1])
cv2.imshow('red', dst[2])

cv2.waitKey()
cv2.destroyAllWindows()
  • 채널 병합
merge = cv2.merge([dst[0], dst[1], dst[2]])

cv2.imshow('merge', merge)
cv2.waitKey()
cv2.destroyAllWindows()
  • 색 변환
src = cv2.imread("./data/lena.jpg")

gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
yCrCb = cv2.cvtColor(src, cv2.COLOR_BGR2YCrCb)
hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)

cv2.imshow("gray", gray)
cv2.imshow("yCrCb", yCrCb)
cv2.imshow("hsv", hsv)

cv2.waitKey()
cv2.destroyAllWindows()
bgr = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
cv2.imshow("bgr", bgr)
cv2.waitKey()
cv2.destroyAllWindows()
bgr.shape
(512, 512, 3)
512 * 512
262144
(bgr[:, :, 2] == gray).sum()
262144
  • 영상 크기 변환
src = cv2.imread("./data/lena.jpg", cv2.IMREAD_GRAYSCALE)
dst1 = cv2.resize(src, dsize = (320, 240))
dst2 = cv2.resize(src, dsize = (0, 0), fx=1.5, fy=1.2)

cv2.imshow('dst1', dst1)
cv2.imshow('dst2', dst2)
cv2.waitKey()
cv2.destroyAllWindows()
  • 영상 회전 변환
src = cv2.imread("./data/lena.jpg")

dst1 = cv2.rotate(src, cv2.ROTATE_90_CLOCKWISE)
dst2 = cv2.rotate(src, cv2.ROTATE_90_COUNTERCLOCKWISE)

cv2.imshow('dst1', dst1)
cv2.imshow('dst2', dst2)
cv2.waitKey()
cv2.destroyAllWindows()
src = cv2.imread("./data/lena.jpg")

height, width, channels = src.shape

M1 = cv2.getRotationMatrix2D((height/2, width/2), 45, 0.5)
M2 = cv2.getRotationMatrix2D((height/2, width/2), -45, 0.5)

dst1 = cv2.warpAffine(src, M1, (width, height))
dst2 = cv2.warpAffine(src, M2, (width, height))

cv2.imshow('dst1', dst1)
cv2.imshow('dst2', dst2)
cv2.waitKey()
cv2.destroyAllWindows()
  • 영상 어파인 변환 (모서리 3지점)
src = cv2.imread("./data/tekapo.bmp")

height, width, channels = src.shape

srcPts = np.float32([[0, 0], [width-1, 0], [width-1, height-1]])
dstPts = np.float32([[50, 50], [width-100, 100], [width-50, height-50]])

M = cv2.getAffineTransform(srcPts, dstPts)

dst = cv2.warpAffine(src, M, (width, height))

cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()
  • 영상 이동 변환
src = cv2.imread("./data/tekapo.bmp")

height, width, channels = src.shape

M = np.array([[1, 0, 150], 
             [0, 1, 100]], dtype=np.float64)

dst = cv2.warpAffine(src, M, (width, height))

cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()
  • 영상 대칭 변환
src = cv2.imread("./data/eastsea.bmp")
cv2.imshow("src", src)

dst = cv2.flip(src, -1) # 1 : 좌우대칭, 0 : 상하대칭, -1 : 좌우, 상하대칭

cv2.imshow("dst", dst)
cv2.waitKey()
cv2.destroyAllWindows()
  • 영상 투시 변환
height, width = 300, 200 

cnt = 0

srcQuad = np.zeros((4,2), dtype=np.float32)
# dstQuad = np.zeros((4,2), dtypes=np.float32)
dstQuad = np.array([[0,0], [width-1, 0], [width-1, height-1], [0, height-1]], dtype=np.float32)

def onMouse(event, x, y, flags, param):
    global cnt
    
    if event == cv2.EVENT_LBUTTONDOWN: 
        if cnt < 4:
            srcQuad[cnt] = np.array([x, y], dtype=np.float32)
            cv2.circle(param[0], (x, y), 5,(255,0,0), 2)
            cv2.imshow("src", param[0])
            cnt += 1
        if cnt == 4:
            M = cv2.getPerspectiveTransform(srcQuad, dstQuad)
            dst = cv2.warpPerspective(param[0], M, (width, height))   
            cv2.imshow('dst', dst)
            
src = cv2.imread("./data/card.bmp")
cv2.imshow("src", src)
cv2.setMouseCallback('src', onMouse, [src])    
cv2.waitKey()
cv2.destroyAllWindows()

좋은 웹페이지 즐겨찾기