오늘은 http://opencvexamples.blogspot.com/p/learning-opencv-functions-step-by-step.html에 있는 세번째 예제를 따라해보도록 하겠습니다. 


3. Basic drawing examples

1) 선 그리기

소스코드부터 보시죠. 

#include <opencv2/core/core.hpp>

#include <opencv2/highgui/highgui.hpp>

#include <opencv2/imgproc/imgproc.hpp>


using namespace cv;


int main()

{

// Create black empty images

Mat image = Mat::zeros(400, 400, CV_8UC3); // 세로, 가로 각각 400, 400 사이즈의 검정 이미지를 만든다. 


// Draw a line 

line(image, Point(15, 20), Point(300, 350), Scalar(0, 255, 0), 10, 8); 

imshow("Image", image);

imwrite("result.bmp", image);


waitKey(0);

return(0);

}

링크의 예제에서는 #include <opencv2/imgproc/imgproc.hpp>가 없는데, 이걸 포함해줘야 line 함수를 사용할 수 있습니다. 

line 함수에 대해서 아는 한 설명을 해보겠습니다. 

line(image, Point(15, 20), Point(300, 350), Scalar(0, 255, 0), 10, 8); 

  • 1번째 인수: 도화지가 되어줄 이미지를 넣어줍니다. 
  • 2번째, 3번째 인수: 어디서부터 어디까지 선을 그릴지 픽셀 위치들을 뜻합니다. 즉 (15, 20)부터 (300, 350)을 잇는 선을 그리겠다는 것입니다. 

  • 4번째 인수: 선의 색을 결정지어줍니다. Scalar(0, 255, 0)은 녹색 선을 그리겠다는 것입니다. BGR순서로 되어 있습니다. 만약 Scalar(0, 0, 255)라고 세팅-하면 빨간색 선이 될 것입니다. 
  • 5번째 인수: 선의 굵기를 선택합니다. 클수록 굵어집니다.
  • 6번째 인수: 라인의 타입을 결정해줍니다. (이것의 역할은 잘 몰라서, 일단 그냥 default값으로 놔두겠습니다.)

실행결과 아래와 같은 이미지가 전시되고, 저장됩니다.



2) 원 그리기

이번에는 원을 그려보도록 하겠습니다. 

소스코드는 아래와 같습니다. 

#include <opencv2/core/core.hpp>

#include <opencv2/highgui/highgui.hpp>

#include <opencv2/imgproc/imgproc.hpp>


using namespace cv;


int main()

{

// Create black empty images

Mat image = Mat::zeros(400, 400, CV_8UC3); // 세로, 가로 각각 400, 400 사이즈의 검정 이미지를 만든다. 


// Draw a circle 

circle(image, Point(200, 200), 32.0, Scalar(0, 0, 255), 5, 8); 

  circle(image, Point(100, 300), 40.0, Scalar(255, 0, 255), 10, 8);

imshow("Image", image);

imwrite("result.bmp", image);


waitKey(0);

return(0);

}

circle 함수 

  • 1번째 인수: 역시 도화지가 되어줄 이미지입니다. 여기서는 400 x 400의 검정 이미지이겠지요? 
  • 2번째 인수: 원의 중심의 픽셀 위치입니다. 
  • 3번째 인수: 원의 반지름입니다. 
  • 4번째 인수: 원의 색깔로 역시 BGR순서로 되어 있습니다. 첫번째 원은 빨간 색이 되게 Scalar(0, 0, 255)로 설정했습니다. 
  • 5번째 인수: 원의 두께를 결정해주는 것입니다. 클수록 두꺼워집니다. 
  • 6번째 인수: 라인의 타입을 결정해주는 것입니다. 

line함수의 인수들의 진행패턴과 크게 다르지 않습니다. 아래 그림은 결과로 그려진 두 개의 원을 보여줍니다. 



3) 타원 그리기

이번에는 타원을 그리겠습니다. 

#include <opencv2/core/core.hpp>

#include <opencv2/highgui/highgui.hpp>

#include <opencv2/imgproc/imgproc.hpp>


using namespace cv;


int main()

