본문 바로가기
프로그램/SKT FLY AI

SKT FLY AI : 26일차 - OpenCV

by hsloth 2023. 7. 31.

오늘부터는 OpenCV를 배우는 날이다!

  • 05.event_trackbar.py

import numpy as np
import cv2

def onChange(value): # 트랙바 콜백 함수
global image, title # 전역 변수 참조

add_value = value - int(image[0][0])  # 트랙바 값과 영솽 화소값 처분
print("추가 화소값", add_value)
image = image + add_value  # 행렬과 스칼라 덧셈 수행
cv2.imshow(title, image)

image = np.zeros((300, 500), np.uint8) # 영상 생성

title = "Trackbar Event"
cv2.imshow(title, image)

cv2.createTrackbar("Brightness", title, image[0][0], 255, onChange) # 트랙바 콜백 함수 등록
cv2.waitKey(0)
cv2.destroyAllWindows() # 모든 윈도우 제거ㄴ


- 06.event_mouse_trackbar.py

```python

import numpy as np
import cv2


def onChange(value):  # 트랙바 콜백 함수
    global image, title  # 전역 변수 참조

    add_value = value - int(image[0][0])  # 트랙바 값과 영솽 화소값 처분
    print("추가 화소값", add_value)
    image = image + add_value  # 행렬과 스칼라 덧셈 수행
    cv2.imshow(title, image)


def onMouse(event, x, y, flags, param):  # 마우스 콜백 함수
    global image, bar_name

    if event == cv2.EVENT_RBUTTONDOWN:  # 마우스 우클릭
        if image[0][0] < 246:
            image = image + 10
            cv2.setTrackbarPos(bar_name, title, image[0][0])  # 트랙바 위치 변경
            cv2.imshow(title, image)

    elif event == cv2.EVENT_LBUTTONDOWN:
        if image[0][0] >= 10:
            image = image - 10
            cv2.setTrackbarPos(bar_name, title, image[0][0])
            cv2.imshow(title, image)


image = np.zeros((300, 500), np.uint8)
title = "Trackbar * Mouse Event"
bar_name = "Brightness"
cv2.imshow(title, image)

cv2.createTrackbar(bar_name, title, image[0][0], 255, onChange)  # 트랙바 콜백 함수
cv2.setMouseCallback(title, onMouse)  # 마우스 콜백 함수 등록
cv2.waitKey(0)  # 키 입력 대기
cv2.destroyAllWindows()

  • 07.draw_line_rect.py

import numpy as np
import cv2

blue, green, red = (255, 0, 0), (0, 255, 0), (0, 0, 255)  # 색상 선언
image = np.zeros((400, 600, 3), np.uint8)  # 3채널 컬러 영상 생성
image[:] = (255, 255, 255)

pt1, pt2 = (50, 50), (250, 150)  # 좌표 선언 - 정수형 묶음
pt3, pt4 = (400, 150), (500, 50)
roi = (50, 200, 200, 100)  # 사각형 영역 - 4원소 묶음

# 직선 그리기
cv2.line(image, pt1, pt2, red)
cv2.line(image, pt3, pt4, green, 3, cv2.LINE_AA)

# 사각형 그리기
cv2.rectangle(image, pt1, pt2, blue, 3, cv2.LINE_4)
cv2.rectangle(image, roi, red, 3, cv2.LINE_8)
cv2.rectangle(image, (400, 200, 100, 100), green, cv2.FILLED)

cv2.imshow("Line & Rectangle", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 09.draw_circle.py

import numpy as np
import cv2


orange, blue, cyan = (0, 165, 255), (255, 0, 0), (255, 255, 0)
white, black = (255, 255, 255), (0, 0, 0)
image = np.full((300, 500, 3), white, np.uint8)  # 컬러 영상 생성 및 초기화

center = (image.shape[1] // 2, image.shape[0] // 2)  # 영상 중심 좌표 - 역순 구성
pt1, pt2 = (300, 50), (100, 220)
shade = (pt2[0] + 2, pt2[1] + 1)

cv2.circle(image, center, 100, blue)
cv2.circle(image, pt1, 50, orange, 2)
cv2.circle(image, pt2, 70, cyan, -1)

font = cv2.FONT_HERSHEY_COMPLEX

cv2.putText(image, "center_blue", center, font, 1.0, blue)
cv2.putText(image, "pt1_orange", pt1, font, 0.8, orange)
cv2.putText(image, "pt2_cyan", shade, font, 1.2, black, 2)
cv2.putText(image, "pt2_cyan", pt2, font, 1.2, cyan, 1)

cv2.imshow("Draw circles", image)
cv2.waitKey(0)
  • 10.draw_ellipse.py

import numpy as np
import cv2

orange, blue, white = (0, 165, 255), (255, 0, 0), (255, 255, 255)
image = np.full((300, 700, 3), white, np.uint8)

pt1, pt2 = (180, 150), (550, 150)
size = (120, 60)  # 타원 크기 - 반지름 값임

# 타원 가운데 점 그리기
cv2.circle(image, pt1, 1, 0, 2)
cv2.circle(image, pt2, 1, 0, 2)

# ellips(img, center, axes, angle, startAngle, endAngle, color[, thickness[, lineType[, shift]]]) -> img
# axes : 축의 절반 길이(중심에서 긴 거리, 짧은거리)
# angle : 타원의 기울기
# startAngle : 타원을 그리는 시작 각도
# endAnglel : 타원을 그리는 종료 각도
# thickness : 선 두께
cv2.ellipse(image, pt1, size, 0, 0, 360, blue, 1)
cv2.ellipse(image, pt2, size, 90, 0, 360, blue, 1)

# 호 그리자
cv2.ellipse(image, pt1, size, 0, 30, 270, orange, 4)
cv2.ellipse(image, pt2, size, 90, -45, 90, orange, 4)

cv2.imshow("문자열", image)
cv2.waitKey()
  • 실습
    # 마우스 왼쪽 버튼 두 번으로 사각형 그리기
    # 마우스 오른쪽 버튼 두 번으로 원 그리기 (센터, 반지름)
    

import numpy as np
import cv2
import math

left = []
right = []

def onMouse(event, x, y, flags, param): # 마우스 콜백 함수
global image, left, right

if event == cv2.EVENT_RBUTTONDOWN:  # 마우스 우클릭
    right.append((x, y))
    if len(right) == 2:
        second = right.pop()
        first = right.pop()
        r = int(
            math.sqrt((first[0] - second[0]) ** 2 + (first[1] - second[1]) ** 2)
        )
        print(r)
        cv2.circle(image, first, r, red, 3)
        cv2.imshow(title, image)

    print(right)

elif event == cv2.EVENT_LBUTTONDOWN:
    left.append((x, y))

    if len(left) == 2:
        second = left.pop()
        first = left.pop()
        cv2.rectangle(image, first, second, blue, 3, cv2.LINE_4)
        cv2.imshow(title, image)

BRG

blue, red = (255, 0, 0), (0, 0, 255)
image = np.full((300, 700, 3), (255, 255, 255), np.uint8)

title = "Draw Event"
cv2.imshow(title, image)
cv2.setMouseCallback(title, onMouse)
cv2.waitKey()


- 12.read_image1.py
```python

