본문 바로가기
파이썬으로 배우는 지구과학

파이썬을 이용하여 사진의 RGB 색상 분석하기

by 0대갈장군0 2022. 6. 15.
반응형

파이썬을 사용하면 이미지를 분석하거나 약간의 보정도 가능합니다. 정말 못하는게 없는거 같습니다. 다만 파이썬을 이용하여 이미지 처리를 할 때에는 좀 색다를 라이브러리를 써야 합니다. PIL이라는 라이브러리인데요, 이 바닥에서는 꾀 유명한 라이브러리로, 이미지 분석을 위해 개발되었습니다. 일반적으로 아나콘다를 설치할 때에는 요 라이브러리가 설치되지 않기 때문에 라이브러리를 따로 설치해야 합니다.

  1. 라이브러리 설치

그런데 보통 라이브러리를 설치할 때 해당 라이브러리의 이름을 쳐서 설치합니다. 우리는 PIL을 설치해야 하므로 아래와 같은 명령어를 생각하실 겁니다.

더보기

pip install PIL

쳐 보신 분들은 아실겁니다. 설치 안되고 오류가 뜹니다..ㅠㅠ

 

사실 PIL이라는 것을 사용하려면 pillow라는 라이브러리를 설치해야 됩니다. 

더보기

pip install pillow

라이브러리 설치를 위해 저 명령어를 치는 곳은 어딘지 다들 아실거라 생각하지만, 혹시 모르시는 분을 위해 말씀 드리면, anaconda 기준으로 anaconda prompt(anaconda3)를 실행하여 명령 프롬프트에 저 위의 명령어를 치시면 됩니다.

전 이미 설치를 하여 위와 같이 나오네요.

  2. 분석할 이미지 가져오기

이미지야 무엇을 분석하던 상관 없습니다. 여기는 과학, 특히 지구과학 관련 파이썬이니까 연속스펙트럼을 분석해 보겠습니다.

저는 위의 스펙트럼을 사용하였는데, 필요하신 분들이 다운로드 하실 수 있도록 아래에 파일을 넣어 두겠습니다.

anospec.jpg
0.00MB

  3. 사진의 픽셀 수 확인

첫 번째로, 사진의 전체 픽셀 수를 알아야 합니다. 그래야 분석할 위치를 찾을 수 있기 때문인데, 코드는 간단합니다.

#그림 불러오기 및 그림 크기 확인
from PIL import Image
import numpy as np
im=Image.open('C:\\111\\anospec.jpg')
pix=np.array(im)
print(im.size)

저 위의 코드를 실행하면 아래와 같은 결과가 나옵니다.

저것이 의미하는 것은 간단합니다. 가로 방향으로 총 512개의 픽셀이, 세로 방향으로 총 85개의 픽셀이 있다는 소리겠지요.

코드를 해석하면,  우선 Image라는 라이브러리에 있는 사진을 불러오는 명령어 open을 이용해 분석할 사진을 불러 오는것이 im=Image.open 이하의 코드입니다.

다음으로는 np.array(im)이라는 코드인데, 이건 사실 1차원이나 2차원의 행렬형태의 배열을 만드는 코드입니다. 저 코드를 이용하는 이유는 간단합니다. 각 픽셀의 위치를 번호를 부여하여 2차원 배열형태로 나타내기 위함입니다. 그래서 pix=np.array(im)이라고 한 것입니다.

그리고 마지막으로 print(im.size)라고 함은, 변수 im에서 지정한 스펙트럼 사진의 크기, 다시말해 2차원 배열의 가로 세로 수가 얼마인지를 출력해내라는 소리입니다.

반응형

  4. 픽셀별 RGB 색상 분석하기

이제 픽셀 수를 알았으면, 해당 픽셀의 RGB 값을 찾아낼 차례입니다.

 

만약 가로로 200번째, 세로로 40번째의 픽셀의 RGB값을 알고 싶다면 이렇게 하면 됩니다.

print(pix[40][200])

이게 좀 이상한데, 보통 가로를 먼저 세로를 다음에 표시하기 때문입니다. 하지만 여기서는 희안하게 세로를 먼저 씁니다. 이건 이유가 간단합니다. 첫 번째는 행, 두 번째는 열을 나타내기 때문입니다. 그래서 마치 세로가 먼저, 가로가 다음으로 표기하는 것 처럼 보이는 것입니다. 햇깔릴 수 있고, 실수하기 쉬운 부분이니 조심하셔야 해요.

 

어쨌든 저렇게 코드를 치고 실행하면 아래와 같은 결과가 나옵니다.

[253, 217,1] 이라는 데이터가 나왔습니다. 의미는 간단합니다. 숫자를 RGB 순서대로 출력한 것인데, R은 253, G는 217, B는 1이라는 소리입니다.

 

여기서 잠깐 RGB 색상의 구현 방법을 아주 간단하게만 소개하겠습니다. 색상의 표현방법은 RGB뿐만 아니라 여러가지가 있는데, 가장 이해하기 쉬운 RGB를 우선 이야기 하면, 크게 빨강, 녹색, 파란색의 조합으로 모든 색을 표현한다 생각하면 됩니다. 각각의 최소값은 0이고 최대값은 255인데, 적색같은 경우 RGB는 [255, 0, 0], 녹색의 경우 [0,255,0], 파란색의 경우[0,0,255]가 되는 식입니다. 완전히 검정색은 [0,0,0], 완전히 흰색은 [255,255,255]가 됩니다. 이하 다른 색상 조합은 아래 표를 보시면 알 수 있을 것입니다.