{

// Create black empty images

Mat image = Mat::zeros(400, 400, CV_8UC3); // 세로, 가로 각각 400, 400 사이즈의 검정 이미지를 만든다. 


// Draw a ellipse

        ellipse(image, Point(200, 200), Size(100.0, 160.0), 45, 0, 360, Scalar(255, 0, 0), 1, 8);

ellipse(image, Point(200, 200), Size(100.0, 160.0), 0, 0, 360, Scalar(255, 0, 0), 5, 8);

ellipse(image, Point(200, 200), Size(100.0, 160.0), 135, 0, 360, Scalar(255, 0, 0), 10, 8);

imshow("Image", image);

imwrite("result.bmp", image);


waitKey(0);

return(0);

}

ellipse 함수가 타원을 그릴 때 사용하는 함수입니다. 

  • 1번째 인수: 도화지가 될 이미지입니다. 
  • 2번째 인수: 타원의 중심위치입니다. 
  • 3번째 인수: 타원축들의 길이를 의미합니다. 즉, 세번째 인수가 Size(100,0, 160,0)라면 x축으로는 100만큼, y축으로는 160만큼 긴 모양의 타원을 만들겠다는 것입니다. 
  • 4번째 인수: 타원이 회전된 각도입니다. 첫번째 타원의 경우 45도만큼 오른쪽으로 회전시키겠다는 것입니다. 
  • 5번째, 6번째 인수: 타원이 시작하는 각도와 끝나는 각도를 결정지어주는 것인데 완전한 타원을 그리고 싶다면 0, 360으로 설정해주면 됩니다. 
  • 7번째 인수: 색을 결정해주는 것입니다. 세 타원 모두 파란색으로 설정해줬습니다. 
  • 8번째 인수: 타원의 굵기를 결정해주는 것입니다. 크면 클수록 굵어집니다. 
  • 9번째 인수: 역시 선의 타입을 결정해주는 것입니다. 

아래 그림은 결과적으로 그려진 3개의 타원을 보여줍니다. 뭔가 멋있네요. 



4) 직사각형 그리기

직사각형 그리는 코드입니다.

#include <opencv2/core/core.hpp>

#include <opencv2/highgui/highgui.hpp>

#include <opencv2/imgproc/imgproc.hpp>


using namespace cv;


int main()

{

// Create black empty images

Mat image = Mat::zeros(400, 400, CV_8UC3); // 세로, 가로 각각 400, 400 사이즈의 검정 이미지를 만든다. 


// Draw a rectangle

rectangle(image, Point(15, 20), Point(70, 50), Scalar(0, 55, 255), +1, 4); 

rectangle(image, Point(200, 300), Point(300, 350), Scalar(100, 100, 0), -1, 8); 

imshow("Image", image);

imwrite("result.bmp", image);


waitKey(0);

return(0);

}

직사각형을 그려주는 rectangle 함수를 살펴봅시다. 

  • 1번째 인수: 도화지가 되어줄 이미지입니다.
  • 2번째 인수: 직사각형의 왼쪽 상단 모서리 픽셀 위치입니다.
  • 3번째 인수: 직사각형의 오른쪽 하단 모서리 픽셀 위치입니다.
  • 4번째 인수: 색을 결정해줍니다.
  • 5번째 인수: 양수면 빈 직사각형, 음수면 채워진 직사각형을 만듭니다.
  • 6번째 인수: 라인의 타입을 결정해줍니다. 

구현된 결과이미지입니다. 하나의 빈 직사각형과 하나의 채워진 직사각형을 보실 수 있습니다.




5) 다각형 그리기

이번에는 채워져있는 다각형을 그려보겠습니다. 

#include <opencv2/core/core.hpp>

#include <opencv2/highgui/highgui.hpp>

#include <opencv2/imgproc/imgproc.hpp>


using namespace cv;


int main()