import cv2
from os import path
import os


def print_matInfo(name, image):
    if image.dtype == "uint8":
        mat_type = "CV_8U"
    elif image.dtype == "int8":
        mat_type = "CV_8S"
    elif image.dtype == "uint16":
        mat_type = "CV16U"
    elif image.dtype == "int16":
        mat_type = "CV_16S"
    elif image.dtype == "float32":
        mat_type = "CV_32F"
    elif image.dtype == "float64":
        mat_type = "CV_64F"
    nchannel = 3 if image.ndim == 3 else 1

    ## depth, channel 출력
    print(
        "%12s: dept(%s), channels(%s) -> mat_type(%sC%d)"
        % (name, image.dtype, nchannel, mat_type, nchannel)
    )


print(path.join(os.getcwd(), "./images/read_gray.jpg"))

title1, title2 = "gray2gray", "gray2color"
gray2gray = cv2.imread(
    path.join(os.getcwd(), "./images/read_gray.jpg"), cv2.IMREAD_GRAYSCALE
)
gray2color = cv2.imread(
    path.join(os.getcwd(), "./images/read_gray.jpg"), cv2.IMREAD_COLOR
)

print(gray2gray)

# 예외처리 - 영상파일 읽기 여부 조사
if gray2gray is None or gray2color is None:
    raise Exception("영상파일 읽기 에러")

