728x90
opencv를 이용한 컴퓨터 비전
- computer vision Top project 2024기준
- Football player dete
- fish detection in sea
- vehicle detection tracking and countin
- personal protective equipment detection and monitoring
- virtual gym using pose estimation
디지털 영상 처리 분류
- 화소 점 처리 (point processing)
- 화소 점의 원래 값이나 화소 점의 위치를 기반으로 화소 값 변경
- 영역 처리 (area processing)
- 화소의 원래 값과 이웃하는 화소의 값을 기반으로 화소값 변경
- 기하학 처리 (geometric processing)
- 화소들의 위치나 배열을 변화시킴
- 프레임 처리 (frame processing)
- 두 개 이상의 서로 다른 디지털 영상들이 연산 등의 조합을 통해서 새로운 화소값 생성
디지털 영상 : 표본화 양자화
표본화에 따른 영상차이
양자화에 따른 영상 차이
표본화 + 양자화
영상 신호의 디지털화 과정
디지털 영상의 표현 방법
색공간 모델
RGB 색상 예제
산술 연산을 이용한 물체 인식
Grayscale stretching
Histogram
- 이미지에서 주어진 값의 픽셀 수를 나타내는 간단한 데이터
- ex) 8비트 그레이 스케일 이미지
영상과 히스토그램 분포
RGB 히스토그램
히스토그램 수정
• 히스토그램을 기반으로 이미지 대비 및 밝기 개선 히스토그램 모양과 범위에 초점을 맞춥니다
fields
Scaling
opencv를 이용한 영상 정규화 실습
영상읽기
# !pip install opencv-python !pip install matplot |
# pip install opencv-python import cv2 import numpy as np import sys import matplotlib.pyplot as plt from pathlib import Path print(cv2.__version__) |
4.11.0
# cv2.imread(filename. flags = None) -> retval # flags: # cv2.IMREAD_COLOR: BGR color로 읽기 # cv2.IMREAD_GRAYSCALE: 그레이 color로 읽기 # cv2.IMREAD_UNCHANGED: 파일 속성대로 읽기 # cv2.IMREAD_REDUCED_GRAYSCALE_2 # cv2.IMREAD_REDUCED_COLOR_2 # retval: numpy.ndarray로 반환 |
folder = "fig" |
img = cv2.imread(Path(folder, "dog.bmp"), cv2.IMREAD_COLOR) # img = cv2.imread(Path(folder, "mri_brain.jpeg"), cv2.IMREAD_GRAYSCALE) if img is None: print("Image read failed") sys.exit() print(type(img)) # class numpyㅁ print(img.shape) # bgr (rgb x) print(img.dtype) # # cv2_imshow(img) cv2.imshow("dog", img) cv2.waitKey(0) # ms cv2.destroyAllWindows() |
Image read failed
새창띄우기 : cv2.namedWindow()
# cv2.namedWindow(winname, flags = None) -> None # winname: 창 이름 # flags: # cv2.WINDOW_NORMAL: 영상크기를 창 크기에 맞게 지정 # cv2.WINDOW_AUTOSIZE: 창크기를 영상 크기에 맞게 변경 # cv2.imwrite(filename, mat) -> None # filename: 저장할 이름 # mat: numpy.ndarray (default = uint8) # uint16, int32의 경우 255로 나누어서 출력 # float32, float64의 경우 0 ~ 1로 만든 후 행렬값에 255를 곱해서 출력 |
## cv2.namedWindow() img = cv2.imread(Path(folder, "dog.bmp"), cv2.IMREAD_COLOR) print("width = {}, height = {}".format( img.shape[1], img.shape[0])) # img_resize = cv2.resize(img, (img.shape[1]//2, img.shape[0]//2)) if img is None: print("Image read failed") sys.exit() ## cv2.WINDOW_AUTOSIZE: 창의 크기를 영상에 맞춤 cv2.namedWindow("Dog", cv2.WINDOW_AUTOSIZE) # cv2.namedWindow("Dog", cv2.WINDOW_NORMAL) cv2.imshow("Dog", img) # cv2.imshow("Dog_resize", img_resize) cv2.waitKey(0) cv2.destroyAllWindows() # mac os # cv2.waitKey(1) |
width = 640, height = 480
키보드 입력대기
# waitKey([, delay]) -> retval # delay: Delay in milliseconds. 0 is the special value that means "forever" # cv2.waitKey() -> ASCII code # retval |
img = cv2.imread(Path(folder, "dog.bmp"), cv2.IMREAD_COLOR) if img is None: print("Image read failed") sys.exit() cv2.namedWindow("dog", cv2.WINDOW_NORMAL) cv2.imshow("dog", img) while True: if cv2.waitKey() == ord("q"): break # cv2.waitKey() cv2.destroyAllWindows() |
matplotlib
import matplotlib.pyplot as plt img = cv2.imread(Path(folder, "dog.bmp"), cv2.IMREAD_COLOR) # BGR imgrgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) #RGB imggray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # GRAY if img is None: print("Image read failed") sys.exit() # plt.imshow(imgrgb) # plt.axis("off") # plt.show() plt.figure(figsize=(10,3)) plt.subplot(131), plt.imshow(img), plt.axis("off") plt.subplot(132), plt.imshow(imgrgb), plt.axis("off") plt.subplot(133), plt.imshow(imggray, cmap = "gray"), plt.axis("off") plt.show() # fig, axs = plt.subplots(1, 3, figsize = (10, 4)) # axs[0].imshow(img) # axs[0].set_title("BGR") # axs[0].axis('off') # plt.show() |
온라인 영상 읽기
from urllib import request url = "https://image.artbox.co.kr/upload/C00001/goods/800_800/179/241101006087179.jpg?s=/goods/org/179/241101006087179.jpg" # url = "https://i.ytimg.com/vi/VCUT4Hqy5lA/maxresdefault.jpg" source = request.urlopen(url).read() # bytes print(type(source)) print(source) # bytearray(source) |
image = np.array(bytearray(source), dtype = np.uint8) print("image shape = ", image.shape) # (101968,) image = cv2.imdecode(image, cv2.IMREAD_COLOR) cv2.imwrite("Charistmas.png", image) # cv2.namedWindow("img", cv2.WINDOW_NORMAL) cv2.imshow("img", image) cv2.waitKey() cv2.destroyAllWindows() |
image shape = (161202,)
디렉토리 내 영상읽기
import os img_list = os.listdir(Path(folder, "images")) # print(img_list) img_files = [] # list for i in img_list: img_dir = Path(folder, "images", i) # python string img_files.append(img_dir) # print(img_files) cv2.namedWindow("folder images", cv2.WINDOW_NORMAL) cv2.setWindowProperty("folder images", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) idx = 0 while True: # for i in img_files: img = cv2.imread(img_files[idx], cv2.IMREAD_COLOR) cv2.imshow('folder images', img) if cv2.waitKey(3000) == 27: break idx += 1 if idx >= len(img_files): idx = 0 cv2.destroyAllWindows() |
영상의 픽셀값 참조
img = cv2.imread(Path(folder, "dog.bmp"), cv2.IMREAD_COLOR) if img is None: print("image read failed") sys.exit() print("img width = {}, height = {}".format( img.shape[1], img.shape[0])) ## 영상 픽셀값 x = 320; y = 240 print("x = {}, y = {} 의 픽셀값".format(x, y)) print(img[240, 320]) # print(img[200:300, 250:400]) img[150:250, 250:500] = (125, 44, 66) cv2.namedWindow("image", cv2.WINDOW_AUTOSIZE) cv2.imshow("image", img) while True: if cv2.waitKey() == 27: break cv2.destroyAllWindows() |
img width = 640, height = 480
x = 320, y = 240 의 픽셀값
[ 0 14 40]
Canvas
# img1 = np.random.randint(0, 255, (200, 200), np.uint8) # int32 img2 = np.ones((1200, 800, 3), dtype = np.uint8)*255 # img3 = np.zeros((200, 200), np.uint8) + 255 # img4 = np.full((200, 200, 3), (255, 0, 255), np.uint8) # cv2.imshow("rand int", img1) cv2.imshow("rand ones", img2) # cv2.imshow("rand zeros", img3) # cv2.imshow("rand full", img4) cv2.waitKey() cv2.destroyAllWindows() |
영상 복사 (memory copy)
img = cv2.imread(Path(folder, "rose.jpg"), cv2.IMREAD_COLOR) if img is None: print("image read failed") sys.exit() # img2 = img # deep copy img2 = img.copy() img2[100:150, 200:300] = (255, 0, 0) cv2.namedWindow("rose", cv2.WINDOW_AUTOSIZE) cv2.imshow("rose", img) cv2.imshow("rose copy", img2) while True: if cv2.waitKey() == ord("q"): break cv2.destroyAllWindows() |
영상합성
# 마스크 영상을 이용한 영상 합성 # cv2.copyTo(src, mask, dst = None) -> dst # src: copy 하고자 하는 원본 영상 # mask: mask 영상 # dst: copy 후에 결과 영상 |
## 부분영상: 영상 합성에 유리 img = cv2.imread(Path(folder, "dog.bmp"), cv2.IMREAD_COLOR) if img is None: print("image read failed") sys.exit() dog_eye = img[150:250, 250:500] # circle(img, center, radius, color[, thickness[, lineType[, shift]]]) -> img cv2.circle(dog_eye, (50, 50), 30, (0, 0, 255), 5) print(dog_eye.shape) cv2.namedWindow("dog", cv2.WINDOW_NORMAL) cv2.imshow("dog", img) cv2.imshow("dog eye", dog_eye) while True: if cv2.waitKey() == 27: break cv2.destroyAllWindows() |
(100, 250, 3)
## copyTo(): 영상합성 # src = cv2.imread("./fig/airplane.bmp", cv2.IMREAD_COLOR) # mask = cv2.imread("./fig/mask_plane.bmp", cv2.IMREAD_GRAYSCALE) # dst = cv2.imread("./fig/field.bmp", cv2.IMREAD_COLOR) # src = cv2.imread(Path(folder, "airplane.bmp"), cv2.IMREAD_COLOR) mask = cv2.imread(Path(folder, "mask_plane.bmp"), cv2.IMREAD_GRAYSCALE) dst = cv2.imread(Path(folder, "field.bmp"), cv2.IMREAD_COLOR) # print(dst.shape) if src is None or mask is None or dst is None: print("Images read failed") sys.exit() ## numpy class # dst[mask > 0] = src[mask > 0] cv2.copyTo(src, mask, dst) cv2.imshow("src", src) cv2.imshow("mask",mask) cv2.imshow("dst",dst) cv2.waitKey() cv2.destroyAllWindows() |
(400, 600, 3)
## 알파채널 영상 일기 # src = cv2.imread('fig/sunglass.png', cv2.IMREAD_UNCHANGED) src = cv2.imread(Path(folder, "sunglass.png"), cv2.IMREAD_UNCHANGED) if src is None or src is None: print('Image read failed!') sys.exit() mask = src[:,:, -1] # mask는 알파 채널로 만든 마스크 영상 glass = src[:,:, 0:3] # glass는 b, g, r 3채널로 구성된 컬러 영상 #cv2.imshow('raw', raw) cv2.imshow('src', src) cv2.imshow('glass', glass) cv2.imshow('mask', mask) cv2.waitKey() cv2.destroyAllWindows() |
Draw lines
# cv2.line(img, pt1, pt2, color, thickness = None, lineType = None, shift = None) -> img # flags # img:그림을 그릴 영상 # pt1, pt2: 직선의 시작점, 끝점 # color: 직선의 칼라 (B,G,R)의 튜플 # thinkness: 선두께, 기본은= 1 # lineType: cv2.LINE_4, cv2.LINE_8, cv2.LINE_AA # cv2.rectangle(img, pt1, pt2, color, thickness = None, lineType = None) -> img # pt1 :좌측 상단, pt2: 우측하단 # cv2.rectangle(img, rect, color, thickness = None, lineType = None) -> img # rect: 사각형의 위치 정보 (x, y, w, h) # cv2.circle(img, center, radius, color, thickness = None, lineType = None) -> img # center: 원의 중심좌표 (x, y) # radius : 원의 반지름 # cv2.ellips(img, center, axes, angle, startAngle, endAngle, color[, thickness[, lineType[, shift]]]) -> img # center: 원의 중심좌표 (x, y) # axis: 축의 반지름(x, y) # angle: 타원의 기울기 (예, 10, 오른쪽으로 10도 기울어짐) # startAngle: 타원을 그리는 시작 각도 (3시 방향이 0도) # endAngle: 타원을 그리는 종료 각도 # cv2.polylines(img, pts, isClosed, color, thickness = None, lineType = None) -> img # center: 다각형 점들의 array # isClosed : True for 폐곡선 |
## 그리기 img = np.ones((600, 1200, 3), np.uint8)*255 cv2.line(img, (100, 50), (300 ,50), (0, 0, 255), 10, cv2.LINE_AA) cv2.line(img, (300 ,50), (200, 300), (0, 0, 255), 20, cv2.LINE_AA) cv2.arrowedLine(img, (400, 50), (400, 300), (255, 0, 0), 10, cv2.LINE_AA) # cv2.rectangle(img, (200, 400), (400, 500), (0, 0, 255), 5, cv2.LINE_AA) cv2.rectangle(img, (200, 400, 200, 100), (0, 0, 255), 5, cv2.LINE_AA) cv2.circle(img, (700, 300), 100, (255, 0, 255), -1) cv2.ellipse(img, (500, 100), (100, 50), 10, 0, 360, (255, 0, 0), 2) pts = np.array([[250, 200], [300, 200], [350, 300], [250, 300]]) cv2.polylines(img, [pts], True, (255, 0, 255), 2, cv2.LINE_AA) text = "OpenCV version=4.9" cv2.putText(img, text, (700, 100), cv2.FONT_ITALIC, 1, (0, 0, 255), 2, cv2.LINE_AA) cv2.imshow("img", img) cv2.waitKey(0) cv2.destroyAllWindows() |
화소점 처리
# add(src1, src2[, dst[, mask[, dtype]]]) -> dst # src1: 첫번째 입력영상 # src2: 두번째 입력영상 # dst: 덧셈 연산의 결과 # mask: 마스크 영상 # dtype: 출력영상의 타입 (예, cv2.CV_8U, cv2.CV_32F) ## add, subract, addweighted, absdiff, multiply, divivde |
# src = cv2.imread("./fig/lenna.png", cv2.IMREAD_COLOR) src = cv2.imread(Path(folder, "lenna.png"), cv2.IMREAD_COLOR) if src is None: print("image read failed") sys.exit() dst1 = cv2.add(src, 100) # 클리핑 #dst1 = np.clip(src + 100., 0, 255).astype(np.uint8) dst2 = cv2.add(src, (0, 0, 250, 0)) # 클리핑 cv2.imshow("src", src) cv2.imshow("dst1", dst1) cv2.imshow("dst2", dst2) cv2.waitKey() cv2.destroyAllWindows() |
## 사칙연산 src1 = cv2.imread(Path(folder, "lenna.png"), cv2.IMREAD_GRAYSCALE) src2 = np.zeros((220, 220), np.uint8) cv2.circle(src2, (110, 110), 80, 200, -1) cv2.circle(src2, (110, 110), 40, 50, -1) if src is None: print("image read failed") sys.exit() # cv2.divide, cv2.multiply() dst1 = cv2.add(src1, src2) dst2 = cv2.subtract(src1, src2) dst3 = cv2.addWeighted(src1, 0.8, src2, 0.2, 0.0) dst4 = cv2.absdiff(src1, src2) dst5 = cv2.divide(src1, 2) dst6 = cv2.multiply(src1, 2) cv2.imshow("src1", src1) cv2.imshow("src2", src2) cv2.imshow("add", dst1) cv2.imshow("subtract", dst2) cv2.imshow("addWeighted", dst3) cv2.imshow("absdiff", dst4) cv2.imshow("divide", dst5) cv2.imshow("multiply", dst6) cv2.waitKey() cv2.destroyAllWindows() |
# src = cv2.imread("./fig/rose.jpg", cv2.IMREAD_COLOR) src = cv2.imread(Path(folder, "rose.jpg"), cv2.IMREAD_COLOR) background = np.ones_like(src)*255 weight = np.arange(0, 1, 0.01) # print(weight) for i in weight: dst = cv2.addWeighted(src, i, background, 1-i, 0.0) cv2.imshow('dst', dst) if cv2.waitKey(100) == 27: break cv2.destroyAllWindows() |
영상 히스토 그램
# cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]]) -> hist # images: 입력영상 리스트(리스트로 입력) # channels: 채널리스트, 3 채널의 경우 [0,1,2] # mask: 마스크 영상입력, 영상전체는 None으로 지정 # histSize: 히스터그램 빈의 크기 # range: 히스토그램의 최솟값과 최댓값 # hist: 계산된 히스토그램, numpy.ndarray 타입 # accumulate: 기존의 히스토그램을 누적할경우 True |
src = cv2.imread(Path(folder, "lenna.png"), cv2.IMREAD_COLOR) if src is None: print("Image read failed") sys.exit() # 채널별 히스토그램 hist_b = cv2.calcHist([src], [0], None, [256], [0, 256]) hist_g = cv2.calcHist([src], [1], None, [256], [0, 255]) hist_r = cv2.calcHist([src], [2], None, [256], [0, 255]) plt.bar(np.arange(len(hist_b)), hist_b[:,0], color = "b", alpha = 0.5) # blue channel plt.bar(np.arange(len(hist_g)), hist_g[:,0], color = "g", alpha = 0.5) # green channel plt.bar(np.arange(len(hist_r)), hist_r[:,0], color = "r", alpha = 0.5) # red channel plt.show() cv2.imshow("lenna", src) cv2.waitKey(0) cv2.destroyAllWindows() |
히스토그램 정규화
# cv2.normalize(src, dst=None, alpha=None, beta=None, norm_type=None, dtype=None, mask=None) -> dst # src: 입력영상 # dst: 결과영상 # alpha: 정규화 최소값 (예, 0) # beta: 정규화 최댓값 (예, 155) # norm_type: cv2.NORM_MINMAX # dtype = -1, src와 같은 type |
# src = cv2.imread('fig/puppy_shrink.png') src = cv2.imread(Path(folder, "puppy_shrink.png")) # src = cv2.imread('fig/autumn.jpg', cv2.IMREAD_REDUCED_COLOR_8) # src = cv2.imread('fig/manjang.jpg') if src is None: print('Image load failed!') sys.exit() # minMaxLoc(src[, mask]) -> minVal, maxVal, minLoc, maxLoc # smin, smax, _, _ = cv2.minMaxLoc(src) dst_norm = cv2.normalize(src, None, 0, 255, cv2.NORM_MINMAX, -1) # dst = np.clip(255*(src-smin)/(smax-smin) + 0, 0, 255).astype(np.uint8) cv2.imshow('src', src) cv2.imshow('dst_norm', dst_norm) cv2.waitKey() cv2.destroyAllWindows() |
728x90
'AI 개론' 카테고리의 다른 글
AI 개론 _ OpenCV를 이용한 컴퓨터 비전3 + OpenCV를 이용한 객체 검출, 동영상 처리 실습 (0) | 2025.04.09 |
---|---|
AI 개론 _ OpenCV를 이용한 컴퓨터 비전2 + OpenCV를 이용한 기하학적 변환 실습 (0) | 2025.04.09 |