{

// Create black empty images

Mat image = Mat::zeros(400, 400, CV_8UC3); // 세로, 가로 각각 400, 400 사이즈의 검정 이미지를 만든다. 


int w = 400;

/** Create some points */

Point rook_points[1][20]; // 여기서 rook는 체스의 말의 이름입니다.

rook_points[0][0] = Point(w / 4.0, 7 * w / 8.0);

rook_points[0][1] = Point(3 * w / 4.0, 7 * w / 8.0);

rook_points[0][2] = Point(3 * w / 4.0, 13 * w / 16.0);

rook_points[0][3] = Point(11 * w / 16.0, 13 * w / 16.0);

rook_points[0][4] = Point(19 * w / 32.0, 3 * w / 8.0);

rook_points[0][5] = Point(3 * w / 4.0, 3 * w / 8.0);

rook_points[0][6] = Point(3 * w / 4.0, w / 8.0);

rook_points[0][7] = Point(26 * w / 40.0, w / 8.0);

rook_points[0][8] = Point(26 * w / 40.0, w / 4.0);

rook_points[0][9] = Point(22 * w / 40.0, w / 4.0);

rook_points[0][10] = Point(22 * w / 40.0, w / 8.0);

rook_points[0][11] = Point(18 * w / 40.0, w / 8.0);

rook_points[0][12] = Point(18 * w / 40.0, w / 4.0);

rook_points[0][13] = Point(14 * w / 40.0, w / 4.0);

rook_points[0][14] = Point(14 * w / 40.0, w / 8.0);

rook_points[0][15] = Point(w / 4.0, w / 8.0);

rook_points[0][16] = Point(w / 4.0, 3 * w / 8.0);

rook_points[0][17] = Point(13 * w / 32.0, 3 * w / 8.0);

rook_points[0][18] = Point(5 * w / 16.0, 13 * w / 16.0);

rook_points[0][19] = Point(w / 4.0, 13 * w / 16.0);


const Point* ppt[1] = { rook_points[0] };

int npt[] = { 20 };


fillPoly(image, ppt, npt, 1, Scalar(255, 255, 255), 8);

imshow("Image", image);

imwrite("result.bmp", image);


waitKey(0);

return(0);

}

fillPoly함수의 인수들을 살펴봅시다. 

  • 1번째 인수: 도화지가 될 이미지입니다.
  • 2번째 인수: 꼭지점들을 담고 있는 배열입니다. (Array of polygons where each polygon is represented as an array of points)
  • 3번째 인수: 꼭지점들의 갯수를 담고 있는 배열입니다. (Array of polygon vertex counters)
  • 4번째 인수: 색으로 채워진 지역을 감싸는 가장자리의 갯수를 설정해줍니다. (Number of contours that bind the filled region)
  • 5번째 인수: 다각형의 색을 설정합니다.
  • 6번째 인수: 라인의 타입을 결정해줍니다.

아래 그림과 같이 체스의 rook가 그려집니다.


이번에는 fillPoly 함수를 사용해서 다각형 중의 하나인 삼각형을 하나 그려보겠습니다. 코드는 아래와 같습니다.

#include <opencv2/core/core.hpp>

#include <opencv2/highgui/highgui.hpp>

#include <opencv2/imgproc/imgproc.hpp>


using namespace cv;


int main()

{

// Create black empty images

Mat image = Mat::zeros(400, 400, CV_8UC3); // 세로, 가로 각각 400, 400 사이즈의 검정 이미지를 만든다. 


int w = 400;

/** Create some points */

Point rook_points[1][3]; // 여기서 rook는 체스의 말의 이름입니다.

rook_points[0][0] = Point(w / 2.0, w / 4.0); // Point(가로 픽셀 위치, 세로 픽셀 위치)

rook_points[0][1] = Point(w / 4.0, 3 * w / 4.0);

rook_points[0][2] = Point(3 * w / 4.0, 3 * w / 4.0);

const Point* ppt[1] = { rook_points[0] };

int npt[] = { 3 };


fillPoly(image, ppt, npt, 1, Scalar(255, 255, 255), 8);

imshow("Image", image);

imwrite("result.bmp", image);


waitKey(0);

return(0);

}

삼각형을 그리므로 세 점만 있으면 됩니다. 그려진 그림은 아래와 같습니다.




6) 이미지에 텍스트 넣기

이제 마지막으로 이미지에 텍스트 넣는 것을 따라해보겠습니다. 
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;

int main()
{
// Create black empty images
Mat image = Mat::zeros(400, 400, CV_8UC3); // 세로, 가로 각각 400, 400 사이즈의 검정 이미지를 만든다. 

putText(image, "God is good!", Point(50, 100), FONT_HERSHEY_PLAIN, 2, Scalar(0, 200, 200), 3); //이미지에 텍스트 넣기
imshow("Image", image);
imwrite("result.bmp", image);

waitKey(0);
return(0);
}
putText 함수를 살펴봅시다.
  • 1번째 인수: 도화지가 될 이미지입니다.
  • 2번째 인수: 텍스트 내용을 적어줍니다.
  • 3번째 인수: 이미지에서 텍스트가 배치될 위치를 결정해줍니다. 텍스트 스트링의 왼쪽 아래 위치가 됩니다. 
  • 4번째 인수: 폰트를 선택합니다. FONT_HERSHEY_SIMPLEX, FONT_HERSHEY_PLAIN,FONT_HERSHEY_DUPLEX, FONT_HERSHEY_COMPLEX, FONT_HERSHEY_TRIPLEX,FONT_HERSHEY_COMPLEX_SMALL, FONT_HERSHEY_SCRIPT_SIMPLEX, FONT_HERSHEY_SCRIPT_COMPLEX
  • 5번째 인수: 글자의 크기를 결정합니다. 
  • 6번째 인수: 글자의 색을 선택합니다.
  • 7번째 인수: 글자의 두께를 선택합니다. 
