-
이미지 처리-1 이미지 기초 처리이미지 처리 2023. 6. 14. 17:48
1. PIL, openCV
PIL(Python Imaging Library)는 파이썬에서 이미지를 저장하고 여러 가지 작업을 할 수 있게 만들어주는 라이브러리이다.
OpenCV(Open Source Computer Vision)는 실시간 이미지처리를 위한 라이브러리이며 c/c++에서 개발되어 널리 사용되고 있다.
따라서 pil 라이브러리는 간단하고 직관적인 api로 가벼운 이미지 처리 툴로서 사용되며 opencv는 이미지 처리와 함께 영상 처리, 컴퓨터 비전 등 이미지 연산 등을 목적으로 가진다.
2. 이미지 출력, 크기 조정, 자르기
import matplotlib.pyplot as plt import cv2 image_path = '../../../../kim/photo/dog and cat/cat/images.jfif' image = cv2.imread(image_path) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) plt.imshow(image) plt.show()
주피터 노트북 환경에서는 cv.imshow 함수를 직접 사용할 수 없기 때문에 matplotlib 라이브러리를 불러와서 plt.show 함수를 이용해서 이미지를 출력한다.
cv2.imread 함수로 이미지의 경로를 읽어오며 ../ 하나당 상위 폴더 한 개를 의미한다. opencv에서는 사진을 bgr 순서로 사용하고 matplotlib에서는 rgb 순서로 사용하기 때문에 cvtColor 함수를 사용하여 bgr 순서를 rgb 순서로 변환한다.
image_resize = cv2.resize(image, (220,220)) plt.imshow(image_resize) plt.show()
resize 함수를 사용하여 이미지의 크기를 재조정할 수 있다. 170*270이었던 이미지를 220*220으로 조정했다.
cv2.imwrite('./resize_image.png',image_resize) True
imwrite 함수는 이미지를 지정된 경로로 저장할 수 있다.
image_cropped = image[10:,:200] plt.imshow(image_cropped) plt.show()
배열을 슬라이싱을 이미지에도 똑같이 적용할 수 있으며 세로 10번 픽셀부터 끝까지, 가로 처음부터 200번 픽셀까지 자를 수 있다.
3. 이미지 필터
import numpy as np kernel = np.ones((10,10))/140 image_kernel = cv2.filter2D(image, -1,kernel) plt.imshow(image_kernel) plt.show()
직접 커널을 생성하여 이미지를 흐릿하게 만들 수 있다. 커널은 실수형이여야 하며 10*10의 배열로 1의 값을 채우고 140으로 나누어 커널을 생성하고 filter2 D 함수를 사용하여 이미지를 필터링한다. -1은 대상 이미지의 깊이 속성이며 -1으로 설정하면 입력 사진과 동일한 깊이를 의미한다.
커널로 필터링 할 때 커널의 행렬이 커질수록 더 흐릿해지고 커널의 값이 클수록 선명해지고 작을수록 흐릿해지지만 일정 수준 이상을 넘어가면 완전히 선명해져 하얀색 사진이 된다.
image_gaussianBlur = cv2.GaussianBlur(image, (5,5),0) plt.imshow(image_gaussianBlur) plt.show()
가우시안 블러는 정규분포를 가지는 커널로 이미지를 흐릿하게 하는 방법이다. 모두 균일한 값으로 진행했던 이전의 블러처리와 달리 중앙값이 크고 멀어질수록 값이 작아진다.
이미지를 GaussianBlur 함수에 넣고 5*5 행렬로 블러처리를 한다. 가우시안 블러의 행렬은 홀수 행렬로 구성해야 하며 행렬 값이 클수록 사진은 흐려진다.
image_sharp = cv2.filter2D(image, -1, np.array([[0,-1,0], [-1,5.5,-1], [0,-1,0]])) plt.imshow(image_sharp) plt.show()
filter 2D 함수를 사용하여 특정 배열을 활용하여 이미지를 선명하거나 흐려지게 만들 수 있다. 이전의 코드에서는 zero.ones를 사용하여 일정한 숫자를 구성하여 평균적으로 흐리게 만들었다면 2D 필터에서 값들을 잘 조정하여 이미지를 선명하게 나타낸다.
4. 이미지 평활화, 이진화
image_gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY) image_enhanced = cv2.equalizeHist(image_gray) plt.imshow(image_enhanced,'gray') plt.show()
equalizeHist 함수를 사용하여 히스토그램 평활화를 진행할 수 있다. 히스토그램 평활화는 명암의 분포를 고르게 할 수 있다. 회색 이미지로 변경하는 이유는 연산의 양을 줄일 수 있다.
image_gray = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) max_output_value = 255 neighborhood_size = 99 subtract_from_mean =10 image_binarized = cv2.adaptiveThreshold(image_gray, max_output_value, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, neighborhood_size, subtract_from_mean) plt.imshow(image_binarized,'gray') plt.show()
이미지 이진화는 임계값보다 큰값은 흰색으로 작은 값은 검은색으로 만드는 방법이다.
5. 이미지 회전, 반전
image_90 =cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE) image_180 = cv2.rotate(image, cv2.ROTATE_180) image_270 = cv2.rotate(image, cv2.ROTATE_90_COUNTERCLOCKWISE) plt.imshow(image_90) plt.show() plt.imshow(image_180) plt.show() plt.imshow(image_270) plt.show()
cv2.ROTATE 함수로 사진을 회전할 수 있다.
dst_1 = cv2.flip(image,1) dst_2 = cv2.flip(image, 0) plt.imshow(dst_1) plt.show() plt.imshow(dst_2) plt.show()
cv2.flip 함수는 사진을 좌우, 상하 반전시킨다.
6. 이미지 배경 제거
rectangle = (35,15,190,180) mask = np.zeros(image.shape[:2], np.uint8) bgdModel = np.zeros((1,65), np.float64) fgdModel = np.zeros((1,65), np.float64) cv2.grabCut(image, mask, rectangle, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_RECT ) mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8') image_rgb_nobg = image * mask2[:,:,np.newaxis] plt.imshow(mask2) plt.show() plt.imshow(image_rgb_nobg) plt.show()
배경을 제거하기 위해 원하는 이미지의 크기만큼 사각형을 생성하고 grabCut에 사용할 배경 모델, 전경 모델 두 가지를 생성하여 grabCut 함수를 실행하여 배경을 제거한다. 5번 반복해서 실행하며 그림을 자르기 위한 마스크를 생성하고 이미지에 확장된 마스크 2를 곱하여 배경을 제거한다.
7. 이미지 경계선
image_grey = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) median_intensity = np.median(image_gray) lower_threshold = int(max(0,(1.0 -0.33)*median_intensity)) upper_threshold = int(min(255,(1.0 +0.33)*median_intensity)) image_canny = cv2.Canny(image_grey, lower_threshold, upper_threshold) plt.imshow(image_canny,'gray') plt.show()
canny 함수를 사용하여 경계선을 감지한다. cv2.Canny 함수는 낮은 임계값과 높은 임계값을 필요로 하며 낮은 임계값과 높은 임계값 사이에 있는 픽셀은 약한 경계선으로 높은 임계값보다 큰 픽셀은 강한 경계선으로 나타낸다.
8. 이미지 모서리, 차원 축소
image_gray = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) image_gray = np.float32(image_gray) bl_size = 4 aper=29 fr_params = 0.04 detect_res = cv2.cornerHarris(image_gray, bl_size, aper, fr_params) detect_res = cv2.dilate(detect_res, None) threshold = 0.01 for i in range(detect_res.shape[0]): for j in range(detect_res.shape[1]): if detect_res[i,j]> threshold * detect_res.max(): cv2.circle(image,(j,i), radius=5, color = (0,0,255),thickness= -1) image =cv2.cvtColor(image, cv2.COLOR_BGR2RGB) plt.imshow(image) plt.show()
cv2.cornerHarris 함수를 사용하여 이미지의 모서리를 감지할 수 있다. cv2.dilate 함수는 모서리를 강조시킨다. detect_res로 추출된 값들이 detect_res.max * 임계값보다 높다면 빨간 점으로 표시한다.
image_10x10 = cv2.resize(image_gray,(10,10)) image_10x10.flatten() plt.imshow(image_10x10,'gray') plt.show() image_255x255 = cv2.resize(image_gray,(255,255)) image_255x255.flatten() plt.imshow(image_255x255) plt.show()
ㄹflatten 함수는 이미지 데이터를 1차원 벡터로 변환할 수 있다.
'이미지 처리' 카테고리의 다른 글
이미지 처리-5 이미지 혼합 (0) 2023.06.19 이미지 처리-4 얼굴 이미지 회전 (0) 2023.06.19 이미지 처리-3 번호판 (2) 2023.06.18 이미지 처리-2 이미지 필터 처리 (0) 2023.06.17