뭐 저런 식으로 오만가지 색을 다 표현한다 생각하시면 됩니다.

  5. 모든 픽셀의 RGB 색상 분석하기

그런데 픽셀 하나하나 분석하는건 문제가 안됩니다. 코드도 간단하구요. 그렇다면 통째로 분석하고 싶다면? 특히 예를들어 저런 스펙트럼의 경우 한 줄을 통째로 분석하는것이 더 의미가 있습니다. 색상이 연속적으로 변하기 때문인데요,

예를 들어 위 그림의 보라색 상자안의 가로 방향으로 RGB 색상이 연속적으로 어떻게 변화하는지 본다면 꾀 재미있습니다.

그래서 아래와 같이 for문을 사용하여 코드를 짭니다.

#픽셀별 R,G,B 값 추출
import numpy as np
c=np.arange(1,512,1)
text=open('C:\\111\\anospec3.txt', 'a')
for a in c:
    print(pix[41][a], file=text)
text.close()

코드를 번역해 보겠습니다.

c=np.arange(1,512,1)은 1부터 511까지를 1간격으로 숫자를 출력 하겠다는 것.

for문 이하는 간단하니까 금새 아실겁니다.

text=open('C:\\111\\anospec3.txt', 'a') → anospec3라는 텍스트 파일을 만든다.
print(pix[40][a], file=text) → for문에서 수행하는 1부터 511까지 숫자들을 차례대로 집어 넣으면서 RGB 값을 출력하고, 이를 텍스트 파일에 저장한다.
text.close() → 텍스트 파일 저장을 종료한다.

 

이렇게 코드를 짜고 실행하면 바로 anospec3.txt라는 파일이 생성되고, 41번째 행에 1~511까지의 픽셀에 대한 rgb가 모두 분석되어 저장되 있습니다.

 

이제 이 파일을 엑셀을 이용해 엽니다. 그럼 아래와 같은 화면이 나오는데요

여기서 너비가 일정함에 체크하고 다음

그 다음 화면에서도 바로 다음

마침을 누르면 숫자가 쭉 나옵니다.

여기서 우리에게 필요없는 문자인 [ ] 는 삭제해 줍니다. 모두 일일이 삭제하는건 무리수겠지요? ctrl + f 를 누루면 찾기가 되고, 여기서 [ 를 공백으로 바꾸기, ]도 공백으로 바꾸기를 하십니다. 

위 그림과 같이 ctrl + f 를 눌렀을 때 나오는 탭에서 바꾸기를 클릭, 찾을 내용에 [ 를 입력하고 바꿀내용에는 아무것도 입력하지 말고 다음 찾기를 클릭하면 [ 가 모두 지워집니다. 마찬가지로 다시 ctrl + f를 누르고 찾을 내용에 ]를, 바꿀 내용은 빈칸으로 하면 ]가 모두 지워집니다.

다음으로 맨 윗줄에 헤더 정보를 입력해 줍니다. 첫 번째 열은 R, 두 번째는 G, 세 번째는 B라고 입력해 줍니다.

이제 저장을 하시는데, 파일 형식을 csv(쉼표로 분리)로 저장하십니다.

 

그럼 이제 그래프를 그릴 준비가 다 되었습니다.

#그래프로 표현
import pandas as pd
import matplotlib.pyplot as plt
data=pd.read_csv('C:\\111\\anospec3.csv')
plt.figure(figsize=(15,2))
plt.plot(data['R'], c='r', label='R')
plt.plot(data['G'], c='g', label='G')
plt.plot(data['B'], c='b', label='B')
plt.legend()
plt.xlim(0,510)
plt.ylim(0,300)
plt.savefig('C:\\111\\anospecRGB.png')
plt.show()

그래프 그리는 코드는 아주 간단합니다. 궂이 설명을 달지 않아도 될 것 같아요. 이렇게 그래프를 그리면, 3개의 그래프가 나옵니다.

이 그래프를 아까전 스펙트럼과 같이 보면 

빨간색에서 보라색으로 갈 수록, R은 처음에는 일정하지만 G가 점진적으로 증가. G로 오면서 R은 감소하고 G가 최대를 찍은 뒤 점차 감소, 이후 R은 거의 0이 되고, B가 점차적으로 증가합니다. 보라색에 와서는 G는 거의 0이되고, R이 다시 소폭 증가합니다.

다소 애매한 부분은 B인데, 이건 예제로 사용한 연속 스펙트럼에서 B 값에 다소간에 오차가 있게 그려진게 원인인 것 같습니다.

 

지구과학 파이썬 내용으로 작성하긴 했지만, 사실 이 방법은 굉장히 많은 분야에서 사용할 수 있을 것 같습니다.

 

특히 중고등학생들 탐구대회 심사를 가 보면 탐구 결과를 색으로 제시하는 경우가 많은데 실험 결과가 빨간색이다 초록색이다 그래서 이러이러하다 하는 부분을 볼 때마다 다소 안타까웠습니다. 색깔을 우리말로 표현하는건 정량적이지 못할 뿐더러, 약간의 주관도 개입될 수 있습니다. 하지만 이런 방식으로 완전히 숫자로 표현해 버리면 정량적일 뿐더러 주관이 개입할 여지가 작아집니다.

 

여러 분야에서 활용가능한 부분이니 잘 보셔서 활용하시길 바랍니다.

 

다음번에도 재미있는 간단한 파이썬 코드를 소개해 올리겠습니다~~

 

반응형

댓글