실행결과를 보시죠.

이번 예제는 조금 길었네요. 그리기 함수들을 이용해서 간단한 이미지를 하나 그려보겠습니다. 재미를 위해서..ㅎㅎ 아래 그림 중에서 왼쪽 아래에 있는 집을 한번 따라 그려보겠습니다. 그림의 출처는 http://cafe.naver.com/logo12/1692719입니다.


사실 노가다지만, 그래도 함수들 확실히 익힐겸 해봤습니다. 코드는 아래와 같습니다.

#include <opencv2/core/core.hpp>

#include <opencv2/highgui/highgui.hpp>

#include <opencv2/imgproc/imgproc.hpp>


using namespace cv;


int main()

{

// Create black empty images

Mat image = Mat::zeros(400, 400, CV_8UC3); // 세로, 가로 각각 400, 400 사이즈의 검은색 이미지를 만든다. 

rectangle(image, Point(0, 0), Point(399, 399), Scalar(255, 255, 255), -1, 8); // 흰색 도화지로 바꿔준다. 

// 큰 지붕, 다각형 함수 활용

int w = 400;

Point roof1_points[1][4];

roof1_points[0][0] = Point(140, 40);   

roof1_points[0][1] = Point(260, 40);

roof1_points[0][2] = Point(360, 160);

roof1_points[0][3] = Point(40, 160);

const Point* ppt1[1] = { roof1_points[0] };

int npt1[] = { 4 };

fillPoly(image, ppt1, npt1, 1, Scalar(30, 30, 30), 8);


// 건물의 몸통. 직사각형 함수 활용

rectangle(image, Point(70, 161), Point(330, 340), Scalar(150, 150, 150), -1, 8);

rectangle(image, Point(70, 341), Point(330, 360), Scalar(30, 30, 30), -1, 8);


// 작은 지붕

Point roof2_points[1][4];

roof2_points[0][0] = Point(160, 100);

roof2_points[0][1] = Point(240, 100);

roof2_points[0][2] = Point(300, 172);

roof2_points[0][3] = Point(100, 172);


const Point* ppt2[1] = { roof2_points[0] };

int npt2[] = { 4 };

fillPoly(image, ppt2, npt2, 1, Scalar(60, 60, 60), 8);


// 중간에 회색 두 줄

rectangle(image, Point(150, 173), Point(160, 340), Scalar(100, 100, 100), -1, 8);

rectangle(image, Point(240, 173), Point(250, 340), Scalar(100, 100, 100), -1, 8);

//굴뚝

Point chimney_points[1][4];

chimney_points[0][0] = Point(70, 60);

chimney_points[0][1] = Point(92, 60);

chimney_points[0][2] = Point(92, 97);

chimney_points[0][3] = Point(70, 124);


const Point* ppt3[1] = { chimney_points[0] };

int npt3[] = { 4 };

fillPoly(image, ppt3, npt3, 1, Scalar(60, 60, 60), 8);


//굴뚝 덮개 

rectangle(image, Point(67, 48), Point(95, 59), Scalar(30, 30, 30), -1, 8);


//문

rectangle(image, Point(172, 252), Point(228, 340), Scalar(70, 70, 90), -1, 8);


//문에 있는 창문 두 개

rectangle(image, Point(180, 264), Point(190, 288), Scalar(255, 200, 150), -1, 8);

rectangle(image, Point(210, 264), Point(220, 288), Scalar(255, 200, 150), -1, 8);


//문에 있는 점 두 개, 원 그리기 활용

circle(image, Point(190, 300), 2, Scalar(30, 30, 30), 2, 8);

circle(image, Point(210, 300), 2, Scalar(30, 30, 30), 2, 8);


//중간 원형 창문의 테두리

circle(image, Point(200, 210), 18, Scalar(55, 55, 55), 10, 8);


//중간 원형 창문

circle(image, Point(200, 210), 8, Scalar(255, 200, 150), 18, 8);


//중간 원형 창문 십자

rectangle(image, Point(199, 190), Point(201, 230), Scalar(55, 55, 55), -1, 8);

rectangle(image, Point(180, 209), Point(220, 211), Scalar(55, 55, 55), -1, 8);


//왼쪽 상단 창문 회색 틀

rectangle(image, Point(85, 240), Point(135, 247), Scalar(55, 55, 55), -1, 8);


//왼쪽 상단 창문 검은 틀

Point win1_points[1][4];

win1_points[0][0] = Point(88, 248);

win1_points[0][1] = Point(132, 248);

win1_points[0][2] = Point(127, 255);

win1_points[0][3] = Point(93, 255);


const Point* win1_ppt[1] = { win1_points[0] };

int win1_npt[] = { 4 };

fillPoly(image, win1_ppt, win1_npt, 1, Scalar(30, 30, 30), 8);


//왼쪽 상단 창문

rectangle(image, Point(88, 190), Point(132, 239), Scalar(255, 200, 150), -1, 8);


//왼쪽 상단 창문 십자

rectangle(image, Point(88, 215), Point(132, 217), Scalar(55, 55, 55), -1, 8);

rectangle(image, Point(109, 190), Point(111, 239), Scalar(55, 55, 55), -1, 8);

//오른쪽 상단 창문 회색 틀

rectangle(image, Point(265, 240), Point(315, 247), Scalar(55, 55, 55), -1, 8);


//오른쪽 상단 창문 검은 틀

Point win2_points[1][4];

win2_points[0][0] = Point(268, 248);

win2_points[0][1] = Point(312, 248);

win2_points[0][2] = Point(307, 255);

win2_points[0][3] = Point(273, 255);


const Point* win2_ppt[1] = { win2_points[0] };

int win2_npt[] = { 4 };

fillPoly(image, win2_ppt, win2_npt, 1, Scalar(30, 30, 30), 8);


//오른쪽 상단 창문

rectangle(image, Point(268, 190), Point(312, 239), Scalar(255, 200, 150), -1, 8);


//오른쪽 상단 창문 십자

rectangle(image, Point(268, 215), Point(312, 217), Scalar(55, 55, 55), -1, 8);

rectangle(image, Point(289, 190), Point(291, 239), Scalar(55, 55, 55), -1, 8);


//왼쪽 하단 창문 회색 틀

rectangle(image, Point(85, 315), Point(135, 322), Scalar(55, 55, 55), -1, 8);


//왼쪽 하단 창문 검은 틀

Point win3_points[1][4];

win3_points[0][0] = Point(88, 323);

win3_points[0][1] = Point(132, 323);

win3_points[0][2] = Point(127, 330);

win3_points[0][3] = Point(93, 330);


const Point* win3_ppt[1] = { win3_points[0] };

int win3_npt[] = { 4 };

fillPoly(image, win3_ppt, win3_npt, 1, Scalar(30, 30, 30), 8);

//왼쪽 하단 창문

rectangle(image, Point(88, 265), Point(132, 314), Scalar(255, 200, 150), -1, 8);


//왼쪽 하단 창문 십자

rectangle(image, Point(88, 290), Point(132, 292), Scalar(55, 55, 55), -1, 8);

rectangle(image, Point(109, 265), Point(111, 314), Scalar(55, 55, 55), -1, 8);

//오른쪽 하단 창문 회색 틀

rectangle(image, Point(265, 315), Point(315, 322), Scalar(55, 55, 55), -1, 8);


//오른쪽 하단 창문 검은 틀

Point win4_points[1][4];

win4_points[0][0] = Point(268, 323);

win4_points[0][1] = Point(312, 323);

win4_points[0][2] = Point(307, 330);

win4_points[0][3] = Point(273, 330);


const Point* win4_ppt[1] = { win4_points[0] };

int win4_npt[] = { 4 };

fillPoly(image, win4_ppt, win4_npt, 1, Scalar(30, 30, 30), 8);


//오른쪽 하단 창문

rectangle(image, Point(268, 265), Point(312, 314), Scalar(255, 200, 150), -1, 8);


//오른쪽 하단 창문 십자

rectangle(image, Point(268, 290), Point(312, 292), Scalar(55, 55, 55), -1, 8);

rectangle(image, Point(289, 265), Point(291, 314), Scalar(55, 55, 55), -1, 8);



imshow("Image", image);

imwrite("result.bmp", image);



waitKey(0);

return(0);

}


