컴퓨터 비전

4-(2). OpenCV

인공지능파이썬 2025. 3. 5. 15:06

길어서 두번째 부분 예제 시작하겠습니다.

 

3. 영상의 이진화
* 이진화(Binary Thresholding) 는 영상을 흑백(0 또는 255)으로 변환하여 특정 임계값(threshold) 이상인 픽셀을 흰색(255)으로, 이하인 픽셀을 검은색(0)으로 변환하는 과정입니다. 
* 이는 객체 검출, OCR(광학 문자 인식), 엣지 검출 등의 전처리 과정에서 중요한 역할을 합니다. 
* OpenCV에서는 cv2.threshold() 함수를 사용하여 고정 임계값 이진화, 적응형 이진화, Otsu의 이진화 등을 적용할 수 있습니다. 
* 특히, cv2.THRESH_BINARY는 기본적인 이진화 방법이며, cv2.ADAPTIVE_THRESH_GAUSSIAN_C는 조명이 균일하지 않은 경우에도 효과적으로 이진화를 수행할 수 있습니다.

3-1. 오츠 이진화
* 오츠 이진화(Otsu's Binarization) 는 OpenCV에서 제공하는 자동 임계값 결정 기법으로, 영상의 히스토그램을 분석하여 객체와 배경을 가장 잘 구분할 수 있는 최적의 임계값을 자동으로 찾는 방법입니다. 
* 이는 cv2.THRESH_OTSU 옵션을 사용하여 cv2.threshold() 함수에서 적용할 수 있으며, 특히 배경과 객체 간의 명암 대비가 뚜렷한 경우 효과적으로 동작합니다. 
* 오츠 이진화는 모든 픽셀 값의 분포를 기반으로 클래스 내 분산(intra-class variance)을 최소화하는 임계값을 자동으로 선택하여 수동으로 임계값을 설정하는 불편함을 줄여줍니다. 
* 일반적으로 cv2.THRESH_BINARY + cv2.THRESH_OTSU를 함께 사용하여 이진화를 수행하며, 그레이스케일 변환이 선행되어야 합니다.

3-2. 적응형 이진화
* 적응형 이진화(Adaptive Thresholding) 는 OpenCV에서 제공하는 이진화 기법 중 하나로, 조명 변화가 심한 영상에서도 적절한 임계값을 적용하여 이진화를 수행하는 방법입니다. 
* 일반적인 cv2.threshold()는 하나의 고정된 임계값을 사용하지만, cv2.adaptiveThreshold()는 영상의 작은 영역마다 서로 다른 임계값을 계산하여 적용합니다. 
* 이를 통해 명암 차이가 고르지 않은 이미지에서도 효과적으로 객체와 배경을 분리할 수 있습니다. 
* OpenCV에서는 평균값을 이용하는 cv2.ADAPTIVE_THRESH_MEAN_C와 가우시안 가중치를 적용하는 cv2.ADAPTIVE_THRESH_GAUSSIAN_C 두 가지 방식을 제공하며, 블록 크기(blockSize)와 상수 값(C)을 조절하여 최적의 결과를 얻을 수 있습니다.


4. 영상의 변환
* 영상의 변환(Image Transformation) 이란 영상의 형태, 크기, 밝기, 색상 등을 변경하여 새로운 영상으로 변환하는 과정으로, 컴퓨터 비전에서 다양한 전처리 및 후처리에 활용됩니다. 
* OpenCV에서는 대표적으로 기하학적 변환(Geometric Transformation) 과 강도 변환(Intensity Transformation) 을 제공합니다. 
* 기하학적 변환에는 확대/축소(Scaling), 회전(Rotation), 이동(Translation), 투시 변환(Perspective Transform) 등이 있으며, cv2.warpAffine()과 cv2.getPerspectiveTransform()을 통해 수행할 수 있습니다. 
* 강도 변환은 픽셀 값의 변화를 조정하는 방법으로 명암 조절, 히스토그램 평활화, 이진화(Thresholding) 등이 있으며, cv2.equalizeHist(), cv2.threshold(), cv2.adaptiveThreshold() 등이 이에 해당합니다.

5. 영상의 필터링 연산
* 영상의 필터링 연산(Image Filtering Operation) 은 영상의 특성을 강조하거나 잡음을 제거하기 위해 커널(필터)을 활용하여 픽셀 값을 변환하는 과정입니다. 
* OpenCV에서는 필터링을 통해 노이즈 제거, 엣지 검출, 블러 효과, 샤프닝 등의 처리를 수행할 수 있습니다. 대표적인 필터링 기법으로는 평균 블러링(Averaging), 가우시안 블러링(Gaussian Blur), 미디언 블러링(Median Blur) 등이 있으며, cv2.blur(), cv2.GaussianBlur(), cv2.medianBlur() 함수를 통해 적용할 수 있습니다. 
* 또한, 고급 필터링 기법으로 소벨 필터(Sobel Filter), 라플라시안 필터(Laplacian Filter) 와 같은 엣지 검출 필터도 제공되며, cv2.Sobel() 및 cv2.Laplacian()을 사용하여 적용할 수 있습니다. 
* 필터링 연산은 영상 내 중요한 특징을 강조하거나 불필요한 정보를 제거하는 데 활용되며, 영상 분석 및 전처리에 필수적인 기법입니다.

 

https://pixabay.com/ko/videos/ 

동영상 2개를 다운받아 movie1.mp4, movie2.mp4로 저장하고 아래 예제를 실행합니다.

 

예시 1)