print("행렬 좌표 (100, 100) 화소값")
print("%s %s" % (title1, gray2gray[100, 100]))  # 행렬 내 한 화소값 표시
print("%s %s\n" % (title2, gray2color[100, 100]))

print_matInfo(title1, gray2gray)  # 행렬 정보 출력 함수 호출
print_matInfo(title2, gray2color)

cv2.imshow(title1, gray2gray)
cv2.imshow(title2, gray2color)
cv2.waitKey(0)
    1. write_image1.py

import cv2

image = cv2.imread("images/read_color.jpg", cv2.IMREAD_COLOR)
if image is None:
    raise Exception("영상파일 읽기 에러")

params_jpg = (cv2.IMWRITE_JPEG_QUALITY, 10)  # JPEG 화질 설정
params_png = [cv2.IMWRITE_PNG_COMPRESSION, 9]  # PNG 압축 레벨 설정

# 행렬을 영상파일로 저장
cv2.imwrite("images/write_test1.jpg", image)  # 디폴트는 95
cv2.imwrite("images/write_test2.jpg", image, params_jpg)  # 지정한 화질로 저장
cv2.imwrite("images/write_test3.png", image, params_png)
cv2.imwrite("images/write_test4.bmp", image)  # BMP 파일로 저장
print("저장 완료")
  • 16.write_image2.py
import numpy as np
import cv2

image8 = cv2.imread("images/read_color.jpg", cv2.IMREAD_COLOR)
if image8 is None:
    raise Exception("영상 파일 읽기 에러")


# 형변환 및 화소 스케일 조정
image16 = np.uint16(image8 * (65535 / 255))  # 8비트를 16비트로
image32 = np.float32(image8 * (1 / 255))  # 8비트를 32비트 float로 바꾸는 것 (0~1)

# 화소값 확인 - 관심 영역((10, 10) 위치에서 2행, 3열) 출력
print("image8 행렬의 일부\n %s\n" % image8[10:12, 10:13])
print("image16 행렬의 일부\n %s\n" % image16[10:12, 10:13])
print("image32 행렬의 일부\n %s\n" % image32[10:12, 10:13])

cv2.imwrite("images/write_test16.tif", image16)  # 16비트 행렬 저장
cv2.imwrite("images/write_test_32.tif", image32)  # 32비트 행렬 저장

cv2.imshow("image16", image16)  # 영상 표시
cv2.imshow("image32", (image32 * 255).astype("uint8"))
cv2.waitKey(0)

  • 17.read_pccamera.py

import cv2


def put_string(frame, text, pt, value, color=(120, 200, 90)):  # 문자열 출력 함수
    text += str(value)
    shade = (pt[0] + 2, pt[1] + 2)
    font = cv2.FONT_HERSHEY_SIMPLEX
    cv2.putText(frame, text, shade, font, 0.7, (0, 0, 0), 2)  # 그림자 효과
    cv2.putText(frame, text, pt, font, 0.7, color, 2)  # 글자 적기


capture = cv2.VideoCapture(0)
if capture.isOpened() == False:
    raise Exception("카메라 연결 안됨")