구현된 이미지는 밑에 있습니다. 사실 그냥 노가다였지만 나름 성취감이 있네요. ㅋㅋ 창문에 햇살 비친 것까지 하긴 너무 귀찮아서 패스했습니다. 






Posted by 톈진난만

댓글을 달아 주세요

오늘 묵상한 본문은 요한복음 18:3-6입니다.

유다가 군대와 대제사장과 바리새인들에게서 얻은 아랫사람들을 데리고 등과 횃불과 무기를 가지고 그리로 오는지라

예수께서 그 당할 일을 아시고 나아가 이르시되 너희가 누구를 찾느냐

대답하되 나사렛 예수라 하거늘 이르시되 내가 그니라 하시니라

예수께서 그들에게 내가 그니라 하실 때에 그들이 물러가서 땅에 엎드러지는지라

출처: 개역개정 성경


이 부분에 해당하는 매일성경 해설은 아래와 같습니다. 


주도적으로 누구를 찾느냐고 묻고, 신적 정체를 밝히십니다. 군인들은 "나사렛 사람" 예수를 찾지만, 예수님은 하나님의 이름인 "내가 그다"(출 3:14) 하고 답하십니다. 예수님의 정체가 이름을 통해 드러나자, 군인들은 그 권세에 압도당해서 저절로 뒤로 밀려나 땅에 엎드립니다. 하나님이신 분에게 합당한 경배의 자세입니다. 내 신앙과 사랑을 감추지 마십시오. 누구냐고 묻거든 담대함과 겸손함으로 대답하십시오. "나는 그리스도인입니다."