import cv2  
import sys 

# 동영상 파일 또는 웹캠에서 영상을 가져오기
cap = cv2.VideoCapture('./london.mp4')  # 'london.mp4'라는 동영상 파일을 불러옴

# 동영상을 정상적으로 불러왔는지 확인
if not cap.isOpened():  # 동영상을 불러올 수 없는 경우
    print('동영상을 불러올 수 없음')  # 오류 메시지 출력
    sys.exit()  # 프로그램 종료
print('동영상을 불러올 수 있음')  # 정상적으로 동영상이 열렸다면 출력

# 동영상의 기본 속성 출력
print('가로 사이즈: ', int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)))  # 동영상 프레임의 가로 크기 출력
print('세로 사이즈: ', int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))  # 동영상 프레임의 세로 크기 출력
print('프레임 수: ', int(cap.get(cv2.CAP_PROP_FRAME_COUNT)))  # 동영상의 총 프레임 수 출력
print('FPS: ', cap.get(cv2.CAP_PROP_FPS))  # 초당 프레임 수(FPS) 출력

# 동영상 프레임을 반복적으로 읽어와서 화면에 표시
while True:
    ret, frame = cap.read()  # 한 프레임 읽기
    if not ret:  # 프레임을 더 이상 읽을 수 없는 경우 (영상이 끝난 경우)
        break  # 반복문 종료

    cv2.imshow('frame', frame)  # 읽어온 프레임을 화면에 표시

    if cv2.waitKey(10) == 27:  # 키 입력을 기다림 (ESC(27) 키를 누르면 종료)
        break

cap.release()  # 메모리 해제

 

예시 2)

import cv2  
import sys 

# 웹캠을 열어서 비디오 캡처 객체 생성 (0은 기본 웹캠을 의미)
cap = cv2.VideoCapture(0)

# 카메라가 정상적으로 열렸는지 확인
if not cap.isOpened():  # 카메라를 열 수 없는 경우
    print('카메라를 열 수 없음')  # 오류 메시지 출력
    sys.exit()  # 프로그램 종료
    
print('카메라 연결 성공')  # 정상적으로 카메라가 연결되었음을 출력

# 카메라의 기본 속성 출력
print('가로 사이즈: ', int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)))  # 웹캠 프레임의 가로 크기 출력
print('세로 사이즈: ', int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))  # 웹캠 프레임의 세로 크기 출력
print('FPS: ', cap.get(cv2.CAP_PROP_FPS))  # 초당 프레임 수(FPS) 출력

# 카메라에서 영상을 지속적으로 받아와서 화면에 출력
while True:
    ret, frame = cap.read()  # 한 프레임 읽기
    if not ret:  # 프레임을 정상적으로 읽지 못한 경우
        break  # 반복문 종료

    cv2.imshow('frame', frame)  # 읽어온 프레임을 화면에 표시

    if cv2.waitKey(10) == 27:  # ESC(27) 키를 누르면 종료
        break

cap.release()  # 카메라 자원 해제

 

예시 3)

import cv2

