오늘은 IDL에서 동영상 파일을 제작하는 방법을 소개해보고자 합니다. 물론 IDL에서는 여러가지 형식의 동영상 파일을 제작할 수 있지만, 여기서는 확장자가 .mp4인 파일로 저장되는 MPEG-4 형식의 동영상 파일을 제작하는 경우에 촛점을 맞추어서 살펴보겠습니다. 참고로 IDL의 동영상 파일 제작 기능은 8.1 버전에서 처음 도입이 되었고, 초창기에는 라이센스 문제 등으로 인하여 사용 범위가 다소 제한적이기도 했었지만, 최근 버전의 IDL에서는 이러한 이슈는 거의 다 사라지고 별다른 제한없이 해당 기능의 사용이 가능합니다.
IDL에서 MPEG-4 형식의 동영상을 제작하는 기능은 두가지 방식으로 지원됩니다. 첫번째는 IDLffVideoWrite라는 클래스의 객체를 이용하는 방법이고, 두번째는 WRITE_VIDEO 프로시저를 이용하는 방법입니다. 그래서 이 두가지 방법을 순차적으로 소개해보고자 합니다. 오늘은 먼저 IDLffVideoWrite 클래스의 객체를 사용하는 방법부터 살펴봅시다. 먼저 동영상에 담을 그래픽 컨텐츠를 생성해야 하는데요. 여기서는 플롯을 표출하면서 데이터 포인트들을 한꺼번에 모두 표시하는 대신 하나씩 순차적으로 표시하는 예제를 사용해볼까 합니다. 예제 데이터의 생성 및 표출의 과정은 다음과 같습니다.
x = FINDGEN(301)
y = SIN(2*x*!DTOR)*5+RANDOMU(seed, 301)
sx = 800
sy = 450
win = WINDOW(DIMENSIONS=[sx, sy], BACKGROUND_COLOR='khaki', $
/NO_TOOLBAR)
p = PLOT(x, y, XRANGE=[0, 300], YRANGE=[-6, 6], $
/NODATA, FONT_SIZE=11, MARGIN=0.1, /CURRENT)
tx = TEXT(0.5, 0.93, 'Test Plot for Video Save', $
ALIGNMENT=0.5, COLOR='maroon', FONT_SIZE=16, /NORMAL)
po = PLOT(x[0:0], y[0:0], COLOR='royal blue', SYMBOL='circle', $
/SYM_FILLED, SYM_SIZE=0.5, CLIP=0, /OVERPLOT)
FOR j = 0, 300 DO BEGIN
po.SetData, x[0:j], y[0:j]
ENDFOR
이 내용은 기본적으로는 301개의 데이터 포인트들로 구성된 1차원 배열인 x 및 y를 생성하고 이를 PLOT 함수로 표출하는 과정입니다. 다만 데이터 포인트들을 한꺼번에 모두 표시하는 대신 순서대로 하나씩 찍어서 늘려가는 방식으로 구현한 것입니다. 이러한 방식으로 구현하기 위하여 그래픽 표출의 순서를 다음과 같이 정의하였습니다.
(1) 맨 처음에는 PLOT 함수를 사용하여 X, Y 축으로 구성된 플롯 공간만 표출하기 위하여 PLOT 함수를 /NODATA 키워드와 함께 사용한다
(2) 그 다음에는 PLOT 함수를 별도로 사용하여 첫번째 데이터 포인트만 심볼 형태로 찍는다. 이를 위하여 PLOT 함수의 인수는 x[0:0], y[0:0]으로 투입한다.
(3) 반복형 구문을 사용하여 데이터 포인트들의 갯수를 하나씩 늘려가면서 플롯 개체의 모습을 변화시킨다. 이를 위하여 플롯 개체에 대하여 SetData 메서드를 사용하며 그 인수는 x[0:j], y[0:j]가 된다.
따라서 위의 내용을 실행하면 반복형 구문에 의하여 플롯의 데이터 포인트들이 하나씩 증가하는 모습을 볼 수 있을 것입니다. 그리고 반복이 모두 종료된 후의 최종적인 모습은 다음과 같을 것입니다.
이제 이러한 과정을 동영상 파일로 담고자 합니다. 이를 위해서는 IDLffVideoWrite 객체를 사용하는 내용을 추가해야 합니다. 이러한 내용을 추가하여 위의 내용을 전체적으로 수정해보면 다음과 같습니다.
x = FINDGEN(301)
y = SIN(2*x*!DTOR)*5+RANDOMU(seed, 301)
sx = 800
sy = 450
win = WINDOW(DIMENSIONS=[sx, sy], BACKGROUND_COLOR='khaki', $
/NO_TOOLBAR)
p = PLOT(x, y, XRANGE=[0, 300], YRANGE=[-6, 6], $
/NODATA, FONT_SIZE=11, MARGIN=0.1, /CURRENT)
tx = TEXT(0.5, 0.93, 'Test Plot for Video Save', $
ALIGNMENT=0.5, COLOR='maroon', FONT_SIZE=16, /NORMAL)
po = PLOT(x[0:0], y[0:0], COLOR='royal blue', SYMBOL='circle', $
/SYM_FILLED, SYM_SIZE=0.5, CLIP=0, /OVERPLOT)
vfile = 'idl_video.mp4'
fps = 30
oVid = IDLffVideoWrite(vfile)
vidStream = oVid.AddVideoStream(sx, sy, fps)
FOR j = 0, 300 DO BEGIN
po.SetData, x[0:j], y[0:j]
cap = win.CopyWindow(WIDTH=sx)
time = oVid.Put(vidStream, cap)
ENDFOR
oVid.CleanUp
여기서는 IDLffVideoWrite 객체의 사용을 위하여 관련 내용들이 추가되었고 이러한 내용은 볼드체로 표시하였습니다. 가장 먼저 주목해야 할 부분은 저장될 파일의 이름을 .mp4 확장자로 정의하고 이 파일명을 인수로 투입하여 IDLffVideoWrite 클래스의 객체를 생성(여기서는 oVid라는 이름으로 생성함)하는 부분입니다. 그리고 이 객체에 대하여 AddVideoStream 메서드를 적용하면서 화면의 가로 및 세로 크기(sx, sy) 그리고 초당 프레임수(fps)를 인수로 투입해야 합니다. 여기서는 이 값들을 그래픽 창의 크기와 동일한 800, 450 그리고 초당 프레임수는 30프레임으로 설정해보았습니다. 참고로 초당 프레임수(frames per second)는 동영상이 재생될 때 1초에 몇 프레임이 재생되는가를 수치로 나타내는 개념입니다. 통상적으로는 30 또는 60을 많이 사용합니다.
그리고 반복형 구문 내에 새로 들어간 내용도 주목해야 하는데, 먼저 반복 회차마다 변화하는 그림을 그래픽 창으로부터 캡쳐하기 위하여 그래픽 창 개체인 win에 대하여 CopyWindow 메서드를 사용하였습니다. 이 때 WIDTH 키워드의 값을 800으로 설정함으로써 그래픽 창의 크기와 동일한 이미지로 캡쳐되도록 하였습니다. 이렇게 캡쳐된 이미지에 해당되는 배열인 cap은 그 구조가 3x800x450인 24비트 RGB 이미지가 됩니다. 그리고 앞서 정의했던 oVid에 대하여 Put 메서드를 사용하여 이러한 캡쳐 이미지 배열(cap)을 동영상의 각 프레임별 이미지로 투입합니다. 이러한 과정이 반복되면서 비디오 스트림에 각 프레임별 이미지가 차곡차곡 누적됩니다. 이러한 반복 작업이 모두 종료된 후에는 oVid에 대하여 CleanUp 메서드를 사용하여 비디오 파일 저장 작업을 마무리하면 됩니다. 그러면 idl_video.mp4라는 동영상 파일이 생성될 것입니다. 실제로 생성된 파일을 아래에 첨부합니다. 재생 버튼을 누르면 동영상을 돌려볼 수 있습니다.
첨부된 동영상 파일을 재생해보면 우리가 의도했던대로 동영상이 제작된 것을 확인할 수 있습니다. 서두에서 언급했던 첫번째 방법인 IDLffVideoWrite 클래스의 객체를 이용하여 동영상을 제작하는 방법은 대략 이와 같습니다. 그리고 두번째 방법으로서 WRITE_VIDEO 프로시저를 사용하는 방법도 있는데요. 이 방법은 다음 회차에서 이어서 소개하기로 합니다.
이 글이 도움이 되었다면 게시물에 대하여 공감 버튼(하트 모양) 클릭 및 블로그 구독도 해주시면 더 큰 힘이 됩니다. 감사합니다.
'IDL > New Graphics' 카테고리의 다른 글
동영상 파일의 제작 [3] (2) | 2024.11.13 |
---|---|
동영상 파일의 제작 [2] (1) | 2024.11.12 |
그래픽 창 없이 그림을 표출하고 저장하기 (Z-Buffer) (0) | 2024.10.28 |
플롯(Plot) 상에 축과 데이터 추가하기 [2] (1) | 2024.10.22 |
플롯(Plot) 상에 축과 데이터 추가하기 [1] (0) | 2024.10.16 |