출처: 매일성경 2017년 3,4월호 p.126

오늘 본문은 유다의 배신 하에 군병들이 예수님을 붙잡으러 온 장면입니다. 이 때 예수님은 되려 그들에게 누구를 찾고 있냐고 물으십니다. 그들은 예수를 찾고 있다고 말하고, 그에 예수님은 내가 바로 그라고 답변하십니다. 여기서 "내가 그니라", 즉 "I am he"는 예수님 자신이 하나님임을 드러내는 것이라고 합니다. 신성모독이라는 프레임을 씌워서 자신을 붙잡으러 온 그들에게 자신의 정체성을 전혀 숨기지 않으십니다. 충분히 도망치실 수 있으셨고, 자신의 정체를 숨기실 수도 있으셨지만, 그러지 않으셨습니다. 자신의 정체성을 있는 그대로 드러내셨습니다. 나의 정체성은 무엇일까요? 저의 가장 중요한 정체성은 하나님의 자녀, 즉 그리스도인이라는 것입니다. 예수님을 믿는 사람입니다. 하나님은 제가 그리스도인들과 교회가 욕먹고 있는 이 시대 가운데에서도 정체성을 분명히 드러내길 원하십니다. 세계 곳곳에서는 예수님을 믿는 사람이라고 말하는 것 자체로도 목숨의 위협을 받고 있는 사람들이 많이 있습니다. 그 상황이 설령 닥쳐오더라도 제가 담대하게 겸손함으로 그리스도인임을 밝힐 수 있길 소원합니다. 그리고 매일의 일상에서도 말과 삶으로 제가 그리스도인임을 분명히 드러내길 원합니다. 정체성을 잊지 맙시다. 그리고 잃지 맙시다.

Posted by 톈진난만

댓글을 달아 주세요

오늘 묵상한 말씀은 요한복음 16:8-11입니다.

그가 와서 죄에 대하여, 의에 대하여, 심판에 대하여 세상을 책망하시리라 죄에 대하여라 함은 그들이 나를 믿지 아니함이요 의에 대하여라 함은 내가 아버지께로 가니 너희가 다시 나를 보지 못함이요 심판에 대하여라 함은 이 세상 임금이 심판을 받았음이라
출처: 개역개정 성경

이 부분에 대한 매일성경 큐티책의 해설은 아래와 같습니다.