# 두 개의 동영상 파일 불러오기
cap1 = cv2.VideoCapture('./london.mp4')  # 첫 번째 동영상
cap2 = cv2.VideoCapture('./forest.mp4')  # 두 번째 동영상

# 첫 번째 동영상의 프레임 너비와 높이 가져오기
w = int(cap1.get(cv2.CAP_PROP_FRAME_WIDTH))  # 가로 크기
h = int(cap1.get(cv2.CAP_PROP_FRAME_HEIGHT))  # 세로 크기

# 두 동영상의 총 프레임 수 가져오기
frame_cnt1 = int(cap1.get(cv2.CAP_PROP_FRAME_COUNT))  # 첫 번째 동영상의 프레임 개수
frame_cnt2 = int(cap2.get(cv2.CAP_PROP_FRAME_COUNT))  # 두 번째 동영상의 프레임 개수

# 두 동영상의 초당 프레임 수(FPS) 가져오기
fps1 = cap1.get(cv2.CAP_PROP_FPS)  # 첫 번째 동영상의 FPS
fps2 = cap2.get(cv2.CAP_PROP_FPS)  # 여기서 cap1이 아니라 cap2에서 FPS를 가져와야 함 (오타 수정 필요)

# 동영상 정보 출력
print(w, h)  # 동영상 해상도 출력 (예: 640 360)
print(frame_cnt1, frame_cnt2)  # 두 동영상의 총 프레임 수 출력 (예: 242 315)
print(fps1, fps2)  # 두 동영상의 FPS 출력 (예: 24.0 24.0)

# 비디오 코덱 설정 및 출력 파일 생성 (DIVX 코덱 사용)
fourcc = cv2.VideoWriter.fourcc(*'DIVX')
out = cv2.VideoWriter('mix.avi', fourcc, fps1, (w, h))  # 새로운 동영상 파일 생성

# 첫 번째 동영상을 프레임 단위로 읽어서 저장
for i in range(frame_cnt1):
    ret, frame = cap1.read()  # 프레임 한 장 읽기
    if not ret:  # 프레임을 읽을 수 없으면 중단
        break
    cv2.imshow('output', frame)  # 프레임을 화면에 표시
    out.write(frame)  # 프레임을 새 동영상 파일에 저장
    if cv2.waitKey(10) == 27:  # ESC(27) 키를 누르면 종료
        break

# 메모리 해제
cap1.release()
cap2.release()
out.release()

 

예제 4)

import cv2

# 웹캠 열기 (0: 기본 웹캠)
cap = cv2.VideoCapture(0)

# 웹캠의 해상도 및 FPS 값 가져오기
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))  # 가로 크기
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))  # 세로 크기
fps = cap.get(cv2.CAP_PROP_FPS)  # 초당 프레임 수

# 현재 웹캠 정보 출력
print(w, h)  # 해상도 출력
print(fps)  # FPS 출력

# 동영상 저장을 위한 설정
fourcc = cv2.VideoWriter.fourcc(*'DIVX')  # 코덱 설정 (DIVX)
out = cv2.VideoWriter('mix.avi', fourcc, fps, (w, h))  # 'mix.avi' 파일 생성

# 웹캠으로 영상 촬영 및 저장
while True:
    ret, frame = cap.read()  # 한 프레임 읽기
    if not ret:  # 프레임을 정상적으로 읽지 못한 경우 종료
        break
    cv2.imshow('frame', frame)  # 프레임을 화면에 표시
    out.write(frame)  # 프레임을 동영상 파일에 저장

    if cv2.waitKey(10) == 27:  # ESC(27) 키를 누르면 종료
        break

# 메모리 해제
cap.release()  
out.release()

 

 

예시 5)

import cv2
import matplotlib.pyplot as plt

# 그레이스케일 이미지 불러오기
img = cv2.imread('./images/apple.png', cv2.IMREAD_GRAYSCALE)

# 이미지가 정상적으로 로드되었는지 확인
if img is None:
    print("이미지를 불러올 수 없습니다.")
    exit()

# 히스토그램 계산(이미지의 픽셀 값 분포를 나타냄)
# calcHist(히스토그램을 계산할 이미지 목록, 그레이스케일 이미지의 채널, 마스크를 사용하지 않음, 
# 빈(bin)을 사용하여 0부터 255까지의 픽셀 값 분포를 계산, 0 ~ 255의 픽셀 값의 범위)
hist = cv2.calcHist([img], [0], None, [256], [0, 255])

