데이터분석/Vision Recognition

① 파이썬 - 컴퓨터 비전 프로그래밍 (Basic Image Handling and Processing) (1)

늘근이 2015. 9. 30. 11:21

 

본 글은 Programming Computer Vision with Python (Jan Erik Solem) 을 그대로 따라간거임.

 

 


 

Basic Image Handling and Processing

Local Image Descriptor

Image to Image Mappings

Camera Models and Augmented Reality

Multiple View Geometry

 Clustering Images

 Searching Images

 Classifying Image Content

 Image Segmentation

 OpenCV

 


 

 

 

파이썬과 라이브러리 설치

 

일단 이것저것 라이브러리 깔기가 귀찮으니, 아나콘다로 한방에 패키지 설치를 끝낸다.

 

 

파이썬 3.4는 그다지 기능적인 면에서 막 업그레이드 된것 같지는 않지만 최신기술을 쓴다는 자기합리화 아래 위와같이 설치한다.

 

 

 

Python Image Library 기본 사용 - 로딩 / 그레이스케일적용 / 저장

 

아나콘다를 설치할때 QT Console이 설치되어있을것이다. 이걸 실행시키고

간단한 이미지를 조작하기 전에 이미지를 저장하는 디렉토리의 확인이 필요하다.

 

 

import os

os.getcwd()

 

로 확인 가능하다.

 

이미지 파일로는 다음과 같은 사진을 준비했다.

 

image.png

저옆의 빨간신발은 신경쓰지 않도록 한다.

 

 

이미지가 준비되었으면 해당하는 경로에 넣고 파이썬 콘솔로 불러본다.  (소문자 / 대문자에 주의)

 

from PIL import Image

image = Image.open('image.png')

 

 

그리고 그림에 간단한 그레이스케일 ( 회색으로 변환시키기 ) 을 적용한후

 

image2 = image.convert('L')

 

 

저장한다

 

image2.save('image2.png')

 

 

 

 

확인해보면 위와같은 image2.png가 해당 경로에 저장되었음을 확인할수 있다.

 

 

그레이스케일로 변환하는것 뿐만 아니라 그밖에도 다음과 같은 간단한 것들이 있다.

 

thumbnail((128,128)) - 작은크기의 썸네일 생성

crop((100,100,400,400)) - 자르기

paste(위크롭한거,(100,100,400,400)) - 붙여넣기

resize(((128,128)) - 사이즈 조정

rotate(45) - 각도 회전

 

 

Matplotlib - 그래프

 

사진 조작 라이브러리보다 많이 쓰이는게 Matplotlib과 같은 그래프 라이브러리일듯.

 

 

from pylab import *

im = array(Image.open('image.png'))

show()

 

 

 

복잡한 프로그래밍을 위한 코드 에디터 추천

 

여기서부터는, 이미지를 로딩하면서 콘솔이 느려지고 답답할수 있으므로 차라리 Sublime Editor나 정말 가벼운 마이크로소프트 Visual Studio Code프로그램을 사용하여서 py확장자로 저장한 다음 실행시키는게 낫다.

 

 

 

 

 

 

 

 

히스토그램과 같이 보기

 

아무래도 머신러닝쪽에서 행렬과 벡터를 이용해 이것저것 계산하기 때문에 array로 변환한 다음 작업을 꽤 많이 한다. 이를 위해서는 먼저 그림을 배열에 넣고, 이를 히스토그램 figure2에서 변환해서 띄워볼수있다.

 

 

from PIL import Image
from pylab import *

im = array(Image.open('image.png').convert('L'))


figure() 
gray() 

contour(im, origin='image')
axis('equal')
axis('off')


figure()
hist(im.flatten(),128)
show()

 

 figure() 함수를 통해서 동시에 두개 이미지가 띄워지도록 하고있다.

 

 

참조로 위의 두개 사진은 별개이다. 히스토그램은 contour변환전 히스토그램으로 오리지널 데이터를 히스토그램화 시킨것이다. 

근데 도대체 이게 무슨 그래프냐구. 2차원 배열로 되어있는 놈을  flatten() 하면 일자로 주욱 늘어진다. hist()메서드가 인자로 일차원 배열만 받기 때문에 변환을 시켜서 얼마나 찐한놈들이 오나 히스토그램으로 변환시킨것이다.

이그림은 샘플이 별로 안좋기는 한데, 만약 검은게 안쪽에 몰려있으면 히스토그램은 중앙분포일것이다.


Numpy

이제 조금더 파이썬에서 자주 쓰는 라이브러리인 Numpy를 한번 써서 그림을 분석하고 평균화 하여 조금 더 '평평한' 이미지를 만들어본다.

 만약 광원이 불규칙하다면 한쪽은 굉장히 하얗고 한쪽은 굉장히 까맣게 잘 안나온 사진이 있을수 있다. 이러한 이미지를 일단 Numpy에서 제공하는 행렬로 변환한 다음에 어느정도 이미지 변환을 거쳐서 다시 저장할수 있다.

보통 아래와 같이 변환하며

array(Image.open('image.png').convert('L'))

행렬을 만들어내며 작업이 끝났다면 이미지로 변환 가능하다.

Image.fromarray(image)


처음 그림은 다음과 같았다.


바로 위의 히스토그램에서 볼수 있다시피 그다지 평준화된 사진은 아니다. 조금더 그레이 스케일을 평평하게 만들어 식별가능하게 만들어볼수있다. 아래와 같은 다소 복잡한 코드를 통해 사진을 변환한다.


 from PIL import Image
from numpy import *
from pylab import *


def histeq(im,nbr_bins=256) :
 # get image histogram
 imhist,bins = histogram(im.flatten(),nbr_bins,normed=True)
 cdf = imhist.cumsum() # cumulative distribution function
 cdf = 255 * cdf / cdf[-1] # normalize
 # use linear interpolation of cdf to find new pixel values
 im2 = interp(im.flatten(),bins[:-1],cdf)
 return im2.reshape(im.shape), cdf
 
 
im = array(Image.open('image.png').convert('L'))
im2, cdf = histeq(im,256)

image = Image.fromarray(im2).convert('RGB')
image.save("image_test.png")

figure()
hist(im2.flatten(),256)
show()

def 메서드 선언을 통해 아예 메서드로 구현했다. CDF는 Cumulative Distribution Function으로써 누적적으로 픽셀의 값이 대각선이 되도록 도와주는 함수다. 적절한 normalize과정을 거쳐서 평평한 사진이 완성될것이다.


변환된 그림은 아래와 같다.


솔직히 위의 사진은 좀더 과장되었고 구린 느낌이긴 한데 어쨌거나 아래의 히스토그램을 참조한다면 분명히 '평평해진' 사진은 맞는듯 해 보인다. 이러한 사진은 부자연스럽게 보일수는 있어도 기계의 입장에서는 또 나름 괜찮은 샘플일수 있다. 일단은 검정과 하양의 경계가 과장되게 보여주어야 기계입장에서는 편할것이므로..