픽셀 기반 영상처리와 영역 기반 영상처리가 무엇인가?
by 효기’s
python을 사용하여 openCV 영상처리 실습
배경 내에 검정 좌표를 이동시키는 방법 (픽셀 값을 읽고 바꾸기)
import cv2
import numpy as np
img = cv2.imread('images/scene2.jpg', cv2.IMREAD_GRAYSCALE) #이미지를 Grayscale로 읽는다
cv2.imshow('Image Processing', img)
print(img.shape)
px = img[200,200]
print(px)
img[100:210,100:210] = 0 #[배경상단 100 : 세로, 배경좌측 100 : 가로]
cv2.imshow('Results', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
픽셀 값과 컬러 영상을 읽는다.
import cv2
import numpy as np
img = cv2.imread('images/scene2.jpg', cv2.IMREAD_COLOR) #이미지파일을 컬러로 읽어들인다.
cv2.imshow('Image Processing', img)
print(img.shape)
px = img[100,100]
print(px)
img[100:110,100:110] = 0 # black
img[110:120,110:120] = [255,255,255] # white (컬러를 바꾸고 싶으면 이부분을 수정해본다)
cv2.imshow('Results', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
컬러 영상을 읽고 red, green, blue 채널을 분리한다.
import cv2
import numpy as np
img = cv2.imread('images/fruits.png', cv2.IMREAD_COLOR) #이미지 파일을 읽어들인다.
cv2.imshow('Image Processing', img)
# b,g,r = cv2.split(img)
# img = cv2.merge((b,g,r))
# split()함수보다 numpy indexing이 빠르다.
b = img[:,:,0] #파란색(blue) 채널분리
g = img[:,:,1] #녹색 (green) 채널분리
r = img[:,:,2] #빨간색 (red) 채널분리
cv2.imshow('Blue', b)
cv2.imshow('Green', g)
cv2.imshow('Red', r)
cv2.waitKey(0)
cv2.destroyAllWindows()
산술연산 ( 각 픽셀에 +, -, *, / )
import cv2
import numpy as np
img = cv2.imread('images/scene2.jpg', cv2.IMREAD_GRAYSCALE)
cv2.imshow('Image Processing', img)
img_plus = cv2.add(img, 50,) # cv2연산은 saturated 연산이어서 255보다 크면 255로 고정됨
img_minus = cv2.subtract(img, 50) # cv2연산은 saturated 연산이어서 0보다 작으면 0으로 고정됨
img_mul = cv2.multiply(img,2)
img_div = cv2.divide(img,2)
# img_plus = img + 50 #이것도 가능하나, 0~255로 변환이 필요하다.
img_pp = np.clip(img+50., 0, 255).astype(np.uint8)
# opencv에는 이외에도 max(), min(), minMaxLoc(),
# bitwise_and(), bitwise_or() 등 다양한 함수를 제공한다.
cv2.imshow('ResultsP', img_plus) #+
cv2.imshow('ResultsM', img_minus) #-
cv2.imshow('ResultsMu', img_mul) #*
cv2.imshow('ResultsD', img_div) #/
cv2.imshow('ResultsPP', img_pp)
cv2.waitKey(0)
cv2.destroyAllWindows()
색이 있는 산술연산 ( 각 픽셀에 +, -, *, / )
import cv2
import numpy as np
img = cv2.imread('images/scene2.jpg', cv2.IMREAD_COLOR)
cv2.imshow('Image Processing', img)
img_plus = cv2.add(img, (50,50,50,0)) # cv2연산은 saturated 연산이어서 255보다 크면 255로 고정됨
img_minus = cv2.subtract(img, (50,50,50,0)) # cv2연산은 saturated 연산이어서 0보다 작으면 0으로 고정됨
img_mul = cv2.multiply(img,(2,2,2,0))
img_div = cv2.divide(img,(2,2,2,0))
# opencv에는 이외에도 max(), min(), minMaxLoc(),
# bitwise_and(), bitwise_or() 등 다양한 함수를 제공한다.
cv2.imshow('ResultsP', img_plus) #+
cv2.imshow('ResultsM', img_minus) #-
cv2.imshow('ResultsMu', img_mul) #*
cv2.imshow('ResultsD', img_div) #/
cv2.waitKey(0)
cv2.destroyAllWindows()
이진화 (Thresholding)
import cv2
import numpy as np
img = cv2.imread('images/apples.jpg', cv2.IMREAD_GRAYSCALE)
cv2.imshow('Image Processing', img)
#cv2.THRESH_BINARY : 픽셀 값이 임계값을 넘으면 value로 지정하고, 넘지 못하면 0으로 지정
ret, img_binary = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) # 127임계값, 255 픽셀값
# 최적의 임계값을 찾아주는 otsu의 알고리즘 적용
ret, img_otsu = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
cv2.imshow('ResultsB', img_binary)
cv2.imshow('ResultsO', img_otsu)
cv2.waitKey(0)
cv2.destroyAllWindows()
적응적 이진화 (adaptiveThreshold)
import cv2
import numpy as np
img = cv2.imread('images/sudoku.jpg', cv2.IMREAD_GRAYSCALE)
cv2.imshow('Image Processing', img)
blk_size = 9 # 블럭 사이즈
C = 5 # 차감 상수
ret, img_otsu = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
img_a1 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY, blk_size, C)
img_a2 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, blk_size, C)
cv2.imshow('Results Otsu', img_otsu) #OTSU 알고리즘을 적용
cv2.imshow('Results Adaptive1', img_a1) #적응적 이진화 : 이웃 픽셀의 평균으로 결정
cv2.imshow('Results Adaptive2', img_a2) #적응적 이진화 : 가우시안 분포에 따른 가중치의 합으로 결정
cv2.waitKey(0)
cv2.destroyAllWindows()
히스토그램
import cv2
import numpy as np
import matplotlib.pylab as plt
# 이미지 그레이 스케일로 읽기 및 출력
img = cv2.imread('images/Lenna.png', cv2.IMREAD_GRAYSCALE)
cv2.imshow('Image Processing', img)
# 히스토그램 계산 및 그리기
# 이미지 리스트에 감싸서 전달, 분석 처리 할 채널 리스트에 감싸서 전달,
# 마스크에 지정한 픽셀만 히스토그램 계산 None이면 전체영역, 계급(Bin)의 개수 채널 개수에 맞게 리스트로 표현, 픽셀이 가질 수 있는 값의 범위 RGB인경우 [0, 256]
hist = cv2.calcHist([img], [0], None, [256], [0,256])
plt.plot(hist) #히스토그램 출력
print("hist.shape:", hist.shape) # 히스토그램의 shape (256,1)
print("hist.sum():", hist.sum(), "img.shape:",img.shape) # 히스토그램 총 합계와 이미지의 크기
plt.show()
컬러 영상의 히스토그램
import cv2
import numpy as np
import matplotlib.pylab as plt
# 컬러영상
img = cv2.imread('images/Lenna.png', cv2.IMREAD_COLOR)
cv2.imshow('Image Processing', img)
# 히스토그램 계산 및 그리기
channels = cv2.split(img)
colors = ('b', 'g', 'r')
for (ch, color) in zip (channels, colors):
hist = cv2.calcHist([ch], [0], None, [256], [0, 256])
plt.plot(hist, color = color)
plt.show()
히스토그램 평활화
import cv2
import numpy as np
import matplotlib.pylab as plt
# 그레이 스케일로 읽기
img = cv2.imread('images/low_contrast.jpg', cv2.IMREAD_GRAYSCALE)
rows, cols = img.shape[:2]
# 히스토그램 평활화 계산
hist = cv2.calcHist([img], [0], None, [256], [0, 256]) # 히스토그램 계산
cdf = hist.cumsum() # 누적 히스토그램
cdf_m = np.ma.masked_equal(cdf, 0) # 0(zero)인 값을 NaN으로 제거
cdf_m = (cdf_m - cdf_m.min()) /(rows * cols) * 255 # 이퀄라이즈 히스토그램 계산
cdf = np.ma.filled(cdf_m,0).astype('uint8') # NaN을 다시 0으로 환원
print(cdf.shape)
img2 = cdf[img] # 히스토그램을 픽셀로 맵핑
# OpenCV API로 이퀄라이즈 히스토그램 적용
img3 = cv2.equalizeHist(img)
# 이퀄라이즈 결과 히스토그램 계산
hist2 = cv2.calcHist([img2], [0], None, [256], [0, 256])
hist3 = cv2.calcHist([img3], [0], None, [256], [0, 256])
# 결과 출력
cv2.imshow('Before', img)
cv2.imshow('Manual', img2)
cv2.imshow('cv2.equalizeHist()', img3)
hists = {'Before':hist, 'Manual':hist2, 'cv2.equalizeHist()':hist3}
for i, (k, v) in enumerate(hists.items()):
plt.subplot(1,3,i+1)
plt.title(k)
plt.plot(v)
plt.show()
컬러영상 히스토그램 평활화
import cv2
import numpy as np
import matplotlib.pylab as plt
# 컬러영상 읽기
img = cv2.imread('images/cute.jpg', cv2.IMREAD_COLOR)
# 컬러공간을 HSV로 변경
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# V(밝기값) 공간에 히스토그램 평활화 적용
img_hsv[:,:,2] = cv2.equalizeHist(img_hsv[:,:,2])
# 컬러공간을 RGB로 원위치
img2 = cv2.cvtColor(img_hsv, cv2.COLOR_HSV2BGR)
b, g, r = cv2.split(img)
b = cv2.equalizeHist(b)
g = cv2.equalizeHist(g)
r = cv2.equalizeHist(r)
img3 = cv2.merge((b,g,r))
# 결과 출력
cv2.imshow('Before', img)
cv2.imshow('After', img2)
cv2.imshow('RGB', img3)
cv2.waitKey()
cv2.destroyAllWindows()
영역기반 영상처리
입력 픽셀과 그 주변 픽셀을 이용하여 출력 픽셀 값을 결정
합성곱 기법을 널리 이용
ex) 흐리게하기, 선명하게하기, 경계산 검출, 노이즈 제거
합성곱 (Convolution) 필터 적용으로 영상 흐림
합성곱 : 하나의 함수와 다른 함수를 반전 이동한 값을 곱하고 구간에 대해 적분하여 새로운 함수를 구하는 수학 연산자(회선)
콘볼루션 : 함수 f가 주어졌을 떄 우리가 원하는 목적에 따라 함수 g를 선정하여 분해, 변환, 필터링 할 수 있다.
합성곱 영상처리 : 입력 픽셀과 주위 픽셀 값에 합성곱 마스크의 값을 곱하여 더한 값을 출력 픽셀 값으로 정한다.
합성곱하는 함수 : 마스크(mask), 필터(filter), 템플릿(template), 커널(kernel)
마스크가 데칭이므로 실제 연산은 correlation(상관) 과 같다.
import cv2
import sys
import numpy as np
img = cv2.imread('images/Lenna.png', cv2.IMREAD_COLOR)
if img is None:
print('영상 읽기 실패')
sys.exit()
size = 7 #사이즈를 조절하면 흐림 정도 조절가능 높을수록 흐림
kernel = np.ones((size, size), dtype=np.float64) / (size*size)
result = cv2.filter2D(img, -1, kernel)
cv2.imshow('Original', img)
cv2.imshow('Result', result)
cv2.waitKey()
cv2.destroyAllWindows()
합성곱 (Convolution) 마스터
# blur()함수로 영상 흐림
import cv2
import sys
import numpy as np
img = cv2.imread('images/Lenna.png', cv2.IMREAD_GRAYSCALE)
if img is None:
print('영상 읽기 실패')
sys.exit()
result3 = cv2.blur(img, (3,3))
result5 = cv2.blur(img, (5,5))
cv2.imshow('Original', img)
cv2.imshow('Result3', result3)
cv2.imshow('Result5', result5)
cv2.waitKey()
cv2.destroyAllWindows()
합성 곱 마스터 특징 : 픽셀 주변을 대칭적으로 계산하므로 홀수 값을 사용(3 * 3, 5 * 5)
마스크 계수의 합은 1또는 0이 되도록 함
0 -1 0
-1 5 -1
0 -1 0
경계 계산 : 0으로 계산, 이웃 픽셀 값 복사, wrap-around 등, 경계선 안쪽에서만 합성곱 계산, 계산 안된 부분은 그대로
영상 흐리게 하기 (Blurring) : 영상의 노이즈를 없애거나, 부드럽게 한다(smoothing), 평균값, 가우시안, 중간값 등의 필터 사용
평균값 필터로 흐리게 하기 : 영상의 노이즈는 없애지만 명암비는 낮아짐 (일반적인 잡티를 없앨 수 있음)
가우시안 필터로 흐리게하기
중앙 픽셀의 가중치가 높음 (영상의 중요 부분 보전 하면서 흐려짐)
# GaussianBlur()함수로 영상 흐림
import cv2
import sys
import numpy as np
img = cv2.imread('images/Lenna.png', cv2.IMREAD_GRAYSCALE)
if img is None:
print('영상 읽기 실패')
sys.exit()
# sigma 지정
result1 = cv2.GaussianBlur(img, (0,0), 1)
result3 = cv2.GaussianBlur(img, (0,0), 3)
# ksize 지정, mean smoothing과 비교
resultB = cv2.blur(img, (5,5)) #평균값필터
resultG = cv2.GaussianBlur(img, (5,5), 0)
cv2.imshow('Original', img)
cv2.imshow('Result_S_1', result1)
cv2.imshow('Result_S_3', result3)
cv2.imshow('Result_mean', resultB) #평균값필터
cv2.imshow('Result_Gaussian', resultG)
cv2.waitKey()
cv2.destroyAllWindows()
중간값 필터 (Median) 필터
비전형 필터, 이웃 픽셀들 값을 오름차순으로 정렬한 수 중앙에 있는 값을 출력 값으로 선택
노이즈 제거에 효과적
# Median Filtering 중간값 필터
import cv2
import sys
import numpy as np
# img = cv2.imread('images/Lenna.png', cv2.IMREAD_GRAYSCALE)
# img = cv2.imread('images/pns.jpg', cv2.IMREAD_GRAYSCALE)
img = cv2.imread('images/gnoise.jpg', cv2.IMREAD_GRAYSCALE)
if img is None:
print('영상 읽기 실패')
sys.exit()
# sigma 지정
result3 = cv2.medianBlur(img, 3)
result5 = cv2.medianBlur(img, 5)
# ksize 지정, mean smoothing과 비교
resultB = cv2.blur(img, (5,5))
resultG = cv2.GaussianBlur(img, (5,5), 0)
cv2.imshow('Original', img)
cv2.imshow('Result_3', result3) #중간값 필터3
cv2.imshow('Result_5', result5) #중간값 필터5
cv2.imshow('Result_mean', resultB) #평균값필터
cv2.imshow('Result_Gaussian', resultG) #가우시안필터
cv2.waitKey()
cv2.destroyAllWindows()
'Studying' 카테고리의 다른 글
웹 프로그래밍 Web programming 이란? (0) | 2023.09.19 |
---|---|
[JAVA] Day 02 AWT 이벤트 리스너 (2) | 2023.09.06 |
아두이노와 MCU 그리고 LED 저항 읽는법 알아보기 (0) | 2023.04.04 |
영상 흐림과 선명화와 경계선 검출 다중 영상처리 개념 (0) | 2023.03.24 |
픽셀(pixel)과 히스토그램 평활화가 무엇인가? (2) | 2023.03.13 |
블로그의 정보
감성 개발자 효기
효기’s