# 임계값을 기준으로 이미지를 이진화
# threshold(이진화를 적용할 이미지, 임계값, 임계값을 넘는 픽셀에 부여할 최대값, 임계값 적용방식)
# THRESH_BINARY: 픽셀 값이 임계값보다 크면 최대값으로 설정, 작거나 같으면 0으로 설정
# a, dst1: a(임계값), dst1(이진화가 적용된 이미지)
a, dst1 = cv2.threshold(img, 100, 255, cv2.THRESH_BINARY)  # 임계값 100 적용
b, dst2 = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY)  # 임계값 150 적용

# 원본 이미지 및 이진화된 이미지 출력
cv2.imshow('Original Image', img)  # 원본 이미지
cv2.imshow('Thresholded Image (100)', dst1)  # 임계값 100 적용된 이미지
cv2.imshow('Thresholded Image (150)', dst2)  # 임계값 150 적용된 이미지

# 히스토그램 그래프 출력
plt.plot(hist)  # 히스토그램 그래프 그리기
plt.title('Grayscale Histogram')  # 그래프 제목
plt.xlabel('Pixel Value')  # X축 라벨 (픽셀 값)
plt.ylabel('Frequency')  # Y축 라벨 (픽셀 빈도수)
plt.show()  # 그래프 표시

cv2.waitKey()

--->

 

예시 6)

import cv2

# 그레이스케일 이미지 불러오기
img = cv2.imread('./images/apple.png', cv2.IMREAD_GRAYSCALE)

# 이미지가 정상적으로 불러와졌는지 확인
if img is None:
    print("이미지를 불러올 수 없습니다.")
    exit()

# Otsu의 이진화 적용 (자동 임계값 결정)
# cv2.threshold(입력 이미지, 초기 임계값(0), 최댓값(255), 이진화 방식)
# THRESH_OTSU: Otsu 알고리즘을 사용하여 최적의 임계값을 자동으로 결정
th, dst = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

# 결정된 임계값 출력
print('Otsu Threshold Value: ', th)  # Otsu 알고리즘이 결정한 임계값 출력 (예: 128.0)

# 원본 이미지 및 이진화된 이미지 출력
cv2.imshow('Original Image', img)  # 원본 이미지 표시
cv2.imshow('Otsu Thresholding', dst)  # Otsu 이진화 적용된 이미지 표시

cv2.waitKey()

--->

 

예시 7)

import cv2
import matplotlib.pyplot as plt 

# 그레이스케일 이미지 불러오기
img = cv2.imread('./images/apple.png', cv2.IMREAD_GRAYSCALE)

# 이미지가 정상적으로 불러와졌는지 확인
if img is None:
    print("이미지를 불러올 수 없습니다.")
    exit()

# Otsu의 이진화 적용 (자동 임계값 결정)
th, dst1 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
print('Otsu Threshold Value: ', th)  # otsu:  128.0

# 적응형 이진화 적용 (Adaptive Thresholding)
# cv2.adaptiveThreshold(입력 이미지, 최댓값, 적응형 방식, 임계 방식, 블록 크기, 상수)
# ADAPTIVE_THRESH_MEAN_C : 지정한 영역 내 픽셀들의 평균값을 임계값으로 사용
dst2 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, 5)

# ADAPTIVE_THRESH_GAUSSIAN_C : 가우시안 가중치를 적용한 평균값을 임계값으로 사용
dst3 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 9, 5)

# 이미지 및 이진화 결과를 딕셔너리에 저장
dic = {'Original Image': img, 
       'Otsu Thresholding': dst1, 
       'Adaptive Mean Thresholding': dst2, 
       'Adaptive Gaussian Thresholding': dst3}

# 결과 이미지 출력
plt.figure(figsize=(10, 10))  # 그래프 크기 설정
for i, (title, image) in enumerate(dic.items()):
    plt.subplot(2, 2, i + 1)  # 2x2 배열의 서브플롯 생성
    plt.title(title)  # 제목 설정
    plt.imshow(image, cmap='gray')  # 이미지를 흑백(Grayscale)으로 출력
    plt.axis('off')  # 축 제거