성령님은 죄와 의와 심판에 관하여 세상을 책망하실 것입니다. 예수님을 고의로 거부하고 악의적으로 방해한 세상의 죄상을 낱낱이 들추어내십니다. 또 십자가와 부활을 통해 그리스도의 의와 세상의 불의를 드러내시고, 세상 임금인 사탄과 사망의 세력을 깨뜨리십니다. 성령이 내주하는 신자의 삶 또한 세상을 책망합니다. 우리의 말과 삶이 세상의 불의한 민낯을 그대로 보여주어야 합니다. 나는 세상을 책망합니까, 아니면 세상이 나를 책망합니까?
출처: 매일성경 2017년 3, 4월호 p.112

성령은 죄와 의와 심판에 관하여 세상을 책망하십니다. 우선 예수님을 믿지 않는 것 자체가 죄라고 말씀하십니다. 그것을 책망하신다는 것입니다. 이 말씀을 좀 더 생각해볼 필요가 있는 것 같습니다. 예수님을 믿지 않는 사람들을 책망하는 것에 그치는 것이 아니라, 예수님을 믿는 저를 포함한 여러 사람들이 과연 예수님을 제대로 믿고 있는가도 점검해봐야합니다. 저만 생각해봐도 예수님을 믿는다고 말하지만 삶으로 예수님의 가르침을 제대로 따르지 않을 때가 많기 때문입니다. 두번째로 사람들의 의롭지 못함에 대해서도 책망하십니다. 우리는 일상을 살아가면서 크고 작은 죄와 불의를 많이 범합니다. 어떤 죄는 법적인 처벌을 받아야하는 것도 있지만, 꼭 법정에 서지 않아도 하나님의 완전하신 기준에는 벗어난 죄들도 많이 있습니다. 예를 들어 우리가 밥먹듯이 하는 거짓말, 남을 시기하고 미워하는 것, 결혼 밖에서의 성관계 등이 있죠. 이러한 우리의 불의에 대해서 책망하신다는 것입니다. 세번째로 심판에 대해서 책망하십니다. 이 부분에 대해서는 아직 잘 모르겠네요. 주석을 참고하고 좀 더 생각한 후에 다시 정리하겠습니다.
성령은 예수님을 믿는 사람들 안에 내주하시는데 내주하신다면 우리를 통해 이러한 책망하심이 드러나야 합니다. 과연 저의 삶을 보고 느끼고 있는 주변 사람들이 각자가 행하고 있는 크고 작은 죄와 불의에 대해 양심에 가책을 받고 있을까요? 아니면 오히려 제가 믿지 않는 사람들에게 책망받고 있을까요? 또 아니면 다른 사람들에게는 엄격한 기준을 말하고, 저 스스로에게는 지극히 낮은 기준을 적용하고 있진 않을까요? 부디 첫번째가 제 삶이 되었으면 좋겠습니다.
Posted by 톈진난만

댓글을 달아 주세요

오늘은 http://opencvexamples.blogspot.com/p/learning-opencv-functions-step-by-step.html에 있는 두번째 예제를 공부해보겠습니다!


2. Capture video from camera


카메라를 작동시켜 촬영된 비디오를 캡쳐하는 방법입니다. 우선 코드부터 보시죠. 

위 링크에서 소개하고 있는 예제에 좀 더 덧붙여 캡쳐한 비디오를 그레이영상으로 전환한 것도 함께 출력하도록 코드를 변경했습니다.

#include "opencv2/opencv.hpp"

using namespace cv;


int main(int, char**)

{

VideoCapture cap(0); // open the default camera

if (!cap.isOpened())  // check if we succeeded

return -1;


namedWindow("Video", 1);

        namedWindow("Video1", 1);

while (1) // 무한루프

{

Mat frame, gray_frame;

cap >> frame;         // 카메라로부터 새 프레임을 얻는다. 

cvtColor(frame, gray_frame, COLOR_BGR2GRAY);    // 얻은 프레임을 그레이이미지로 변환한다. 

imshow("Video1", frame);    // 컬러영상 전시

imshow("Video", gray_frame);    // 그레이 영상 전시


if (waitKey(30) == 'c') break;    // c를 타이핑해줘야 무한루프 탈출! 

}

return 0;

}

소스코드에서 VideoCapture cap(0);에 있는 VideoCapture는 동영상 캡쳐를 위한 클래스라고 하네요. 

이 코드를 실행해보면, default camera로 설정되어 있는 웹캠에서 찍히고 있는 장면이 전시됩니다. 아래는 영상으로 출력되고 있는 장면을 스샷찍은 장면입니다. 





Posted by 톈진난만

댓글을 달아 주세요

티스토리 시작!

공지 2017.05.12 17:09

