검색결과 리스트
글
공개 SW 라이센스 GPL, LGPL, BSD
인터넷에 공개된 코드나 라이브러리 등을 보면 대부분 GPL 또는 LGPL 라이센스를 가지고 있는데, 개인적으로도 어떤 것인지 알아둬야 할 것 같아서 정리해 봅니다.
관련 링크
- GPL 전문(한국어 번역본): http://korea.gnu.org/documents/copyleft/gpl.ko.html
- GPL FAQ(한국어 번역본): http://www.gnu.org/licenses/gpl-faq.ko.htm
- LGPL 전문(한국어 번역본): http://korea.gnu.org/people/chsong/copyleft/lgpl.ko.html
- KLDP 오픈소스 SW 라이센스 가이드: http://wiki.kldp.org/wiki.php/OpenSourceLicenseGuide
GLP/LGPL 전문은 읽어봐도 내용이 어려워서 무슨 말인지 알기가 쉽지 않네요. 하지만 KLDP 가이드를 보면 여러 오픈소스 SW 라이센스(GPL/LGPL/BSD 등)들이 잘 비교 정리되어 있습니다.
GNU GPL(General Public License)
GPL은 Free Software Foundation(FSF)에서 만든 Free 소프트웨어 라이센스로 1989년 1차 버전, 1991년 2차 버전, 2007년 3차 버전까지 발표되었습니다.
기본적으로 어떤 프로그램을 개발할 때, GPL 코드를 일부라도 사용하게 되면 그 프로그램은 GPL이 됩니다. GPL을 가진 프로그램을 유료로 판매하는 것은 가능하지만, 반드시 전체 소스코드는 무료로 공개해야 합니다.
GPL 코드를 사용한 SW를 내부적인(개인, 기관, 단체 등) 목적으로만 사용할 때에는 소스코드를 공개할 필요가 없지만 어떤 형태로든(유료든 무료든) 외부에 공표/배포할 때에는 전체 소스코드를 공개해야 합니다.
예를 들어, GPL 코드를 수정하거나 일부 사용하여 프로그램을 개발했습니다. 이제 개발된 프로그램을 개인적으로 혹은 기관, 단쳬 내부적으로만 사용하자고 하면 코드를 공개할 의무는 없으며 그냥 사용하면 됩니다. 그런데 이 프로그램을 외부에 공개하거나 판매하고자 할 경우에는 반드시 GPL 규정에 따라서 프로그램의 전체 소스코드를 무료로 공개해야 합니다.
전체 소스코드를 무료로 공개하면서 프로그램을 유료로 판매하는 것이 얼핏 이해가 안가지만, 개발자가 아닌 일반 소비자 입장에서는 충분히 구매할 수 있다고 생각됩니다. 그리고 기관 등에 프로그램을 판매할 때에는 단순한 소스코드가 아닌 시스템 구축, 관리, 유지보수 등 토탈 솔루션을 판매한다고 생각할 수 있습니다. 이러한 것들은 아무리 소스가 공개되어 있어도 비전문가가 하기 힘든 일이기 때문입니다.
그런데, 코드를 공개하면 다른 개발자가 이를 기반으로 좀더 개선된 버전의 제품을 개발하여 판매할 수도 있을 것입니다. 일견 억울할 수도 있겠네요..
GPL 관련하여 한가지 햇갈리기 쉬운 점이 있는데, 그건 자신이 개발한 SW에서 GPL 코드를 일부만 사용한 경우입니다.
GPL 전문에 보면, '만일 배포하고자 하는 프로그램의 특정 부분이 GPL 코드로부터 파생된 것이 아닌 독립적인 저작물일 경우에는 독립 저작물 모듈의 개별적인 배포에는 GPL이 적용되지 아니한다 (즉, 코드를 공개할 필요가 없다). 하지만 프로그램을 전체(GPL코드에서 파생된 모듈 + 독립 저작물 모듈)적으로 배포할 때에는 GLP을 따라야 한다.' 고 되어 있습니다.
결론적으로, 'GPL과 관련되지 아니한 부분만 독립적으로 팔거나 배포하는 경우는 관계가 없다. 하지만 GPL 코드를 일부라도 사용한 프로그램 전체를 배포할 때에는 GPL을 적용(즉, 프로그램의 전체 소스코드 공개)해야 한다'는 말이겠네요.. 상당히 강도가 세군요..
기타 세부적인 내용에 대해서는 GPL 전문과 GPL FAQ를 참조하시면 좋습니다. 특히 GPL FAQ를 읽어보면 GPL을 이해하는데 도움이 많이 됩니다.
GPL 전문에 있는 '보통의 소프트웨어 라이센스들이 SW에 대한 공유와 수정의 자유를 제한하려는 목적을 가진 반면에 GPL은 공유와 수정의 자유를 보장하기 위한 규정이다'라는 말이 꽤나 인상적이네요..
GNU LGPL(Lesser General Public License)
LGPL은 GPL보다는 훨씬 완화된(lesser) 조건의 공개 소프트웨어 라이센스입니다.
가장 큰 차이점은 LGPL 코드를 정적(static) 또는 동적(dynamic) 라이브러리로 사용한 프로그램을 개발하여 판매/배포할 경우에 프로그램의 소스코드를 공개하지 않아도 된다는 점입니다. LGPL 코드를 사용했음을 명시만 하면 됩니다.
단, LGPL 코드를 단순히 이용하는 것이 아니라 이를 수정한 또는 이로부터 파생된 라이브러리를 개발하여 배포하는 경우에는 전체 코드를 공개해야 합니다.
BSD (Berkeley Software Distribution) 라이센스
소스코드 공개의 의무가 없으며 상용(상업적) 소프트웨어에서도 무제한 사용 가능한 라이센스라고 하는데.. 그렇다면 아무런 제한이 없는 라이센스라는 의미겠네요.
참고로 OpenCV는 BSD 라이센스를 따릅니다. GPL 정신에는 맞지 않겠지만 쓰는 사람 입장에서는 정말 편하네요..
GNU
문득 GNU는 무엇의 약자일까? 하는 궁금증이 생겨서 같이 찾아보았습니다.
"GNU's Not Unix"의 약자라는군요. gnu는 unix가 아니다.. ㅡ.ㅡ
이런 것을 재귀약자라고 한다네요.
참고로 아프리카 영양중에 gnu(누~ 라고 발음)라는 것이 있는데, 이것과 구분하여 GNU는 '그누~'라고 발음한답니다. 그리고 GNU 홈페이지(http://www.gnu.org/)에 가보면 이 영양 머리모양을 마크로 하고 있음을 알 수 있습니다.
by 다크 프로그래머
'알아두면 좋은 것들' 카테고리의 다른 글
Visual Studio 버전 (6) | 2014.03.17 |
---|---|
참고 자료들 (3) | 2014.03.11 |
여러 장의 이미지를 pdf로 만드는 간편한 방법 (48) | 2013.09.26 |
설정
트랙백
댓글
글
다각형 도형의 면적(넓이) 구하기
프로그래밍 등을 할 때 알아두면 유용한 다각형의 면적 구하는 방법입니다.
(오랜만에 수학관련 포스팅을 합니다 ^^)
1. 2차원 평면에서 세 점의 좌표를 알 때 삼각형 면적 구하기
세 점의 좌표를 (x1,y1), (x2,y2), (x3,y3)라 할 때, 세 점을 꼭지점으로 하는 삼각형의 넓이를 일반적으로 구해 보겠습니다.
[헤론의 공식]
물론 가장 간단한 방법은 헤론의 공식을 이용하는 것입니다.
--- (1)
--- (2)
삼각형의 세 변의 길이를 a, b, c라 할 때 위 식을 이용하면 손쉽게 삼각형 면적을 계산할 수 있습니다.
[벡터의 외적]
그러나 헤론의 공식보다 훨씬 효과적인 방법은 벡터의 외적을 이용하는 것입니다. 여기서 효과적이라는 의미는 프로그래밍 관점에서 연산량이 적다는 의미입니다.
벡터의 외적은 3차원 벡터에서 정의되기 때문에 z = 0으로 생각하고 문제를 적용합니다. 즉, 3차원 공간에서 세 점 (x1,y1,0), (x2,y2,0), (x3,y3,0)이 이루는 삼각형 면적을 구하는 문제로 생각합니다. 두 변을 이루는 벡터를
--- (3)
로 잡으면 삼각형의 면적은 |a × b|/2 와 같습니다 (두 벡터의 외적의 크기는 두 벡터를 두 변으로 하는 평행사변형의 넓이).
a × b = (0, 0, (x2-x1)(y3-y1)-(x3-x1)(y2-y1))이므로 구하는 삼각형의 면적은 다음과 같습니다.
--- (4)
훨씬 효과적으로 삼각형의 면적을 계산할 수 있음을 알 수 있습니다.
2. 3차원 공간에서 세 점의 좌표를 알 때 삼각형 면적 구하기
2D의 경우와 마찬가지로 헤론의 공식 또는 벡터의 외적으로 구할 수 있습니다.
세 점을 (x1,y1,z1), (x2,y2,z2), (x3,y3,z3)라 할 때 벡터의 외적을 이용한 결과만 구해보면 다음과 같습니다.
--- (5)
3차원의 경우에는 식이 좀 복잡하네요..
3. 볼록한 n각형의 면적 구하기
사각형, 오각형, 육각형 등 n각형의 면적은 이들을 삼각형으로 잘게 쪼갠 후 각각 면적을 구해 합치면 됩니다.
그런데 삼각형으로 나눌 때에도 효율적으로 나눠야 합니다. 알고리즘적으로 다각형을 나눌 수 있는 방법은 아래 그림처럼 어느 한 점을 고정하고 이 점이 공통 꼭지점이 되도록 삼각형들을 만들면 될 것입니다.
<그림 1>
만일 P1(x1,y1), P2(x2,y2), ..., Pn(xn,yn)으로 이루어진 n각형이 있다면 이 도형의 면적은 삼각형 P1P2P3, P1P3P4, ..., P1Pn-1Pn의 면적을 구해 모두 합치면 됩니다.
그런데, 만일 도형이 볼록하지 않은 경우에는 어떻게 해야 할까요?
일단은 어떤 도형이 볼록 다각형인지 오목 다각형인지 확인하는 방법부터 알아보겠습니다.
4. 볼록 다각형 / 오목 다각형 판단하기
여기 적는 방법이 가장 효과적인 방법인지는 잘 모르겠지만, 나름 생각한 방법을 적어봅니다.
[방법 1]
어떤 도형이 볼록하려면 임의의 한 변을 잡았을 때, 다른 모든 꼭지점들은 그 변을 확장한 직선을 기준으로 모두 같은 영역에 위치해야 합니다. 예를 들어, 위 그림에서 변 P1P2를 확장한 직선을 생각할 때, P3, P4, ..., Pn은 모두 이 직선의 아래쪽에 존재합니다. 그런데 만일 이 직선 위에 존재하는 꼭지점이 하나라도 존재한다면 이 도형은 오목(concave)하게 됩니다.
이러한 특징을 활용하면 볼록 다각형 여부를 판별할 수 있습니다.
어떤 도형의 방정식 f(x,y) = 0에 의해서 공간이 둘로 나뉜다고 했을 때, 점 (x1,y1), (x2,y2)가 같은 영역에 속할 필요충분 조건은 f(x1,y1)과 f(x2,y2)의 부호가 동일하다 입니다.
따라서 한 변을 지나는 직선의 방정식을 구한 후, 다른 꼭지점들을 이 직선식에 대입했을 때, 모두 같은 부호가 나오는지를 검사하면 됩니다. 이 검사를 모든 변에 대해 수행했을 때 모두 조건이 만족됐다면 이 도형은 볼록 다각형입니다.
변 P1P2의 경우만 예를 들어 보겠습니다.
P1(x1,y1), P2(x2,y2)를 지나는 직선의 방정식은 f(x,y) = (x2-x1)(y-y1)-(y2-y1)(x-x1) = 0이므로 변 P1P2의 경우에는 f(x3,y3), f(x4,y4), ..., f(xn,yn)이 모두 같은 부호인지 체크해 보면 됩니다.
☞ 참고로, 두 점 (x1,y1), (x2,y2)과 도형의 방정식 f(x,y) = 0 이 있을 때, 두 점이 같은 영역에 있을 조건은 f(x1,y1)f(x2,y2)>0, 서로 다른 영역에 있을 조건은 f(x1,y1)f(x2,y2)<0, 도형위에 있을 조건은 f(x1,y1)=0, f(x2,y2)=0 입니다. 이러한 원리를 이용하면 영상처리 등을 할 때 매우 유용하게 활용할 수 있습니다. 예를 들어, 3차원 공간에서 어떤 점 p가 평면 f에 의해 시야에서 가려졌는지 여부를 판단하려면 시점(카메라 위치) v에 대해 f(p)f(v)<0인지를 검사하면 됩니다.
[방법 2]
그런데 생각해 보니 방법 1처럼 우회적인 방법이 아니라 직접적으로 오목/볼록을 판단할 수 있는 방법도 있겠네요.
즉, 각 꼭지점에서의 내각의 크기를 조사하여 180도보다 작으면 볼록, 180도 보다 크면 그 점에서 오목이라고 판별하는 것입니다. 이렇게 하면 각각의 꼭지점이 볼록인지 오목인지 여부도 같이 판별할 수 있는 장점도 있습니다.
다각형의 한 내각의 크기는 이웃한 두 변의 사잇각을 구해야 합니다. 예를 들어, 위 그림에서 점 P2가 오목인지 볼록인지 알기 위해서는 두 벡터 P2P1 = (x1-x2, y1-y2), P2P3 = (x3-x2, y3-y2)의 사잇각을 구해야 합니다.
두 벡터의 사잇각은 벡터의 내적을 이용하여 구합니다. 두 벡터 a = (x1, y1), b = (x2, y2)가 이루는 각을 θ라 하면 a·b = |a||b|cosθ 이므로
--- (6)
그런데 벡터의 내적은 a·b = b·a로 순서에 관계없기 때문에 아래 그림과 같은 두 경우를 구분하지 못하는 문제가 있습니다. 즉, 식 (6)을 만족하는 θ가 0 ~ 2π 범위에서 2개 있는데 이중 어느 것이 a에서 b로의 각인지 내적만으로는 알 수가 없습니다.
<그림 2>
방향을 알아내기 위해 제가 생각해낸 방법은 벡터의 외적을 이용하는 것입니다.
만일 a×b>0 라면 위 그림 왼쪽 경우처럼 내각이 θ<π 인 볼록한 경우이고, a×b<0 라면 오른쪽 경우처럼 내각이 θ>π 인 오목한 경우입니다. 만일 a×b = 0 이라면 θ = 0이거나 θ = π인 경우입니다.
방법을 생각하다 보니.. 만일 내각의 값을 구할 필요가 없고 오직 오목/볼록 여부만 판단하고자 한다면 벡터의 외적만 사용해도 되겠네요. 단, 벡터 외적을 적용하기 위해서는 두 벡터를 a = (x1,y1,0), b = (x2,y2,0)과 같이 3차원으로 확장해서 사용해야 합니다.
벡터의 외적은 정말 활용도가 무궁무진하군요 ^^.
5. 오목한 n각형의 면적 구하기
만일 오목점이 1개인 경우에는 아래 그림처럼 오목점을 중심으로 볼록 다각형의 경우와 동일하게 삼각형으로 나누어 면적을 구하면 됩니다.
<그림 3>
그런데, 아래 그림처럼 오목점이 여러개인 경우에는 위 방법만으로는 면적을 구할 수가 없습니다.
<그림 4>
이 경우에는 삼각형에 따라서 어떤 삼각형은 면적을 더해줘야 하고 어떤 삼각형은 면적을 빼줘야 합니다. 예를 들어, 위 그림의 다각형 면적은 S = -P1P2P3 + P1P3P4 + ... + P1Pn-1Pn 과 같이 구할 수 있습니다.
이 문제를 좀더 일반화해서 P1, P2, ..., Pn을 꼭지점으로 하는 n각형의 면적을 구하는 식을 다음과 같이 잡아보겠습니다.
--- (7)
식 (7)에서 sign()은 +1 또는 -1의 값을 갖는 부호함수이고, area는 삼각형의 면적을 나타내는 함수입니다.
-- (이하 8.10일 추가된 내용)
관건은 삼각형의 부호를 결정하는 것인데, 그건 삼각형의 세 점을 순회하는 방향을 이용합니다.
즉, 점 P1PiPi+1이 시계방향인지 반시계 반향인지에 따라서 부호를 결정합니다. 어느 방향을 +, -로 해도 관계는 없으며 식 (7)에서와 같이 최종 결과에 절대값을 취하면 됩니다.
여기서는 예를 들어, 시계 방향을 +, 반시계 방향을 -라 잡고 위 <그림 4>의 삼각형 면적을 구해보겠습니다.
먼저, 삼각형 P1P2P3는 반시계 방향이므로 삼각형 면적을 뺍니다. 다음으로 삼각형 P1P3P4는 시계방향이므로 면적을 더합니다. 그 다음 P1P4P5, ..., P1Pn-1Pn은 모두 시계방향이므로 면적을 더합니다. 그러면 원래 다각형 면적이 나옴을 확인할 수 있습니다.
그런데, 위 식 (7)은 어떤 점을 시작점으로 잡아도 항상 다각형의 면적이 나옴을 확인할 수 있습니다. 예를 들어, P3를 시작점으로 잡고, 삼각형 P3P4P5, P3P5P6, ..., P3PnP1, P3PnP2까지 면적을 삼각형 방향에 따라 더하고 빼보면 다각형의 면적이 나옴을 알 수 있습니다.
6. 일반적인 n각형의 면적 구하기 (오목/볼록 관계없이 적용)
사실 위 식 (7)은 오목 다각형 뿐만 아니라 볼록 다각형에도 성립합니다. 즉, 오목/볼록 여부에 관계없이 다각형의 면적을 일반적으로 구할 수 있는 식입니다.
그런데, sign(△P1PiPi+1)을 결정하기 위해 △P1PiPi+1이 시계방향인지 반시계반향인지 알아내는게 문제입니다.
그런데 이 문제는 벡터의 외적을 이용하면 깔끔하게 해결됩니다. 벡터의 외적은 방향에 따라 부호가 바뀌기 때문입니다. 따라서, 앞서 식 (4)의 삼각형 면적 구하는 식에서 절대값을 없앤 식을 사용하면 됩니다. 즉, 삼각형의 부호와 면적을 따로 구할 필요없이 식 (4)의 벡터의 외적값으로 부호와 면적을 한꺼번에 구하면 됩니다.
즉, P1(x1, y1), P2(x2, y2), ..., Pn(xn, yn)을 꼭지점으로 하는 n각형의 면적을 오목/볼록 관계없이 일반적으로 다음과 같이 구할 수 있습니다.
--- (8)
7. n각형의 면적 구하는 또 다른 방법
인터넷을 검색해 보니 약간 다른 수식으로 n각형의 면적을 일반적으로 구하는 방법이 있어서 같이 소개합니다 (오목/볼록 모두 적용)
http://www.mathopenref.com/coordpolygonarea2.html에 보면 (x1,y1), ..., (xn,yn)으로 이루어진 n각형의 면적 구하는 식이 다음과 같이 나와 있습니다.
--- (9)
단, 여기서 i = n일 때의 xn+1은 xn에 연결된 다음의 점 즉, x1을 의미합니다. 마찬가지로 yn+1은 y1을 의미합니다. 이 사이트에는 왜 이 식이 면적이 되는지도 직관적으로 잘 설명되어 있습니다.
계산 결과는 같습니다만, 제가 유도한 식 (8)보다는 식 (9)가 훨씬 간결하네요.. ^^;
마지막으로, 머리속에 기억하기 좋은 다른 수식 표현으로는 다음과 같은 것도 있습니다 (출처 http://mathworld.wolfram.com/PolygonArea.html)
--- (10)
식 (10)은 학창시절에 어디선가 한번은 봤던 기억이 납니다. 즉, x좌표와 y좌표들을 순서대로 쭉 나열하고 맨 마지막에 x1, y1을 덧붙입니다. 그리고 나서 오른쪽 대각선 방향으로 좌표들을 곱한 값들에서 왼쪽 대각선 방향으로 곱한 값들을 빼준 후 1/2을 하면 면적이 나온다는...
물론 식 (10)도 오목/볼록 모든 경우에 성립합니다.
한가지 주의사항은 식 (8), (9), (10) 모두 다각형의 변들이 서로 교차하는 경우에는 성립하지 않습니다.
☞ 꼭 이 글에 있는 문제 뿐만 아니라 풀이 과정에서 사용된 여러 수학적 원리를 이해하면 여러모로 쓸모가 많을 것으로 생각합니다. 예를 들어, 볼록 다각형을 판단하는 방법은 영상 homography 행렬이 유효한 행렬인지 여부를 판단할 때 사용할 수 있습니다.
by 다크 프로그래머
'수학 이야기' 카테고리의 다른 글
도형의 평행이동에 대한 이해 (1) | 2013.08.26 |
---|---|
네 점을 지나는 구의 방정식 (12) | 2013.06.21 |
원뿔곡선 이야기(원,타원,포물선,쌍곡선) (1) | 2013.05.12 |
설정
트랙백
댓글
글
가상 3D 영상 생성 프로그램
3차원 도형을 카메라로 봤을 때, 카메라의 위치 및 방향에 따라 어떤 영상이 얻어질지를 보여주는 프로그램입니다.
카메라의 시점에 따라서 이미지가 어떻게 바뀌는지 확인할 때 유용하게 활용될 수 있을 것이라 생각합니다. 또는 역으로 이미지로부터 카메라 시점을 알아낼 수 있는지 확인하는 용도로도 사용 가능합니다.
<실행 동영상 샘플>
기능 및 사용법
본 프로그램의 GUI(사용자 인터페이스) 및 샘플 화면은 다음과 같습니다.
<gui 화면>
<샘플 화면>
키보드의 화살표 키, Shift/Ctrl+화살표 키를 이용하여 카메라의 시점을 자유롭게 바꿀 수 있습니다. 화살표 키는 전진, 후진, 제자리 회전을 하고, shift 또는 ctrl 키를 같이 누르면 카메라 틸트(tilt) 조절, 옆으로 이동을 합니다.
카메라의 높낮이 조절은 PgUp, PgDown 키를 이용합니다.
총 4가지 종류의 도형(평행선, 사각형, 박스, 사다리)을 선택할 수 있으며 도형 꼭지점들의 3D 공간좌표 혹은 픽셀좌표를 볼 수 있습니다. 평행선의 경우에는 위 그림처럼 이미지에 투영된 두 선이 이루는 각을 부가적으로 보여줍니다.
<좌: 공간좌표를 출력한 경우, 우: 픽셀 좌표를 출력한 경우>
좌표계 설정 및 팬(pan), 틸트(tilt) 기준은 3D 좌표계 변환 방법 (예: 월드좌표계 - 카메라 좌표계) 글에서 설명한 내용과 동일합니다.
프로그램 다운로드
ImagingGeometry3D.zip (UI 부분을 제외한 소스코드 포함)
프로그램 용도
이 프로그램은 여러가지 목적을 가지고 구현한 것입니다.
한가지 목적은 최근 [컴퓨터 비전에서의 Geometry #1] 좌표계 ~ [컴퓨터 비전에서의 Geometry #7] Epipolar Geometry 시리즈 글을 올리면서 사용했던 카메라 기하 모델이 정말로 맞는지 확인할 목적이 있었는데 실제로 구현해 보니 잘 맞는 것 같습니다.
다른 목적은 카메라의 높이 및 각도에 따라서 영상이 어떤 특성을 가지고 변하는지 파악하기 위함입니다. 예를 들어, 차선인식 문제에 있어서 차선 영상만 가지고 촬영한 카메라의 위치, 높이, 팬, 틸트를 알아낼 수 있는지 여부를 확인하는 용도로도 사용할 수 있습니다.
마지막으로, 외부(extrinsic) 카메라 캘리브레이션 알고리즘 혹은 위치인식 알고리즘이 정상적으로 동작하는지 여부를 확인하는 용도로도 사용가능합니다. 프로그램에서 다양한 카메라 시점에 따라 영상좌표를 획득할 수 있기 때문에 이들 영상좌표를 입력으로 외부 캘리브레이션(extrinsic calibration) 혹은 위치인식 알고리즘을 적용하여 원래 카메라 시점이 복원되는지 확인해 볼 수 있습니다.
☞ 참고로 영상왜곡 모델도 반영은 됩니다만, 현재의 구현은 꼭지점들만 투영시킨 후 직선으로 연결하는 방식이라서 직선의 휘어짐이 표시되지는 않습니다.
by 다크 프로그래머
'개발한 것들' 카테고리의 다른 글
Ferns Detector (18) | 2013.08.28 |
---|---|
DarkCapture - 화면캡쳐 녹화 프로그램 (Screen Capture Recording Program) (36) | 2013.06.26 |
Haar/Cascade Training 프로그램 (158) | 2013.06.05 |