plt.show()  # 그래프 표시

--->

 

예시 8)

import cv2  # OpenCV 라이브러리 불러오기
import numpy as np  # Numpy 라이브러리 불러오기 (행렬 연산)

# 이미지 불러오기
img = cv2.imread('./images/dog.bmp')

# 이미지가 정상적으로 불러와졌는지 확인
if img is None:
    print("이미지를 불러올 수 없습니다.")
    exit()

# 이동 변환 행렬 (Affine Transformation)
# [[1, 0, 150], [0, 1, 100]] : x 방향으로 150, y 방향으로 100 이동
aff = np.array([[1, 0, 150], 
                [0, 1, 100]], dtype=np.float32)

# 이미지 이동 적용
# cv2.warpAffine(입력 이미지, 변환 행렬, 출력 이미지 크기)
dst = cv2.warpAffine(img, aff, (img.shape[1], img.shape[0]))

# 원본 및 이동된 이미지 출력
cv2.imshow('Original Image', img)
cv2.imshow('Translated Image', dst)

cv2.waitKey()

--->

 

 

예시 9)

import cv2 

# 이미지 불러오기
img = cv2.imread('./images/dog.bmp')

# 이미지가 정상적으로 불러와졌는지 확인
if img is None:
    print("이미지를 불러올 수 없습니다.")
    exit()

# INTER_NEAREST(보간법): 가장 가까운 이웃의 픽셀 값을 사용하여 리사이즈,계산이 빠르지만 계단현상이 발생할수 있음
dst1 = cv2.resize(img, (1280, 1024), interpolation=cv2.INTER_NEAREST)

# INTER_CUBIC : 주변 16개 픽셀 값을 이용하여 리사이즈, 상대적으로 부드럽고 자연스러운 결과를 얻을 수 있지만 계산량이 많음
dst2 = cv2.resize(img, (1280, 1024), interpolation=cv2.INTER_CUBIC)

# 원본 및 리사이즈된 이미지 출력 (일부 영역만 표시)
cv2.imshow('Original Image', img)  # 원본 이미지
cv2.imshow('Resized (INTER_NEAREST)', dst1[400:800, 200:600])  # INTER_NEAREST 방식 리사이즈 후 일부 영역 크롭
cv2.imshow('Resized (INTER_CUBIC)', dst2[400:800, 200:600])  # INTER_CUBIC 방식 리사이즈 후 일부 영역 크롭

cv2.waitKey()

--->

 

 

예시 10)

import cv2

# 이미지 불러오기
img = cv2.imread('./images/dog.bmp')

# 이미지가 정상적으로 불러와졌는지 확인
if img is None:
    print("이미지를 불러올 수 없습니다.")
    exit()

# 회전 중심 좌표 (이미지의 중심)
cp = (img.shape[1] / 2, img.shape[0] / 2)

# 회전 변환 행렬 생성 (cv2.getRotationMatrix2D)
# - 회전 중심(cp): 이미지의 중심
# - 회전 각도(30): 시계 반대 방향으로 30도 회전
# - 크기 조절 비율(0.7): 이미지 크기를 70%로 축소
rot = cv2.getRotationMatrix2D(cp, 30, 0.7)

# 이미지 회전 적용 (cv2.warpAffine)
# warpAffine(입력 이미지, 변환 행렬, 출력 이미지 크기)
dst = cv2.warpAffine(img, rot, (img.shape[1], img.shape[0]))

# 원본 및 회전된 이미지 출력
cv2.imshow('Original Image', img)
cv2.imshow('Rotated Image', dst)

cv2.waitKey()

--->

 

예시 11)

import cv2  
import numpy as np

# 이미지 불러오기
img = cv2.imread('./images/gram.jpg')

# 이미지가 정상적으로 불러와졌는지 확인
if img is None:
    print("이미지를 불러올 수 없습니다.")
    exit()

# 출력 이미지 크기 설정
w, h = 600, 400  # 변환 후 이미지의 너비(W)와 높이(H)

# 원본 이미지에서 투영 변환할 4개의 좌표 (시계 방향으로 선택)
# 예제에서 문서 코너를 기준으로 좌표 설정
srcQuad = np.array([[369, 172],  # 좌상단
                    [1228, 156],  # 우상단
                    [1424, 846],  # 우하단
                    [207, 801]], np.float32)  # 좌하단