# 카메라 속성 획득 및 출력
print("너비 %d" % capture.get(cv2.CAP_PROP_FRAME_WIDTH))
print("너비 %d" % capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
print("너비 %d" % capture.get(cv2.CAP_PROP_EXPOSURE))
print("너비 %d" % capture.get(cv2.CAP_PROP_BRIGHTNESS))

while True:
    ret, frame = capture.read()  # 카메라 영상 받기
    if not ret:
        break
    if cv2.waitKey(30) >= 0:
        break  # 종료 조건 - 스페이스바 키

    exposure = capture.get(cv2.CAP_PROP_EXPOSURE)  # 노출 속성 획득
    put_string(frame, "EXPOS: ", (10, 40), exposure)
    title = "View Frame from Camera"
    cv2.imshow(title, frame)

capture.release()
  • practice02.py

import cv2

capture = cv2.VideoCapture(0) # 0번 카메라 연결

if capture.isOpened() == False:
raise Exception("카메라 연결 안됨")

fps = 30 # 초당 프레임 수

delay = round(1000 / fps) # 프레임 간 지연 시간

size = (640, 480) # 동영상 파일 해상도

fourcc = cv2.VideoWriter_fourcc(*"DIVX") # 압축 코덱 설정

while True: # 무한 반복
ret, frame = capture.read() # 카메라 영상 받기

if not ret:
    break

x, y, w, h = (200, 100, 100, 200)

cv2.rectangle(frame, (x, y, w, h), (0, 0, 255), 3)

blue, green, red = cv2.split(frame)

tmp = green[y : y + h, x : x + w]

cv2.add(tmp, 50, tmp)

frame = cv2.merge([blue, green, red])

if cv2.waitKey(delay) >= 0:
    break

cv2.imshow("ex16", frame)  # 윈도우에 영상 띄우기

capture.release()


- assignment01.py
```python

import cv2
import numpy as np
from matplotlib import pyplot as plt

# 각 데이터의 위치: 25x2 크기에 각각 0~100
trainData = np.random.randint(0, 100, (25, 2)).astype(np.float32)

# 각 데이터는 0 or 1
response = np.random.randint(0, 2, (25, 1)).astype(np.float32)

# 값이 0인 데이터를 각각 화면 (x, y) 위치에 빨간색으로 칠합니다.
red = trainData[response.ravel() == 0]
plt.scatter(red[:, 0], red[:, 1], 80, "r", "^")

# 값이 1인 데이터를 각각 화면 (x, y) 위치에 파란색으로 칠합니다.
blue = trainData[response.ravel() == 1]
plt.scatter(blue[:, 0], blue[:, 1], 80, "b", "s")

# (0 ~ 100, 0 ~ 100) 위치의 데이터를 하나 생성해 칠합니다.
newcomer = np.random.randint(0, 100, (1, 2)).astype(np.float32)
plt.scatter(newcomer[:, 0], newcomer[:, 1], 80, "g", "o")

# knn = cv2.ml.KNearest_create()
# knn.train(trainData, cv2.ml.ROW_SAMPLE, response)
# ret, results, neighbours, dist = knn.findNearest(newcomer, 3)


# 가까운 3개를 찾고, 거리를 고려하여 자신을 정합니다.
# print("result : ", results)
# print("neighbours : ", neighbours)
# print("distance : ", dist)
# plt.show()


def euclidean_dist(pt1, pt2):
    return np.sqrt(np.sum((pt1 - pt2) ** 2))


def knn__train_prectice(train_data, label, new_point, k):
    predictions = []
    for one_point in new_point:
        distances = []
        for train_point in train_data:
            distance = euclidean_dist(one_point, train_point)
            distances.append(distance)

        sorted_indices = np.argsort(distances)
        k_nearest_indices = sorted_indices[:k]
        k_nearest_response = label[k_nearest_indices]

        unique_classes, class_counts = np.unique(k_nearest_response, return_counts=True)
        predicted_class = unique_classes[np.argmax(class_counts)]
        predictions.append(predicted_class)

    return np.array(predictions)