SlideShare a Scribd company logo
1 of 41
Download to read offline
이미지 프로세싱
in Python Open Source
한성민 Gopher
Index
• Image Processing
• Open Source
• Contribution
Image Processing
좌측에 고양이 이미지가 있습니다.
이미지 프로세싱이란
이 이미지는 RGB 형식이고
컴퓨터는 이것을 바이트 단위로
매트릭스(Matrix)라고 부르는
배열 형태로 저장합니다.
이미지 프로세싱이란
(166, 219, 216)
(176, 176, 152)
(150, 140, 111)
(147, 131, 112)
(135, 173, 159)
(199, 160, 127)
(199, 172, 155)
(209, 198, 189)
(131, 141, 115)
(180, 142, 108)
(173, 153, 150)
(204, 189, 176)
(95, 144, 134)
(125, 127, 107)
(154, 142, 132)
(187, 169, 154)
이미지 프로세싱이란
우리는 다양한 수식을 이용하여 이미지를 변환(Transformation)할 수 있고
이것을 이미지 프로세싱(Image Processing)이라 부릅니다.
𝟏
𝟏
𝟏
𝟎
𝟎𝟎
𝟎 𝟎
𝟎 𝟏
𝟏
𝟏
𝑿
𝒀𝟎
𝟎 𝟎
𝟎 𝑾
𝑯
𝟏
𝟎
𝟎𝟎
𝟎 𝟎
𝟎
Original Translate Scale
𝒄𝒐𝒔𝜽
𝟏
𝟎
𝟎
𝟎 𝟎
𝒄𝒐𝒔𝜽
𝒔𝒊𝒏𝜽
−𝒔𝒊𝒏𝜽
Rotate
동영상 처리
이미지 프로세싱이란
이미지 프로세싱은 다양한 종류가 있으며
사진, 그림, 동영상에 따라서 이미지 프로세싱이 여러 갈래로 나눠집니다.
Image Processing
사진, 그림 처리
기하학적 변환 색조화, 양자화, 색변환 패턴 인식, 특징 검출 압축 노이즈 제거 영상 분할, 접합
이미지 프로세싱이란
오늘은 그 중에서 사진, 그림과 같은 2차원 데이터의
기하학적 변환에 대해서 얘기하고자 합니다.
기하학적 변환
기하학적 변환 연산
기하학적 변환이란 이미지의 크기나 위치 변경, 혹은 회전 등의 변화를 가하는 것으로
어파인(Affine) 변환 혹은 원근(Perspective) 변환 등이 있습니다.
이동
(Translate)
회전
(Rotate)
from PIL import Image
img = Image.open('./cat.jpg')
x = 100
y = 50
a = 1
b = 0
c = -x # move the img 100 to the right
d = 0
e = 1
f = y # move the img 50 to the up
translate = img.transform(img.size, Image.AFFINE, (a, b, c, d, e, f))
translate.show()
Pillow Affine Translate
𝟏
𝟏
𝟏
𝑿
𝒀𝟎
𝟎 𝟎
𝟎
Translate
from PIL import Image
import math
img = Image.open('./cat.jpg')
angle = math.radians(45) # 45 degree
a = math.cos(angle)
b = math.sin(angle)
c = 0
d = -math.sin(angle)
e = math.cos(angle)
f = 0
rotate = img.transform(img.size, Image.AFFINE, (a, b, c, d, e, f), resample=Image.BILINEAR)
rotate.show()
𝒄𝒐𝒔𝜽
𝟏
𝟎
𝟎
𝟎 𝟎
𝒄𝒐𝒔𝜽
𝒔𝒊𝒏𝜽
−𝒔𝒊𝒏𝜽
Rotate
Pillow Affine Rotate
def _create_coeff(
xyA1, xyA2, xyA3, xyA4,
xyB1, xyB2, xyB3, xyB4):
A = np.array([
[xyA1[0], xyA1[1], 1, 0, 0, 0, -xyB1[0] * xyA1[0], -xyB1[0] * xyA1[1]],
[0, 0, 0, xyA1[0], xyA1[1], 1, -xyB1[1] * xyA1[0], -xyB1[1] * xyA1[1]],
[xyA2[0], xyA2[1], 1, 0, 0, 0, -xyB2[0] * xyA2[0], -xyB2[0] * xyA2[1]],
[0, 0, 0, xyA2[0], xyA2[1], 1, -xyB2[1] * xyA2[0], -xyB2[1] * xyA2[1]],
[xyA3[0], xyA3[1], 1, 0, 0, 0, -xyB3[0] * xyA3[0], -xyB3[0] * xyA3[1]],
[0, 0, 0, xyA3[0], xyA3[1], 1, -xyB3[1] * xyA3[0], -xyB3[1] * xyA3[1]],
[xyA4[0], xyA4[1], 1, 0, 0, 0, -xyB4[0] * xyA4[0], -xyB4[0] * xyA4[1]],
[0, 0, 0, xyA4[0], xyA4[1], 1, -xyB4[1] * xyA4[0], -xyB4[1] * xyA4[1]],
], dtype=np.float32)
B = np.array([xyB1[0], xyB1[1], xyB2[0], xyB2[1], xyB3[0], xyB3[1], xyB4[0], xyB4[1]], dtype=np.float32)
return linalg.solve(A, B)
img = Image.open('./cat.jpg')
coeff = _create_coeff(
(0, 0), (img.width, 0),
(img.width, img.height), (0, img.height),
(-200, 0), (img.width + 200, 0),
(img.width, img.height), (0, img.height),
)
perspective = img.transform(img.size, Image.PERSPECTIVE, coeff, resample=Image.BILINEAR)
perspective.show()
Pillow Affine Perspective
색상 혼합(Blend)
어파인과 원근 변환 외에도 색상 혼합과 같은 방법을 이미지에 적용할 수 도 있습니다.
대표적으로 두 이미지의 색상을 혼합하는 블랜딩(Blending)이 있습니다.
Example Pillow
from PIL import Image
im1 = Image.open('./cat.jpg')
im2 = Image.open('./dog.jpg')
im3 = Image.blend(im1, im2, 0.5)
im3.show()
Im1, im2 블랜딩
대부분의 이미지 라이브러리는 블랜딩을 지원합니다.
Output
그렇다면, 이미지 라이브러리는
어떤 원리로 동작할까요?
Open Source
코드 설계
+
+
+
+
+
로드 호출 C 바인드 변환
CPU 매트릭스 연산
파이썬에서 이미지 처리는 대부분 그림과 같이 동작합니다.
파이썬 이미지 라이브러리 구조
Python Interface
Python Bind
C lang Compiled Libs
이미지 프로세스는 대부분 컴퓨터 성능을 많이 요구하기 때문에,
C 언어로 작성하고 파이썬에 바인딩하여 사용합니다.
파이썬 바인딩
파이썬은 C 바인딩을 통해 C에서 작성된 함수를 실행 가능하며,
이를 통해 복잡한 연산을 빠르게 실행할 수 있습니다.
process.py
binding.c호출
libImage.c
libImage.h
연산 방식
def blend(im1, im2, alpha):
im1.load()
im2.load()
return im1._new(core.blend(im1.im, im2.im, alpha))
cat.jpg
dog.jpg
src/Image.py
Imaging
ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha)
{
Imaging imOut;
int x, y;
...
if (alpha >= 0 && alpha <= 1.0) {
/* Interpolate between bands */
for (y = 0; y < imIn1->ysize; y++) {
UINT8* in1 = (UINT8*) imIn1->image[y];
...
for (x = 0; x < imIn1->linesize; x++) {
out[x] = (UINT8)
((int) in1[x] + alpha * ((int) in2[x] - (int) in1[x]));
}
}
} else {
/* Extrapolation; must make sure to clip resulting values */
for (y = 0; y < imIn1->ysize; y++) {
UINT8* in1 = (UINT8*) imIn1->image[y];
...
for (x = 0; x < imIn1->linesize; x++) {
...
}
}
}
return imOut;
}src/libImaging/Blend.c
파이썬에서 C로 작성된 함수 호출
Python C Bind
try:
from . import _imaging as core
if __version__ != getattr(core, "PILLOW_VERSION", None):
raise ImportError(
...
)
except ImportError as v:
...
raise
static PyObject*
_blend(ImagingObject* self, PyObject* args)
{
ImagingObject* imagep1;
ImagingObject* imagep2;
double alpha;
alpha = 0.5;
if (!PyArg_ParseTuple(args, "O!O!|d",
&Imaging_Type, &imagep1,
&Imaging_Type, &imagep2,
&alpha)) {
return NULL;
}
return PyImagingNew(ImagingBlend(imagep1->image, imagep2->image,
(float) alpha));
}
src/Image.py
src/_imaging.c
예를 들어,
Pillow는 core를 통해 C 함수를 호출합니다.
Python C Bind
#
# core library
files = ["src/_imaging.c"]
for src_file in _IMAGING:
files.append("src/" + src_file + ".c")
for src_file in _LIB_IMAGING:
files.append(os.path.join("src/libImaging", src_file + ".c"))
libs = self.add_imaging_libs.split()
defs = []
if feature.jpeg:
libs.append(feature.jpeg)
defs.append(("HAVE_LIBJPEG", None))
...
if (sys.platform == "win32“ and ...):
defs.append(("PILLOW_VERSION", '""%s""' % PILLOW_VERSION))
...
exts = [(Extension("PIL._imaging", files, libraries=libs, define_macros=defs))]
setup.py
Python C Bind
#
# core library
files = ["src/_imaging.c"]
for src_file in _IMAGING:
files.append("src/" + src_file + ".c")
for src_file in _LIB_IMAGING:
files.append(os.path.join("src/libImaging", src_file + ".c"))
libs = self.add_imaging_libs.split()
defs = []
if feature.jpeg:
libs.append(feature.jpeg)
defs.append(("HAVE_LIBJPEG", None))
...
if (sys.platform == "win32“ and ...):
defs.append(("PILLOW_VERSION", '""%s""' % PILLOW_VERSION))
...
exts = [(Extension("PIL._imaging", files, libraries=libs, define_macros=defs))]
C 라이브러리 바인드
setup.py
Python C Bind
#
# additional libraries
...
tk_libs = ["psapi"] if sys.platform == "win32" else []
exts.append(
Extension(
"PIL._imagingtk",
["src/_imagingtk.c", "src/Tk/tkImaging.c"],
include_dirs=["src/Tk"],
libraries=tk_libs,
)
)
exts.append(Extension("PIL._imagingmath", ["src/_imagingmath.c"]))
exts.append(Extension("PIL._imagingmorph", ["src/_imagingmorph.c"]))
self.extensions[:] = exts
build_ext.build_extensions(self)
setup.py
Python C Bind
#
# additional libraries
...
tk_libs = ["psapi"] if sys.platform == "win32" else []
exts.append(
Extension(
"PIL._imagingtk",
["src/_imagingtk.c", "src/Tk/tkImaging.c"],
include_dirs=["src/Tk"],
libraries=tk_libs,
)
)
exts.append(Extension("PIL._imagingmath", ["src/_imagingmath.c"]))
exts.append(Extension("PIL._imagingmorph", ["src/_imagingmorph.c"]))
self.extensions[:] = exts
build_ext.build_extensions(self)
setup.py
의존 라이브러리 빌드
Pillow Structure
FreeType LibImaging Libjpeg
libraqm harfbuzz libimagequant
Pillow Structure
FreeType LibImaging Libjpeg
libraqm harfbuzz libimagequant
폰트 랜더링 이미지 처리 JPG 연산
텍스트 레이아웃 계산 폰트 글리프 랜더링 RGBA / 팔레트 변환
ImageMagick
개발사
출시일
언어
라이센스
ImageMagick Studio LLC
1990년 8월 1일
C 언어
ImageMagick License
Wand
from wand.image import Image
from wand.display import display
with Image(filename='cat.jpg') as img:
print(img.size)
for r in 1, 2, 3:
with img.clone() as i:
i.resize(int(i.width * r * 0.25), int(i.height * r * 0.25))
i.rotate(90 * r)
i.save(filename='cat-{0}.jpg'.format(r))
display(i)
파이썬 라이브러리 Wand를 통해 ImageMagick을 사용할 수 있습니다.
Trending
2009년 하반기 이후로 OpenCV가 유행 추세
OpenCV는 컴퓨터 비전 및 물체 인식 등 다양한 기능을 추가로 제공
Contribution
Workflow
PR (Pull Request)
Jenkins pr-head trigger
Lint error
Blocking merge
Fix commit
Jenkins pr-head trigger
Pass
Request changes
Fix commit
Blocking merge
Jenkins pr-head trigger
Pass
Approve
Merge
Merge Opened
포럼을 통한 버그 제보
포럼을 통한 버그 제보
ImageMagick 버그
포토샵, MS 워드 등 다른 프로그램 동작
ImageMagick PR
ImageMagick PR
밑줄 어파인 연산의 조정으로 위치 개선
폰트 색상과 동일한 밑줄 색상 적용
ImageMagick PR
annotate_info->affine.tx=offset.x;
annotate_info->affine.ty=offset.y;
pixel=annotate_info->fill;
if (annotate_info->stroke.alpha != TransparentAlpha) pixel = annotate_info->stroke;
(void) QueryColorname(image,&pixel,AllCompliance,color,exception);
(void) FormatLocaleString(primitive,MagickPathExtent,"stroke %s "
"stroke-width %g " "line 0,0 %g,0",color,(double) metrics.underline_thickness,(double) metrics.width);
...
annotate_info=DestroyDrawInfo(annotate_info);
annotate=DestroyDrawInfo(annotate);
textlist=(char **) RelinquishMagickMemory(textlist);
text=DestroyString(text);
return(status);
글자와 동일한 밑줄 색상 처리
MagickCore/annotate.c
FT_Face face;
...
metrics->bounds.y1=metrics->descent;
metrics->bounds.x2=metrics->ascent+metrics->descent;
metrics->bounds.x1=0.0;
metrics->bounds.y1=metrics->descent;
metrics->bounds.x2=metrics->ascent+metrics->descent;
metrics->bounds.y2=metrics->ascent+metrics->descent;
metrics->underline_position=face->underline_position*(metrics->pixels_per_em.x/face->units_per_EM);
metrics->underline_thickness=face->underline_thickness*(metrics->pixels_per_em.x/face->units_per_EM);
...
ImageMagick PR
MagickCore/annotate.c
FreeType으로 부터 밑줄 크기, 위치 계산
convert -size 320x120 xc:lightblue 
-draw "fill tomato circle 250,30 310,30 
fill limegreen circle 55,75 15,80 
font Candice font-size 72 decorate UnderLine 
fill dodgerblue stroke navy stroke-width 2 
translate 10,110 rotate -15 text 0,0 ' Anthony '" 
draw_mvg.gif
Test with ImageMagick
ImageMagick 명령어로 동작 확인
Test with Python Wand
파이썬 Wand에서 테스트
from wand.color import Color
from wand.drawing import Drawing
from wand.image import Image
with Image(width=320, height=100, background=Color('lightblue')) as image:
with Drawing() as draw:
draw.font = 'Candice'
draw.font_size = 72.0
draw.text_decoration = 'underline'
draw.fill_color = Color('black')
draw.text(28, 68, 'Anthony')
draw(image)
image.save(filename='test.jpg')
Thank you!

More Related Content

What's hot

백엔드 서버 개발과 코틀린의 조합
백엔드 서버 개발과 코틀린의 조합백엔드 서버 개발과 코틀린의 조합
백엔드 서버 개발과 코틀린의 조합Daeseok Kim
 
새해 일어난 일
새해 일어난 일새해 일어난 일
새해 일어난 일Eunhyang Kim
 
Game Physics Engine Development (게임 물리 엔진 개발)
Game Physics Engine Development (게임 물리 엔진 개발)Game Physics Engine Development (게임 물리 엔진 개발)
Game Physics Engine Development (게임 물리 엔진 개발)Bongseok Cho
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심흥배 최
 
Wasserstein GAN 수학 이해하기 I
Wasserstein GAN 수학 이해하기 IWasserstein GAN 수학 이해하기 I
Wasserstein GAN 수학 이해하기 ISungbin Lim
 
송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010devCAT Studio, NEXON
 
MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현YEONG-CHEON YOU
 
Robot framework 을 이용한 기능 테스트 자동화
Robot framework 을 이용한 기능 테스트 자동화Robot framework 을 이용한 기능 테스트 자동화
Robot framework 을 이용한 기능 테스트 자동화Jaehoon Oh
 
예외처리가이드
예외처리가이드예외처리가이드
예외처리가이드도형 임
 
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012Esun Kim
 
[C++ Korea 2nd Seminar] Ranges for The Cpp Standard Library
[C++ Korea 2nd Seminar] Ranges for The Cpp Standard Library[C++ Korea 2nd Seminar] Ranges for The Cpp Standard Library
[C++ Korea 2nd Seminar] Ranges for The Cpp Standard LibraryDongMin Choi
 
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012devCAT Studio, NEXON
 
카카오톡으로 여친 만들기 2013.06.29
카카오톡으로 여친 만들기 2013.06.29카카오톡으로 여친 만들기 2013.06.29
카카오톡으로 여친 만들기 2013.06.29Taehoon Kim
 
서비스중인 게임 DB 설계 (쿠키런 편)
서비스중인 게임 DB 설계 (쿠키런 편)서비스중인 게임 DB 설계 (쿠키런 편)
서비스중인 게임 DB 설계 (쿠키런 편)_ce
 
[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규ChangKyu Song
 
유니티 + Nodejs를 활용한 멀티플레이어 게임 개발하기
유니티 + Nodejs를 활용한 멀티플레이어 게임 개발하기유니티 + Nodejs를 활용한 멀티플레이어 게임 개발하기
유니티 + Nodejs를 활용한 멀티플레이어 게임 개발하기Kiyoung Moon
 
Little Big Data #1. 바닥부터 시작하는 데이터 인프라
Little Big Data #1. 바닥부터 시작하는 데이터 인프라Little Big Data #1. 바닥부터 시작하는 데이터 인프라
Little Big Data #1. 바닥부터 시작하는 데이터 인프라Seongyun Byeon
 
LockFree Algorithm
LockFree AlgorithmLockFree Algorithm
LockFree AlgorithmMerry Merry
 
Software engineer가 되기 위한 여정
Software engineer가 되기 위한 여정Software engineer가 되기 위한 여정
Software engineer가 되기 위한 여정Aree Oh
 
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기강 민우
 

What's hot (20)

백엔드 서버 개발과 코틀린의 조합
백엔드 서버 개발과 코틀린의 조합백엔드 서버 개발과 코틀린의 조합
백엔드 서버 개발과 코틀린의 조합
 
새해 일어난 일
새해 일어난 일새해 일어난 일
새해 일어난 일
 
Game Physics Engine Development (게임 물리 엔진 개발)
Game Physics Engine Development (게임 물리 엔진 개발)Game Physics Engine Development (게임 물리 엔진 개발)
Game Physics Engine Development (게임 물리 엔진 개발)
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심
 
Wasserstein GAN 수학 이해하기 I
Wasserstein GAN 수학 이해하기 IWasserstein GAN 수학 이해하기 I
Wasserstein GAN 수학 이해하기 I
 
송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010
 
MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현
 
Robot framework 을 이용한 기능 테스트 자동화
Robot framework 을 이용한 기능 테스트 자동화Robot framework 을 이용한 기능 테스트 자동화
Robot framework 을 이용한 기능 테스트 자동화
 
예외처리가이드
예외처리가이드예외처리가이드
예외처리가이드
 
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012
 
[C++ Korea 2nd Seminar] Ranges for The Cpp Standard Library
[C++ Korea 2nd Seminar] Ranges for The Cpp Standard Library[C++ Korea 2nd Seminar] Ranges for The Cpp Standard Library
[C++ Korea 2nd Seminar] Ranges for The Cpp Standard Library
 
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
 
카카오톡으로 여친 만들기 2013.06.29
카카오톡으로 여친 만들기 2013.06.29카카오톡으로 여친 만들기 2013.06.29
카카오톡으로 여친 만들기 2013.06.29
 
서비스중인 게임 DB 설계 (쿠키런 편)
서비스중인 게임 DB 설계 (쿠키런 편)서비스중인 게임 DB 설계 (쿠키런 편)
서비스중인 게임 DB 설계 (쿠키런 편)
 
[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규
 
유니티 + Nodejs를 활용한 멀티플레이어 게임 개발하기
유니티 + Nodejs를 활용한 멀티플레이어 게임 개발하기유니티 + Nodejs를 활용한 멀티플레이어 게임 개발하기
유니티 + Nodejs를 활용한 멀티플레이어 게임 개발하기
 
Little Big Data #1. 바닥부터 시작하는 데이터 인프라
Little Big Data #1. 바닥부터 시작하는 데이터 인프라Little Big Data #1. 바닥부터 시작하는 데이터 인프라
Little Big Data #1. 바닥부터 시작하는 데이터 인프라
 
LockFree Algorithm
LockFree AlgorithmLockFree Algorithm
LockFree Algorithm
 
Software engineer가 되기 위한 여정
Software engineer가 되기 위한 여정Software engineer가 되기 위한 여정
Software engineer가 되기 위한 여정
 
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
 

Similar to 이미지 프로세싱 in Python Open Source - PYCON KOREA 2020

[NDC14] 라이브중인 2D게임에 시스템 변경 없이 본 애니메이션 도입하기[던전앤파이터]
[NDC14] 라이브중인 2D게임에 시스템 변경 없이 본 애니메이션 도입하기[던전앤파이터][NDC14] 라이브중인 2D게임에 시스템 변경 없이 본 애니메이션 도입하기[던전앤파이터]
[NDC14] 라이브중인 2D게임에 시스템 변경 없이 본 애니메이션 도입하기[던전앤파이터]SeungWon Lee
 
영상 데이터의 처리와 정보의 추출
영상 데이터의 처리와 정보의 추출영상 데이터의 처리와 정보의 추출
영상 데이터의 처리와 정보의 추출동윤 이
 
투명화 처리로 살펴 본 한층 고급화된 모바일 UX
투명화 처리로 살펴 본 한층 고급화된 모바일 UX투명화 처리로 살펴 본 한층 고급화된 모바일 UX
투명화 처리로 살펴 본 한층 고급화된 모바일 UXDae Yeon Jin
 
효율적인 2D 게임 개발을 위한 2d skeletal 구조에 관한 연구 - Spine을 중심으로
효율적인 2D 게임 개발을 위한 2d skeletal 구조에 관한 연구 - Spine을 중심으로효율적인 2D 게임 개발을 위한 2d skeletal 구조에 관한 연구 - Spine을 중심으로
효율적인 2D 게임 개발을 위한 2d skeletal 구조에 관한 연구 - Spine을 중심으로Hyunwoo Kim
 
c++ opencv tutorial
c++ opencv tutorialc++ opencv tutorial
c++ opencv tutorialTaeKang Woo
 
Python 활용: 이미지 처리와 데이터 분석
Python 활용: 이미지 처리와 데이터 분석Python 활용: 이미지 처리와 데이터 분석
Python 활용: 이미지 처리와 데이터 분석용 최
 
Project#5 최단거리 찾기 D0 Hwp
Project#5 최단거리 찾기 D0 HwpProject#5 최단거리 찾기 D0 Hwp
Project#5 최단거리 찾기 D0 HwpKimjeongmoo
 
자료구조5보고서
자료구조5보고서자료구조5보고서
자료구조5보고서KimChangHoen
 
딥 러닝 자연어 처리 학습을 위한 PPT! (Deep Learning for Natural Language Processing)
딥 러닝 자연어 처리 학습을 위한 PPT! (Deep Learning for Natural Language Processing)딥 러닝 자연어 처리 학습을 위한 PPT! (Deep Learning for Natural Language Processing)
딥 러닝 자연어 처리 학습을 위한 PPT! (Deep Learning for Natural Language Processing)WON JOON YOO
 
파이썬 데이터과학 레벨2 - 데이터 시각화와 실전 데이터분석, 그리고 머신러닝 입문 (2020년 이태영)
파이썬 데이터과학 레벨2 - 데이터 시각화와 실전 데이터분석, 그리고 머신러닝 입문 (2020년 이태영)파이썬 데이터과학 레벨2 - 데이터 시각화와 실전 데이터분석, 그리고 머신러닝 입문 (2020년 이태영)
파이썬 데이터과학 레벨2 - 데이터 시각화와 실전 데이터분석, 그리고 머신러닝 입문 (2020년 이태영)Tae Young Lee
 
딥 러닝 자연어 처리를 학습을 위한 파워포인트. (Deep Learning for Natural Language Processing)
딥 러닝 자연어 처리를 학습을 위한 파워포인트. (Deep Learning for Natural Language Processing)딥 러닝 자연어 처리를 학습을 위한 파워포인트. (Deep Learning for Natural Language Processing)
딥 러닝 자연어 처리를 학습을 위한 파워포인트. (Deep Learning for Natural Language Processing)WON JOON YOO
 
Python programming for Bioinformatics
Python programming for BioinformaticsPython programming for Bioinformatics
Python programming for BioinformaticsHyungyong Kim
 
Standardization of item_data_by_ai_decryption
Standardization of item_data_by_ai_decryptionStandardization of item_data_by_ai_decryption
Standardization of item_data_by_ai_decryptionJihyunSong13
 
Canvas_basic tutorial
Canvas_basic tutorialCanvas_basic tutorial
Canvas_basic tutorialfairesy
 
R 스터디 첫번째
R 스터디 첫번째R 스터디 첫번째
R 스터디 첫번째Jaeseok Park
 
Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀beom kyun choi
 
이미지프로세싱
이미지프로세싱이미지프로세싱
이미지프로세싱일규 최
 
3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택JinTaek Seo
 

Similar to 이미지 프로세싱 in Python Open Source - PYCON KOREA 2020 (20)

[NDC14] 라이브중인 2D게임에 시스템 변경 없이 본 애니메이션 도입하기[던전앤파이터]
[NDC14] 라이브중인 2D게임에 시스템 변경 없이 본 애니메이션 도입하기[던전앤파이터][NDC14] 라이브중인 2D게임에 시스템 변경 없이 본 애니메이션 도입하기[던전앤파이터]
[NDC14] 라이브중인 2D게임에 시스템 변경 없이 본 애니메이션 도입하기[던전앤파이터]
 
영상 데이터의 처리와 정보의 추출
영상 데이터의 처리와 정보의 추출영상 데이터의 처리와 정보의 추출
영상 데이터의 처리와 정보의 추출
 
IPython
IPythonIPython
IPython
 
투명화 처리로 살펴 본 한층 고급화된 모바일 UX
투명화 처리로 살펴 본 한층 고급화된 모바일 UX투명화 처리로 살펴 본 한층 고급화된 모바일 UX
투명화 처리로 살펴 본 한층 고급화된 모바일 UX
 
효율적인 2D 게임 개발을 위한 2d skeletal 구조에 관한 연구 - Spine을 중심으로
효율적인 2D 게임 개발을 위한 2d skeletal 구조에 관한 연구 - Spine을 중심으로효율적인 2D 게임 개발을 위한 2d skeletal 구조에 관한 연구 - Spine을 중심으로
효율적인 2D 게임 개발을 위한 2d skeletal 구조에 관한 연구 - Spine을 중심으로
 
c++ opencv tutorial
c++ opencv tutorialc++ opencv tutorial
c++ opencv tutorial
 
Python 활용: 이미지 처리와 데이터 분석
Python 활용: 이미지 처리와 데이터 분석Python 활용: 이미지 처리와 데이터 분석
Python 활용: 이미지 처리와 데이터 분석
 
Project#5 최단거리 찾기 D0 Hwp
Project#5 최단거리 찾기 D0 HwpProject#5 최단거리 찾기 D0 Hwp
Project#5 최단거리 찾기 D0 Hwp
 
자료구조5보고서
자료구조5보고서자료구조5보고서
자료구조5보고서
 
딥 러닝 자연어 처리 학습을 위한 PPT! (Deep Learning for Natural Language Processing)
딥 러닝 자연어 처리 학습을 위한 PPT! (Deep Learning for Natural Language Processing)딥 러닝 자연어 처리 학습을 위한 PPT! (Deep Learning for Natural Language Processing)
딥 러닝 자연어 처리 학습을 위한 PPT! (Deep Learning for Natural Language Processing)
 
파이썬 데이터과학 레벨2 - 데이터 시각화와 실전 데이터분석, 그리고 머신러닝 입문 (2020년 이태영)
파이썬 데이터과학 레벨2 - 데이터 시각화와 실전 데이터분석, 그리고 머신러닝 입문 (2020년 이태영)파이썬 데이터과학 레벨2 - 데이터 시각화와 실전 데이터분석, 그리고 머신러닝 입문 (2020년 이태영)
파이썬 데이터과학 레벨2 - 데이터 시각화와 실전 데이터분석, 그리고 머신러닝 입문 (2020년 이태영)
 
딥 러닝 자연어 처리를 학습을 위한 파워포인트. (Deep Learning for Natural Language Processing)
딥 러닝 자연어 처리를 학습을 위한 파워포인트. (Deep Learning for Natural Language Processing)딥 러닝 자연어 처리를 학습을 위한 파워포인트. (Deep Learning for Natural Language Processing)
딥 러닝 자연어 처리를 학습을 위한 파워포인트. (Deep Learning for Natural Language Processing)
 
Python programming for Bioinformatics
Python programming for BioinformaticsPython programming for Bioinformatics
Python programming for Bioinformatics
 
[Week4]canvas
[Week4]canvas[Week4]canvas
[Week4]canvas
 
Standardization of item_data_by_ai_decryption
Standardization of item_data_by_ai_decryptionStandardization of item_data_by_ai_decryption
Standardization of item_data_by_ai_decryption
 
Canvas_basic tutorial
Canvas_basic tutorialCanvas_basic tutorial
Canvas_basic tutorial
 
R 스터디 첫번째
R 스터디 첫번째R 스터디 첫번째
R 스터디 첫번째
 
Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀
 
이미지프로세싱
이미지프로세싱이미지프로세싱
이미지프로세싱
 
3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택
 

More from Kenneth Ceyer

정적 컨텐츠 제너레이터 GatsbyJS에 대해서 알아봅시다.
정적 컨텐츠 제너레이터 GatsbyJS에 대해서 알아봅시다.정적 컨텐츠 제너레이터 GatsbyJS에 대해서 알아봅시다.
정적 컨텐츠 제너레이터 GatsbyJS에 대해서 알아봅시다.Kenneth Ceyer
 
LP(linear programming) Algorithm
LP(linear programming) AlgorithmLP(linear programming) Algorithm
LP(linear programming) AlgorithmKenneth Ceyer
 
하둡 에코시스템 위에서 환상적인 테이크오프 - DSTS 2019
하둡 에코시스템 위에서 환상적인 테이크오프 - DSTS 2019 하둡 에코시스템 위에서 환상적인 테이크오프 - DSTS 2019
하둡 에코시스템 위에서 환상적인 테이크오프 - DSTS 2019 Kenneth Ceyer
 
AllReduce for distributed learning I/O Extended Seoul
AllReduce for distributed learning I/O Extended SeoulAllReduce for distributed learning I/O Extended Seoul
AllReduce for distributed learning I/O Extended SeoulKenneth Ceyer
 
gRPC와 goroutine 톺아보기 - GDG Golang Korea 2019
gRPC와 goroutine 톺아보기 - GDG Golang Korea 2019gRPC와 goroutine 톺아보기 - GDG Golang Korea 2019
gRPC와 goroutine 톺아보기 - GDG Golang Korea 2019Kenneth Ceyer
 
Test and refactoring
Test and refactoringTest and refactoring
Test and refactoringKenneth Ceyer
 
Deep dive into Modern frameworks - HTML5 Forum 2018
Deep dive into Modern frameworks - HTML5 Forum 2018Deep dive into Modern frameworks - HTML5 Forum 2018
Deep dive into Modern frameworks - HTML5 Forum 2018Kenneth Ceyer
 
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018Kenneth Ceyer
 
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
 GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기 GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기Kenneth Ceyer
 
엔지니어 관점에서 바라본 데이터시각화
엔지니어 관점에서 바라본 데이터시각화엔지니어 관점에서 바라본 데이터시각화
엔지니어 관점에서 바라본 데이터시각화Kenneth Ceyer
 
Dealing with Python Reactively - PyCon Korea 2017
Dealing with Python Reactively - PyCon Korea 2017Dealing with Python Reactively - PyCon Korea 2017
Dealing with Python Reactively - PyCon Korea 2017Kenneth Ceyer
 
파이썬 리액티브하게 짜기 - PyCon Korea 2017
파이썬 리액티브하게 짜기 - PyCon Korea 2017파이썬 리액티브하게 짜기 - PyCon Korea 2017
파이썬 리액티브하게 짜기 - PyCon Korea 2017Kenneth Ceyer
 
AngularJS 2, version 1 and ReactJS
AngularJS 2, version 1 and ReactJSAngularJS 2, version 1 and ReactJS
AngularJS 2, version 1 and ReactJSKenneth Ceyer
 

More from Kenneth Ceyer (14)

정적 컨텐츠 제너레이터 GatsbyJS에 대해서 알아봅시다.
정적 컨텐츠 제너레이터 GatsbyJS에 대해서 알아봅시다.정적 컨텐츠 제너레이터 GatsbyJS에 대해서 알아봅시다.
정적 컨텐츠 제너레이터 GatsbyJS에 대해서 알아봅시다.
 
LP(linear programming) Algorithm
LP(linear programming) AlgorithmLP(linear programming) Algorithm
LP(linear programming) Algorithm
 
하둡 에코시스템 위에서 환상적인 테이크오프 - DSTS 2019
하둡 에코시스템 위에서 환상적인 테이크오프 - DSTS 2019 하둡 에코시스템 위에서 환상적인 테이크오프 - DSTS 2019
하둡 에코시스템 위에서 환상적인 테이크오프 - DSTS 2019
 
AllReduce for distributed learning I/O Extended Seoul
AllReduce for distributed learning I/O Extended SeoulAllReduce for distributed learning I/O Extended Seoul
AllReduce for distributed learning I/O Extended Seoul
 
gRPC와 goroutine 톺아보기 - GDG Golang Korea 2019
gRPC와 goroutine 톺아보기 - GDG Golang Korea 2019gRPC와 goroutine 톺아보기 - GDG Golang Korea 2019
gRPC와 goroutine 톺아보기 - GDG Golang Korea 2019
 
How to use vim
How to use vimHow to use vim
How to use vim
 
Test and refactoring
Test and refactoringTest and refactoring
Test and refactoring
 
Deep dive into Modern frameworks - HTML5 Forum 2018
Deep dive into Modern frameworks - HTML5 Forum 2018Deep dive into Modern frameworks - HTML5 Forum 2018
Deep dive into Modern frameworks - HTML5 Forum 2018
 
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
 
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
 GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기 GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
 
엔지니어 관점에서 바라본 데이터시각화
엔지니어 관점에서 바라본 데이터시각화엔지니어 관점에서 바라본 데이터시각화
엔지니어 관점에서 바라본 데이터시각화
 
Dealing with Python Reactively - PyCon Korea 2017
Dealing with Python Reactively - PyCon Korea 2017Dealing with Python Reactively - PyCon Korea 2017
Dealing with Python Reactively - PyCon Korea 2017
 
파이썬 리액티브하게 짜기 - PyCon Korea 2017
파이썬 리액티브하게 짜기 - PyCon Korea 2017파이썬 리액티브하게 짜기 - PyCon Korea 2017
파이썬 리액티브하게 짜기 - PyCon Korea 2017
 
AngularJS 2, version 1 and ReactJS
AngularJS 2, version 1 and ReactJSAngularJS 2, version 1 and ReactJS
AngularJS 2, version 1 and ReactJS
 

이미지 프로세싱 in Python Open Source - PYCON KOREA 2020

  • 1. 이미지 프로세싱 in Python Open Source 한성민 Gopher
  • 2. Index • Image Processing • Open Source • Contribution
  • 4. 좌측에 고양이 이미지가 있습니다. 이미지 프로세싱이란
  • 5. 이 이미지는 RGB 형식이고 컴퓨터는 이것을 바이트 단위로 매트릭스(Matrix)라고 부르는 배열 형태로 저장합니다. 이미지 프로세싱이란 (166, 219, 216) (176, 176, 152) (150, 140, 111) (147, 131, 112) (135, 173, 159) (199, 160, 127) (199, 172, 155) (209, 198, 189) (131, 141, 115) (180, 142, 108) (173, 153, 150) (204, 189, 176) (95, 144, 134) (125, 127, 107) (154, 142, 132) (187, 169, 154)
  • 6. 이미지 프로세싱이란 우리는 다양한 수식을 이용하여 이미지를 변환(Transformation)할 수 있고 이것을 이미지 프로세싱(Image Processing)이라 부릅니다. 𝟏 𝟏 𝟏 𝟎 𝟎𝟎 𝟎 𝟎 𝟎 𝟏 𝟏 𝟏 𝑿 𝒀𝟎 𝟎 𝟎 𝟎 𝑾 𝑯 𝟏 𝟎 𝟎𝟎 𝟎 𝟎 𝟎 Original Translate Scale 𝒄𝒐𝒔𝜽 𝟏 𝟎 𝟎 𝟎 𝟎 𝒄𝒐𝒔𝜽 𝒔𝒊𝒏𝜽 −𝒔𝒊𝒏𝜽 Rotate
  • 7. 동영상 처리 이미지 프로세싱이란 이미지 프로세싱은 다양한 종류가 있으며 사진, 그림, 동영상에 따라서 이미지 프로세싱이 여러 갈래로 나눠집니다. Image Processing 사진, 그림 처리 기하학적 변환 색조화, 양자화, 색변환 패턴 인식, 특징 검출 압축 노이즈 제거 영상 분할, 접합
  • 8. 이미지 프로세싱이란 오늘은 그 중에서 사진, 그림과 같은 2차원 데이터의 기하학적 변환에 대해서 얘기하고자 합니다. 기하학적 변환
  • 9. 기하학적 변환 연산 기하학적 변환이란 이미지의 크기나 위치 변경, 혹은 회전 등의 변화를 가하는 것으로 어파인(Affine) 변환 혹은 원근(Perspective) 변환 등이 있습니다. 이동 (Translate) 회전 (Rotate)
  • 10. from PIL import Image img = Image.open('./cat.jpg') x = 100 y = 50 a = 1 b = 0 c = -x # move the img 100 to the right d = 0 e = 1 f = y # move the img 50 to the up translate = img.transform(img.size, Image.AFFINE, (a, b, c, d, e, f)) translate.show() Pillow Affine Translate 𝟏 𝟏 𝟏 𝑿 𝒀𝟎 𝟎 𝟎 𝟎 Translate
  • 11. from PIL import Image import math img = Image.open('./cat.jpg') angle = math.radians(45) # 45 degree a = math.cos(angle) b = math.sin(angle) c = 0 d = -math.sin(angle) e = math.cos(angle) f = 0 rotate = img.transform(img.size, Image.AFFINE, (a, b, c, d, e, f), resample=Image.BILINEAR) rotate.show() 𝒄𝒐𝒔𝜽 𝟏 𝟎 𝟎 𝟎 𝟎 𝒄𝒐𝒔𝜽 𝒔𝒊𝒏𝜽 −𝒔𝒊𝒏𝜽 Rotate Pillow Affine Rotate
  • 12. def _create_coeff( xyA1, xyA2, xyA3, xyA4, xyB1, xyB2, xyB3, xyB4): A = np.array([ [xyA1[0], xyA1[1], 1, 0, 0, 0, -xyB1[0] * xyA1[0], -xyB1[0] * xyA1[1]], [0, 0, 0, xyA1[0], xyA1[1], 1, -xyB1[1] * xyA1[0], -xyB1[1] * xyA1[1]], [xyA2[0], xyA2[1], 1, 0, 0, 0, -xyB2[0] * xyA2[0], -xyB2[0] * xyA2[1]], [0, 0, 0, xyA2[0], xyA2[1], 1, -xyB2[1] * xyA2[0], -xyB2[1] * xyA2[1]], [xyA3[0], xyA3[1], 1, 0, 0, 0, -xyB3[0] * xyA3[0], -xyB3[0] * xyA3[1]], [0, 0, 0, xyA3[0], xyA3[1], 1, -xyB3[1] * xyA3[0], -xyB3[1] * xyA3[1]], [xyA4[0], xyA4[1], 1, 0, 0, 0, -xyB4[0] * xyA4[0], -xyB4[0] * xyA4[1]], [0, 0, 0, xyA4[0], xyA4[1], 1, -xyB4[1] * xyA4[0], -xyB4[1] * xyA4[1]], ], dtype=np.float32) B = np.array([xyB1[0], xyB1[1], xyB2[0], xyB2[1], xyB3[0], xyB3[1], xyB4[0], xyB4[1]], dtype=np.float32) return linalg.solve(A, B) img = Image.open('./cat.jpg') coeff = _create_coeff( (0, 0), (img.width, 0), (img.width, img.height), (0, img.height), (-200, 0), (img.width + 200, 0), (img.width, img.height), (0, img.height), ) perspective = img.transform(img.size, Image.PERSPECTIVE, coeff, resample=Image.BILINEAR) perspective.show() Pillow Affine Perspective
  • 13. 색상 혼합(Blend) 어파인과 원근 변환 외에도 색상 혼합과 같은 방법을 이미지에 적용할 수 도 있습니다. 대표적으로 두 이미지의 색상을 혼합하는 블랜딩(Blending)이 있습니다.
  • 14. Example Pillow from PIL import Image im1 = Image.open('./cat.jpg') im2 = Image.open('./dog.jpg') im3 = Image.blend(im1, im2, 0.5) im3.show() Im1, im2 블랜딩 대부분의 이미지 라이브러리는 블랜딩을 지원합니다.
  • 17. 코드 설계 + + + + + 로드 호출 C 바인드 변환 CPU 매트릭스 연산 파이썬에서 이미지 처리는 대부분 그림과 같이 동작합니다.
  • 18. 파이썬 이미지 라이브러리 구조 Python Interface Python Bind C lang Compiled Libs 이미지 프로세스는 대부분 컴퓨터 성능을 많이 요구하기 때문에, C 언어로 작성하고 파이썬에 바인딩하여 사용합니다.
  • 19. 파이썬 바인딩 파이썬은 C 바인딩을 통해 C에서 작성된 함수를 실행 가능하며, 이를 통해 복잡한 연산을 빠르게 실행할 수 있습니다. process.py binding.c호출 libImage.c libImage.h
  • 20. 연산 방식 def blend(im1, im2, alpha): im1.load() im2.load() return im1._new(core.blend(im1.im, im2.im, alpha)) cat.jpg dog.jpg src/Image.py Imaging ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha) { Imaging imOut; int x, y; ... if (alpha >= 0 && alpha <= 1.0) { /* Interpolate between bands */ for (y = 0; y < imIn1->ysize; y++) { UINT8* in1 = (UINT8*) imIn1->image[y]; ... for (x = 0; x < imIn1->linesize; x++) { out[x] = (UINT8) ((int) in1[x] + alpha * ((int) in2[x] - (int) in1[x])); } } } else { /* Extrapolation; must make sure to clip resulting values */ for (y = 0; y < imIn1->ysize; y++) { UINT8* in1 = (UINT8*) imIn1->image[y]; ... for (x = 0; x < imIn1->linesize; x++) { ... } } } return imOut; }src/libImaging/Blend.c 파이썬에서 C로 작성된 함수 호출
  • 21. Python C Bind try: from . import _imaging as core if __version__ != getattr(core, "PILLOW_VERSION", None): raise ImportError( ... ) except ImportError as v: ... raise static PyObject* _blend(ImagingObject* self, PyObject* args) { ImagingObject* imagep1; ImagingObject* imagep2; double alpha; alpha = 0.5; if (!PyArg_ParseTuple(args, "O!O!|d", &Imaging_Type, &imagep1, &Imaging_Type, &imagep2, &alpha)) { return NULL; } return PyImagingNew(ImagingBlend(imagep1->image, imagep2->image, (float) alpha)); } src/Image.py src/_imaging.c 예를 들어, Pillow는 core를 통해 C 함수를 호출합니다.
  • 22. Python C Bind # # core library files = ["src/_imaging.c"] for src_file in _IMAGING: files.append("src/" + src_file + ".c") for src_file in _LIB_IMAGING: files.append(os.path.join("src/libImaging", src_file + ".c")) libs = self.add_imaging_libs.split() defs = [] if feature.jpeg: libs.append(feature.jpeg) defs.append(("HAVE_LIBJPEG", None)) ... if (sys.platform == "win32“ and ...): defs.append(("PILLOW_VERSION", '""%s""' % PILLOW_VERSION)) ... exts = [(Extension("PIL._imaging", files, libraries=libs, define_macros=defs))] setup.py
  • 23. Python C Bind # # core library files = ["src/_imaging.c"] for src_file in _IMAGING: files.append("src/" + src_file + ".c") for src_file in _LIB_IMAGING: files.append(os.path.join("src/libImaging", src_file + ".c")) libs = self.add_imaging_libs.split() defs = [] if feature.jpeg: libs.append(feature.jpeg) defs.append(("HAVE_LIBJPEG", None)) ... if (sys.platform == "win32“ and ...): defs.append(("PILLOW_VERSION", '""%s""' % PILLOW_VERSION)) ... exts = [(Extension("PIL._imaging", files, libraries=libs, define_macros=defs))] C 라이브러리 바인드 setup.py
  • 24. Python C Bind # # additional libraries ... tk_libs = ["psapi"] if sys.platform == "win32" else [] exts.append( Extension( "PIL._imagingtk", ["src/_imagingtk.c", "src/Tk/tkImaging.c"], include_dirs=["src/Tk"], libraries=tk_libs, ) ) exts.append(Extension("PIL._imagingmath", ["src/_imagingmath.c"])) exts.append(Extension("PIL._imagingmorph", ["src/_imagingmorph.c"])) self.extensions[:] = exts build_ext.build_extensions(self) setup.py
  • 25. Python C Bind # # additional libraries ... tk_libs = ["psapi"] if sys.platform == "win32" else [] exts.append( Extension( "PIL._imagingtk", ["src/_imagingtk.c", "src/Tk/tkImaging.c"], include_dirs=["src/Tk"], libraries=tk_libs, ) ) exts.append(Extension("PIL._imagingmath", ["src/_imagingmath.c"])) exts.append(Extension("PIL._imagingmorph", ["src/_imagingmorph.c"])) self.extensions[:] = exts build_ext.build_extensions(self) setup.py 의존 라이브러리 빌드
  • 26. Pillow Structure FreeType LibImaging Libjpeg libraqm harfbuzz libimagequant
  • 27. Pillow Structure FreeType LibImaging Libjpeg libraqm harfbuzz libimagequant 폰트 랜더링 이미지 처리 JPG 연산 텍스트 레이아웃 계산 폰트 글리프 랜더링 RGBA / 팔레트 변환
  • 29. Wand from wand.image import Image from wand.display import display with Image(filename='cat.jpg') as img: print(img.size) for r in 1, 2, 3: with img.clone() as i: i.resize(int(i.width * r * 0.25), int(i.height * r * 0.25)) i.rotate(90 * r) i.save(filename='cat-{0}.jpg'.format(r)) display(i) 파이썬 라이브러리 Wand를 통해 ImageMagick을 사용할 수 있습니다.
  • 30. Trending 2009년 하반기 이후로 OpenCV가 유행 추세 OpenCV는 컴퓨터 비전 및 물체 인식 등 다양한 기능을 추가로 제공
  • 32. Workflow PR (Pull Request) Jenkins pr-head trigger Lint error Blocking merge Fix commit Jenkins pr-head trigger Pass Request changes Fix commit Blocking merge Jenkins pr-head trigger Pass Approve Merge Merge Opened
  • 34. 포럼을 통한 버그 제보 ImageMagick 버그 포토샵, MS 워드 등 다른 프로그램 동작
  • 36. ImageMagick PR 밑줄 어파인 연산의 조정으로 위치 개선 폰트 색상과 동일한 밑줄 색상 적용
  • 37. ImageMagick PR annotate_info->affine.tx=offset.x; annotate_info->affine.ty=offset.y; pixel=annotate_info->fill; if (annotate_info->stroke.alpha != TransparentAlpha) pixel = annotate_info->stroke; (void) QueryColorname(image,&pixel,AllCompliance,color,exception); (void) FormatLocaleString(primitive,MagickPathExtent,"stroke %s " "stroke-width %g " "line 0,0 %g,0",color,(double) metrics.underline_thickness,(double) metrics.width); ... annotate_info=DestroyDrawInfo(annotate_info); annotate=DestroyDrawInfo(annotate); textlist=(char **) RelinquishMagickMemory(textlist); text=DestroyString(text); return(status); 글자와 동일한 밑줄 색상 처리 MagickCore/annotate.c
  • 39. convert -size 320x120 xc:lightblue -draw "fill tomato circle 250,30 310,30 fill limegreen circle 55,75 15,80 font Candice font-size 72 decorate UnderLine fill dodgerblue stroke navy stroke-width 2 translate 10,110 rotate -15 text 0,0 ' Anthony '" draw_mvg.gif Test with ImageMagick ImageMagick 명령어로 동작 확인
  • 40. Test with Python Wand 파이썬 Wand에서 테스트 from wand.color import Color from wand.drawing import Drawing from wand.image import Image with Image(width=320, height=100, background=Color('lightblue')) as image: with Drawing() as draw: draw.font = 'Candice' draw.font_size = 72.0 draw.text_decoration = 'underline' draw.fill_color = Color('black') draw.text(28, 68, 'Anthony') draw(image) image.save(filename='test.jpg')