# 변환 후의 좌표 (출력 이미지에서 사각형 형태로 정렬)
dstQuad = np.array([[0, 0],   # 좌상단
                    [w, 0],   # 우상단
                    [w, h],   # 우하단
                    [0, h]], np.float32)  # 좌하단

# 투시 변환 행렬 계산
pers = cv2.getPerspectiveTransform(srcQuad, dstQuad)

# 투시 변환 적용
dst = cv2.warpPerspective(img, pers, (w, h))

# 원본 및 변환된 이미지 출력
cv2.imshow('Original Image', img)  # 원본 이미지
cv2.imshow('Perspective Transformed Image', dst)  # 투시 변환된 이미지

cv2.waitKey()

--->

 

 

예시 12)

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

# 이미지 불러오기
img = cv2.imread('./images/dog.bmp')

# 이미지가 정상적으로 불러와졌는지 확인
if img is None:
    print("이미지를 불러올 수 없습니다.")
    exit()

# BGR -> RGB 변환 (Matplotlib에서 올바른 색상 표시를 위해)
dst1 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 평균 블러 적용 (커널 크기: 7x7)
dst2 = cv2.blur(img, (7, 7))

# 원본 및 블러링된 이미지 출력 (OpenCV 사용)
cv2.imshow('Original Image', img)
cv2.imshow('Blurred Image (7x7)', dst2)

# 다양한 커널 크기로 필터링 적용 (Matplotlib 사용)
plt.figure(figsize=(10, 5))
for i, k in enumerate([5, 7, 9]):  # 5x5, 7x7, 9x9 크기의 커널 적용
    kernel = np.ones((k, k), np.float32) / (k ** 2)  # 평균 필터 커널 생성
    filtering = cv2.filter2D(dst1, -1, kernel)  # 필터 적용
    plt.subplot(1, 3, i + 1)  # 1x3 배열로 그래프 표시
    plt.imshow(filtering)  # 필터링된 이미지 출력
    plt.title(f'Kernel size: {k}')  # 제목 설정
    plt.axis('off')  # 축 제거

plt.show()  # 그래프 표시
cv2.waitKey(0)  # 키 입력 대기

--->

 

 

예시 13)

import cv2  # OpenCV 라이브러리 불러오기

# 그레이스케일 이미지 불러오기
img = cv2.imread('./images/dog.bmp', cv2.IMREAD_GRAYSCALE)

# 이미지가 정상적으로 불러와졌는지 확인
if img is None:
    print("이미지를 불러올 수 없습니다.")
    exit()

# 가우시안 블러 적용 (GaussianBlur)
# GaussianBlur(입력 이미지, 커널 크기(0,0): 자동 설정, 표준 편차(1))
# 노이즈 제거에 효과적이며 엣지를 더 잘 보존
dst1 = cv2.GaussianBlur(img, (0, 0), 1)

# 평균 블러 적용 (Blur)
# blur(입력 이미지, 커널 크기(5,5)): 단순히 주변 픽셀 평균을 사용하여 블러 효과 적용
dst2 = cv2.blur(img, (5, 5))

# 원본 및 블러링된 이미지 출력
cv2.imshow('Original Image', img)  # 원본 이미지
cv2.imshow('Gaussian Blur (σ=1)', dst1)  # 가우시안 블러 적용된 이미지
cv2.imshow('Mean Blur (5x5)', dst2)  # 평균 블러 적용된 이미지

cv2.waitKey(0)  # 키 입력 대기

--->

 

 

예시 14)

import cv2

# 그레이스케일 이미지 불러오기
img = cv2.imread('./images/space.webp', cv2.IMREAD_GRAYSCALE)

# 이미지가 정상적으로 불러와졌는지 확인
if img is None:
    print("이미지를 불러올 수 없습니다.")
    exit()

# 미디언 블러 적용 (Median Blur)
# medianBlur(입력 이미지, 커널 크기)
# 커널 크기 3을 사용하여 노이즈 제거 (특히 Salt & Pepper 노이즈 제거에 효과적)
dst1 = cv2.medianBlur(img, 3)

# 가우시안 블러 적용 (Gaussian Blur)
# GaussianBlur(입력 이미지, 커널 크기(0,0): 자동 설정, 표준 편차(σ=2))
# 노이즈 제거 및 부드러운 블러 효과 적용
dst2 = cv2.GaussianBlur(img, (0, 0), 2)