오늘부터 티스토리를 시작합니다. 

평생 읽고 공부하고 삶에 적용해야 할 성경을 묵상한 것도 정리하려고 하고, 독서하고 감상평도 남기려고 합니다.  

또 제가 전공중인 영상처리에 대해 공부한 내용들을 잘 정리해서 저 스스로도 공부하고, 관심 있는 분들의 이해를 돕고자 합니다.

배운 것을 출력하는 것이 공부에 있어서 매우 중요하다고 최근에 읽은 <완벽한 공부법>이란 책에서 그러더라구요.

저는 티스토리를 통해서 출력해보려고 합니다.

참고로 지금까지는 네이버 블로그를 이용해왔습니다. http://blog.naver.com/tlarygns0211

좀 더 퀄리티 있는 포스팅을 위해 티스토리를 주로 활용할 계획입니다. 

많은 분들과 소통하며 성장하길 기대합니다. :D

'공지' 카테고리의 다른 글

톈진난만 블로그 활용법  (10) 2017.10.23
포스팅의 목적, 가르침이 아닌 배움.  (2) 2017.06.04
티스토리 시작!  (4) 2017.05.12
Posted by 톈진난만

댓글을 달아 주세요

  1. 2017.06.12 09:16 신고  댓글주소  수정/삭제  댓글쓰기

    이제 똥 외에 뭔가를 더 출력하겠군

  2. BlogIcon 노정호 2017.10.30 11:33 신고  댓글주소  수정/삭제  댓글쓰기

    파란하늘을보다님도 이런 시작이 있었군요.ㅎㅎ
    저도 시작해보고 싶네요. 화이팅하시고, 계획한 목표 꼭
    달성하시기 바랍니다. GOOD LUCK!!!

당분간 http://opencvexamples.blogspot.com/p/learning-opencv-functions-step-by-step.html 에 있는 초보자들을 위한 예제들을 따라하면서 opencv를 공부하려고 합니다. 총 13개의 예제로 구성되어 있습니다. 참고로 영문사이트입니다.  

오늘은 첫번째 예제를 공부해보겠습니다. :D 


1. Load, Display and Save an image


첫번째 예제는 이미지를 불러와서 전시하고 저장하는 방법을 담고 있습니다. 

우선 코드를 아래에 첨부하겠습니다. 저는 opencv 3.2.0 버전과 visual studio 2017을 사용했습니다. 


main.cpp

여기서 주요한 함수들을 살펴보겠습니다.

imread는 이미지를 불러오는 함수입니다. 저는 tsuL.png를 불러왔습니다.

image = imread("tsuL.png", CV_LOAD_IMAGE_COLOR)에서 CV_LOAD_IMAGE_COLOR는 이미지를 컬러로 불러와서 image변수에 대입하겠다는 뜻입니다.

이 자리에 쓰일 수 있는 것은 4가지가 있습니다. 


  • CV_LOAD_IMAGE_ANYDEPTH - return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit.
  • CV_LOAD_IMAGE_COLOR(>0) - If set, always convert image to the color one.
  • CV_LOAD_IMAGE_GRAYSCALE (0)- If set, always convert image to the grayscale one.
  • CV_LOAD_IMAGE_UNCHANGED (<0) loads the image as is (including the alpha channel if present)


CV_LOAD_IMAGE_GRAYSCALE은 그레이영상으로 이미지를 변환해서 불러온다는 것이고, CV_LOAD_IMAGE_UNCHANGED는 있는 그대로 불러온다는 의미인 것 같습니다. CV_LOAD_IMAGE_ANYDEPTH는 잘 모르겠네요.. ㅎㅎ (아시는 분 계시면 댓글 부탁드립니다!)


imshow는 이미지를 전시해주는 함수입니다. imshow("window", image)에서 "window"라고 쓰여진 이 부분은 사진을 전시해주는 창의 이름을 의미합니다. 코드 실행결과 아래와 같은 이미지가 전시됩니다. 만약에 imshow("test_image", image)라고 코딩했다면 아래 출력된 이미지에서 창의 이름이 test_image가 되었을 것입니다. 


imwrite는 이미지를 저장해주는 함수입니다. imwrite("result.jpg", image)는 이미지를 result.jpg로 저장해준다는 것입니다. 폴더를 보면 result.jpg가 생성되었음을 확인할 수 있습니다.




Posted by 톈진난만

댓글을 달아 주세요



티스토리 툴바