상세 컨텐츠

본문 제목

[Python] 사진의 밝기에 따라 불투명도 조절, 휘도를 투명도로 변환하기

Programming/Python

by PrJun 2023. 2. 1. 19:42

본문

요즘 이미지 처리 관련한 재밌는 기능이 생각나서 이 기능을 넣은 사이트를 만들어보려 했는데 리액트 내에서 다 구현하는 건 무리일 듯해서 파이썬에서 이미지 처리를 진행하고 리액트로 처리된 이미지를 넘기는 방식으로 만들어보려고 했습니다. 제가 파이썬으로 할 일중 첫 번째가 사진의 밝기에 맞춰서 그 사진의 불투명도를 다르게 하는 작업입니다.

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

이미지 처리를 위해 pillow,
이미지 행렬 데이터 연산을 위해 numpy,
이미지를 jupyter notebook에 띄워주기 위해 matplotlib 모듈을 불러와줍니다.

resize_degree = 1

img = Image.open("testimg1.jpeg")

img = img.resize((int(img.size[0]*(resize_degree)), int(img.size[1]*(resize_degree))))

이미지를 불러와 줍니다.
필요에 따라 이미지를 리사이징 시켜줍니다.

# rgba data of origin img
imgData = img.convert("RGBA")

# put in numpy array
imgData_np = np.array(imgData)

우선 불투명도를 조절해야하기 때문에 우리는 RGBA 데이터가 필요합니다.
A는 알파값(Alpha)으로, 투명도를 지정하는 값입니다.
convert(“RGBA”)로 얻을 수 있습니다.
원본 이미지의 RGBA데이터, numpy array로 변환된 RGBA데이터를 변수에 저장해줍니다.

그리고 이미지 픽셀의 밝기를 얻기 위해 이미지를 그레이스케일로 변환해야합니다.
그레이스케일은 이미지의 밝기 정보만을 가지고 있는 데이터입니다.

위키백과

그레이스케일로 변환할때 이미지의 광량을 측정하는 공식이 있지만 저희는 잘 만들어진 모듈을 활용하기만 하면 됩니다.

# grayscaling
gray = img.convert("L")

# put in numpy array
gray_np = np.array(gray)

convert(“L”)로 얻을 수 있습니다.
원본 이미지가 그레이스케일로 변환된 데이터,
numpy array로 변환된 그레이스케일 데이터를 변수에 저장해줍니다.

allpixel_amount = gray.width * gray.height # number of pixels to process
print('가로 픽셀: ' + str(gray.width) + '\n세로 픽셀: ' + str(gray.height) 
      + '\n변형을 진행할 총 픽셀 수: ' + str(gray.width * gray.height))

plt.imshow(gray_np)

이미지의 총 픽셀 수와 불러온 이미지를 확인해봅시다.

4k 이미지라서 가로 4032개, 세로 3024개, 총 12192768개의 픽셀 수를 갖고 있습니다.

print(gray_np)

그레이스케일 이미지의 데이터 형태를 확인해봅시다.

2차원 배열로 사진의 밝기 데이터만 들어있음을 직접 확인할 수 있습니다.

# save brightness of pixels in numpy array
brightness_values = np.array(gray).flatten()

print("Brightness values: ", brightness_values)

그레이스케일 행렬 데이터를 일렬로 쫙 펼쳐서 다시 저장해줍니다.

1차원 배열이 되었습니다.

이제 이미지 처리 및 저장만 남았습니다.

from tqdm import tqdm # indicate progression degree module

이미지 처리의 진행도를 표시하기 위해 tqdm모듈을 불러와줍니다.

newData = imgData_np

pixel_pos = 0 # now pixel position (flatten index)

이미지를 처리하고 새롭게 데이터가 저장될 변수에 처리 전 원본 RGBA데이터를 넣어줍니다. 그리고 현재 몇 번째 픽셀을 처리 중인지 카운팅 하기 위해 pixel_pos 변수를 선언해 줍니다.

print('start.')

# img Alpha change and save
for i in tqdm(range(imgData_np.shape[0])):
    for j in range(imgData_np.shape[1]):
        #print(str(pixel_pos))
        newData[i, j, 3] = brightness_values[pixel_pos]
        pixel_pos = pixel_pos + 1 # count

이중 반복문을 통해서 이미지의 가로 픽셀, 세로 픽셀 전부 불투명도를 밝기 데이터에 맞춰 재설정해줍니다. 재설정 된 데이터의 타입은 numpy array입니다.

edited_img = Image.fromarray(newData, "RGBA")
edited_img = edited_img.rotate(270, expand=1)
print("end processing. \n\n")
print("[result]\n" + str(newData))

처리 된 이미지 데이터는 numpy array 타입이므로 RGBA데이터로 변환해준 뒤 270도로 회전시켜줍니다. 처리된 이미지가 원본과 달리 살짝 돌아가있기 때문에 회전해주는 과정이 필요합니다.
그리고 ‘expand=1’을 넣어서 회전을 할때 크롭없이 사진 그대로 회전되게 해줍니다. 저 인수를 넣지 않게 되면 가로 세로의 비율은 유지된 채 사진만 회전돼서 사진이 유지되지 않고 일부 짤리게 됩니다.

잘 처리된 것 같습니다.
첫 번째 픽셀의 알파 값이 108로, 그레이스케일 데이터의 첫번째 값과 일치함을 볼 수 있습니다.

# save edited img
edited_img.save('edited_img1.png', 'png')

print('saved.')

이제 처리 된 이미지를 저장해줍니다.

'Programming > Python' 카테고리의 다른 글

[Jupyter Notebook] 다크모드로 변경하는 법  (0) 2023.01.31
[Python] 데이터 csv파일 저장  (0) 2021.09.18

관련글 더보기

댓글 영역