# 원본 및 블러링된 이미지 출력
cv2.imshow('Original Image', img)  # 원본 이미지
cv2.imshow('Median Blur (3x3)', dst1)  # 미디언 블러 적용된 이미지
cv2.imshow('Gaussian Blur (σ=2)', dst2)  # 가우시안 블러 적용된 이미지

cv2.waitKey()  # 키 입력 대기

--->

 

예시 15)

import cv2 
import numpy as np  # Numpy 라이브러리 불러오기 (행렬 연산)

# 이미지 불러오기
img = cv2.imread('./images/dog.bmp')

# 이미지가 정상적으로 불러와졌는지 확인
if img is None:
    print("이미지를 불러올 수 없습니다.")
    exit()

# 이미지의 중간(중앙) 픽셀 값 계산 (Canny 엣지 검출을 위한 임계값 설정)
med_val = np.median(img)
print(f"Median Pixel Value: {med_val}")  # 예: 129.0

# Canny 엣지 검출을 위한 낮은 임계값과 높은 임계값 설정
lower = int(max(0, 0.7 * med_val))  # 0보다 작은 값 방지
print(f"Lower Threshold: {lower}")  # 예: 90

upper = int(min(255, 1.3 * med_val))  # 255보다 큰 값 방지
print(f"Upper Threshold: {upper}")  # 예: 167

# 가우시안 블러 적용 (노이즈 제거)
dst = cv2.GaussianBlur(img, (3, 3), 0)

# Canny 엣지 검출 적용
# Canny(입력 이미지, 낮은 임계값, 높은 임계값, Sobel 커널 크기)
# 낮은 임계값보다 작은 값은 무시하고, 높은 임계값보다 큰 값만 엣지로 인식
dst = cv2.Canny(dst, lower, upper, 3)

# 원본 및 엣지 검출된 이미지 출력
cv2.imshow('Original Image', img)  # 원본 이미지
cv2.imshow('Canny Edge Detection', dst)  # Canny 엣지 검출 이미지

cv2.waitKey(0)  # 키 입력 대기
cv2.destroyAllWindows()  # 모든 창 닫기

 

예시 16)

import cv2 
import numpy as np  # Numpy 라이브러리 불러오기 (행렬 연산)

# 이미지 불러오기
img = cv2.imread('./images/dog.bmp')

# 이미지가 정상적으로 불러와졌는지 확인
if img is None:
    print("이미지를 불러올 수 없습니다.")
    exit()

# 이미지의 중간(중앙) 픽셀 값 계산 (Canny 엣지 검출을 위한 임계값 설정)
med_val = np.median(img)
print(f"Median Pixel Value: {med_val}")  # 예: 129.0

# Canny 엣지 검출을 위한 낮은 임계값과 높은 임계값 설정
lower = int(max(0, 0.7 * med_val))  # 0보다 작은 값 방지
print(f"Lower Threshold: {lower}")  # 예: 90

upper = int(min(255, 1.3 * med_val))  # 255보다 큰 값 방지
print(f"Upper Threshold: {upper}")  # 예: 167

# 가우시안 블러 적용 (노이즈 제거)
dst = cv2.GaussianBlur(img, (3, 3), 0)

# Canny 엣지 검출 적용
# Canny(입력 이미지, 낮은 임계값, 높은 임계값, Sobel 커널 크기)
# 낮은 임계값보다 작은 값은 무시하고, 높은 임계값보다 큰 값만 엣지로 인식
dst = cv2.Canny(dst, lower, upper, 3)

# 원본 및 엣지 검출된 이미지 출력
cv2.imshow('Original Image', img)  # 원본 이미지
cv2.imshow('Canny Edge Detection', dst)  # Canny 엣지 검출 이미지

cv2.waitKey(0)  # 키 입력 대기
-->
129.0
90
167

--->

 

728x90
LIST

'컴퓨터 비전' 카테고리의 다른 글

Object Detection  (2) 2025.03.07
OCR  (6) 2025.03.06
4. OpenCV  (0) 2025.03.05
3. 포켓몬 분류 데이터셋  (8) 2025.03.04
2. Classification  (0) 2025.02.28