일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 오픈AI
- ChatGPT
- 서보모터
- 일론 머스크
- 인공지능
- 딥마인드
- 가상환경
- 메타
- 아두이노
- 확산 모델
- ControlNet
- AI 기술
- 오블완
- 이미지 편집
- TRANSFORMER
- tts
- 멀티모달
- 딥러닝
- ubuntu
- 뉴럴링크
- AI
- 티스토리챌린지
- 우분투
- OpenAI
- LORA
- 트랜스포머
- 시간적 일관성
- PYTHON
- LLM
- 생성형 AI
- Today
- Total
AI 탐구노트
speck : 라인을 이용한 이미지 렌더링 도구 본문
speck은 이미지를 연속적인 선으로 렌더링하여 각 가로(또는 세로) 픽셀 라인을 표현하는 파이썬 기반의 라인 아트 이미지 렌더러입니다. 이번 글에서는 speck이 제공하는 기능과 이를 이용한 간단한 테스트를 진행해 보겠습니다.
1.주요 기능:
제공되는 주요 기능은 다음과 같은 것들이 있습니다.
- 선 두께 조절: 픽셀의 그레이스케일 값에 따라 선의 두께를 조절할 수 있습니다.
- 노이즈 프로필 추가: 랜덤성을 부여하기 위해 다양한 노이즈 프로필을 적용할 수 있습니다.
- 색상 프로필 추가: 선의 색상을 다양하게 표현하기 위해 색상 프로필을 적용할 수 있습니다.
- 인터랙티브 조정: ipywidget을 사용하여 출력 결과를 실시간으로 조정할 수 있습니다.
대략 아래와 같은 이미지를 생성할 수 있다고 생각하시면 됩니다.
2.테스트
2.1.설치 방법
설치는 아래의 명령어만으로 간단하게 진행됩니다.
pip install git+https://github.com/lucashadfield/speck.git
2.2.사용 방법
speck 객체 생성자에서 지원되는 옵션은 다음과 같습니다. 기본적으로 from_url, from_path 등의 메소드를 이용합니다.
옵션 | 설명 | 역할/기능 |
image | 입력 이미지의 URL 또는 PATH를 설정합니다. speck.SpeckPlot.from_url(), speck.SpeckPlot.from_path()를 이용합니다. |
라인 아트로 변환할 이미지를 지정합니다. |
upscale | 픽셀 스케일링 계수, 각 입력 픽셀은 업스케일 출력 픽셀에 매핑됩니다(기본값: 10) | |
horizontal | 수평선을 사용하여 이미지를 렌더링합니다(기본값: True) | 라인 아트에서 라인의 방향을 지정합니다. True 수평선, False 수직선 |
resize | 크기를 조정할 치수 또는 긴 모서리를 설정할 단일 값 및 입력 종횡비 유지(기본값: 없음) |
draw 메소드의 옵션 가운데 일부를 소개하면 다음과 같습니다. (대략 gradio 앱에 반영된 것으로 골랐습니다 ^^;)
옵션 | 설명 | 역할/기능 |
weights | 선 두께의 가중치를 설정합니다. (예: weights=(0.2, 0.6)) | 이미지의 그레이스케일 값에 따라 선의 두께를 비율로 조절합니다. |
noise | 노이즈 패턴을 설정합니다. (예: SineNoise(scale=0.7)) | 랜덤성을 부여하기 위해 선에 노이즈를 추가하며, 다양한 패턴을 제공합니다. |
colour | 선의 색상 프로필을 설정합니다. (예: CmapColour('Oranges')) | 선의 색상을 표현하며, Matplotlib의 컬러맵 또는 고유의 색상을 사용할 수 있습니다. |
background | 배경 색상을 설정합니다. 0~1 범위를 가지는 rgba list 형태로 입력을 받습니다. (예: [1,0,0,1]) | 출력 이미지의 배경색을 설정하여 라인 아트와 대비를 강조하거나 특정 스타일을 연출합니다. |
2.3.실행 예제 코드 (심플 버전)
speck를 이용하는 간단한 코드는 다음과 같습니다. 읽고 그리고 저장하고... 단 4줄... 간단하죠?
from speck import SpeckPlot, SineNoise, CmapColour
# 기본 설정
s = SpeckPlot.from_path(path='path_to_image.jpg', resize=100)
s.draw(weights=(0.3, 0.7), noise=SineNoise(scale=0.5), colour=CmapColour('Blues'), line_spacing=3, invert=True)
s.save(path='output_image.png')
2.4.테스트 데이터
테스트에 사용한 얼굴 이미지 데이터는 Unsplash에서 가져와 봤습니다. 아무래도 평범한 얼굴보다는 윤곽이 뚜렷한 쪽이 좋을 것 같아서 선택했는데 결과만 보면 어떤 얼굴을 이용해야 결과물이 좋게 나올 지 아직은 잘 모르겠습니다.
2.5.테스트 코드 (Gradio 버전)
앞서의 간단 코드에 웹 기반 gradio 코드를 입혀서 만들어 봤습니다.
import gradio as gr
from speck import SpeckPlot, SineNoise, CmapColour
from matplotlib.colors import to_rgba
# Parse the RGBA string
def rgba_to_hex(rgba):
rgba = rgba.replace("rgba(", "").replace(")", "")
r, g, b, a = map(float, rgba.split(","))
return [r/255, g/255, b/255, a]
def generate_line_art(image, resize, weights_min, weights_max, noise_scale, colour_map, line_direction, skip, background):
# Speck 인스턴스 생성
speck = SpeckPlot.from_path(
path=image,
resize=resize,
horizontal=(line_direction == '가로')
)
# 옵션 적용
weights = (weights_min, weights_max)
noise = SineNoise(scale=noise_scale)
colour = CmapColour(colour_map)
# 라인 아트 생성
speck.draw(
weights=weights,
noise=noise,
colour=colour,
skip=skip,
background=rgba_to_hex(background)
)
# 이미지 저장 및 반환
output_path = "output_image.png"
speck.save(path=output_path)
return output_path
# Gradio 인터페이스 구성
with gr.Blocks() as app:
with gr.Row():
gr.Markdown("## Speck 라인 아트 생성기")
with gr.Row():
with gr.Column():
input_image = gr.Image(label="입력 이미지", type="filepath")
with gr.Column():
output_image = gr.Image(label="결과 이미지")
with gr.Row():
resize = gr.Slider(50, 500, value=100, step=10, label="이미지 크기 조정 (resize)")
with gr.Row():
weights_min = gr.Slider(0.0, 1.0, value=0.2, step=0.1, label="선 두께 최소값 (weights_min)")
weights_max = gr.Slider(0.0, 1.0, value=0.6, step=0.1, label="선 두께 최대값 (weights_max)")
with gr.Row():
noise_scale = gr.Slider(0.0, 2.0, value=0.7, step=0.1, label="노이즈 크기 (noise_scale)")
with gr.Row():
colour_map = gr.Dropdown(choices=["Oranges", "Blues", "Greens", "Reds", "Purples"], value="Oranges", label="색상 맵 (colour_map)")
line_direction = gr.Radio(["가로", "세로"], value="가로", label="라인 방향 (line_direction)")
with gr.Row():
skip = gr.Slider(0, 10, value=0, step=1, label="라인 건너뛰기 간격 (skip)")
background = gr.ColorPicker(value="#FFFFFF", label="배경 색상 (background)")
with gr.Row():
generate_button = gr.Button("라인 아트 생성")
# Gradio 이벤트 연결
generate_button.click(
generate_line_art,
inputs=[input_image, resize, weights_min, weights_max, noise_scale, colour_map, line_direction, skip, background],
outputs=output_image
)
# Gradio 앱 실행
app.launch()
2.6.실행 화면
실행되면 아래와 같은 화면이 보이며, 조정 가능한 입력 인자는 다음과 같습니다.
- 이미지 크기 (resize)
- 선 두께 최소/최대값 (weights_min, weights_max)
- 노이즈 크기 (noise_scale)
- 색상 맵 (colour_map)
- 라인 방향 (line_direction)
- 라인 건너뛰기 간격 (skip)
- 배경 색상 (background)
2.7.테스트 결과
앞서 언급한 노인 이미지는 가로 방향으로 생성해 봤고, 추가로 체게바라 얼굴을 이용한 것은 세로 방향으로 생성해 봤습니다. 색상맵은 제가 좋아하는 것으로 고정해서 했는데 원하는대로 바꿔서 하시면 됩니다.
3.참고자료
- 코드 (Github)
- 데모 (Colab)
'DIY 테스트' 카테고리의 다른 글
체스(Chess) : 코딩으로 만나는 체스, 재미를 더하다 (3) | 2024.12.20 |
---|---|
마인드맵 : 생각 정리 및 아이디어 도출 도구 (1) | 2024.12.10 |
웹캠을 이용한 rPPG (원격 광혈류측정) 기반의 심박동수 측정 (2) | 2024.12.01 |
'픽셀 넘버' 게임 : 예능 속 퍼즐을 직접 만들어보자 (1) | 2024.11.25 |
머리(Head) 자세 기반의 화면 주시 여부 감지 (0) | 2024.11.22 |