分形/kf-extras
外觀
< 分形
kf-extras:Claude Heiland-Allen 為
- git clone https://code.mathr.co.uk/kf-extras.git
- make
OpenEXR[1]
sudo apt install libopenexr-dev
Exemap:將一系列平坦縮放影像轉換為最終位置,並將其轉換為指數對映(展開到對數極座標中)
- 一張長影像
- 並排平鋪
expmap n < x.txt > x.pgm # exponential map (log polar) with pseudo-de colour x.txt lists kfb files one per line, in order n is number of kfb files listed in x.txt
histogram d < x.kfb > x.pgm # histogram equalize (sort and search, O(N log N)) , d is density >= 1.0, affects the brightness curve
kfbtommit < x.kfb > x.mmit # convert to Mandel Machine iteration data format
pseudo-de < x.kfb > x.pgm # pseudo distance estimate colouring
rainbow < x.kfb > x.ppm # rainbow based on slope direction, plus pseudo-de
resize w h < x.kfb > x.kfb # resize to new (w,h) using bi-cubic interpolation
stretch < x.kfb > x.pgm # simple iteration count stretching
包含的指令碼(需要 'bash' shell 和常用的 linux 實用程式)
kfbtoogv.sh s work tmp
帶有聲音生成的自動電影製作器。這裡
- s 是所需的電影長度,以秒為單位
- work 是包含
- *.kfb 的目錄的絕對路徑;tmp 是輸出目錄的絕對路徑
它會檢查它需要的不太常見的程式
kfb-to-exr test.kfb test.exr exrheader test.exr // utility to print an OpenEXR image file's header pnmcat -tb *.exr > *.ppm // file test.exr
檢查 exr 檔案的標頭
file fraktaler-3.00000036.exr:
結果
file format version: 2, flags 0x0
Fraktaler3 (type string): "program = "fraktaler-3"
version = "0-414-g61fa84a"
location.real = "-1.748764520194788535"
location.imag = "3e-13"
location.zoom = "1.0000000e15"
bailout.iterations = 262144
bailout.maximum_reference_iterations = 262144
bailout.maximum_perturb_iterations = 4096
bailout.inscape_radius = 0.000976562
image.width = 601
image.height = 67
image.subframes = 64
transform.reflect = true
transform.exponential_map = true
render.zoom_out_sequence = true
opencl.tile_width = 601
opencl.tile_height = 67
"
channels (type chlist):
B, 32-bit floating-point, sampling 1 1
G, 32-bit floating-point, sampling 1 1
R, 32-bit floating-point, sampling 1 1
compression (type compression): zip, multi-scanline blocks
dataWindow (type box2i): (0 0) - (600 66)
displayWindow (type box2i): (0 0) - (600 66)
lineOrder (type lineOrder): increasing y
pixelAspectRatio (type float): 1
screenWindowCenter (type v2f): (0 0)
screenWindowWidth (type float): 1
type (type string): "scanlineimage"
- 現在已被完全自動的電影製作器 bash 指令碼(儲存庫中的 kfbtoogv.sh)取代 - 只需指定長度(以秒為單位)和幾個目錄即可!有些事情是硬編碼的(程式目錄、抗鋸齒因子、... - 需要將其設為執行時選項),而且使用 ghc 進行簡單的數學運算有點過分,所以它還不是完美的。
- 我在一夜之間渲染了同一位置的 3840x2160 縮放出序列到 ~/work
- 然後我 mkdir ~/work/tmp,
- kfbtoogv.sh 120 ~/work ~/work/tmp 並且 18 分鐘後獲得了 此影片,無需手動操作
mkdir ~/work
cd ~/work
wine32 ~/windows/fraktal_sft.exe
# render zoom out sequence with kalles fraktaler, saving to ~/work
for i in *.kfb ; do ~/code/maximus_kf-extras/pseudo-de < ${i} | pgmtoppm white > ${i%kfb}ppm done
# count number of kfb files, (ls *.kfb | tail -n 1) gives a hint, I had 311
ls *.kfb | ~/code/maximus_kf-extras/expmap 311 > expmap.pgm
ghc -e "100 / sqrt ( 565 * 19820 / (120 * 8000) )"
# or your favourite calculator program if you don't have ghc
# prints 29.27922435677391
# where 565 * 19820 is the size of the expmap
# 8000 is desired sample rate
# 120 is desired movie length in seconds
gimp expmap.pgm
# downscale by 29.27922435677391% (output from ghci)
# flip vertically
# make sure it's greyscale with no alpha
# save as expmap-downscaled.png
# gimp saves comments in its netpbm writers, my bad code doesn't handle it
pngtopnm < expmap-downscaled.png > expmap-downscaled.pgm
audacity
# import raw expmap-downscaled.pgm as raw unsigned 8bit PCM mono 8000Hz
# set project sample rate to 48000Hz
# select the track, mix and render
# select the track, apply filter DC Offset Removal (maybe needs a plugin)
# select the track, select amplify and apply to normalize the volume
# duplicate the track twice
# for each of the duplicates in turn, select it and apply a reverb (GVerb plugin)
# use slightly different reverb settings for each track (for stereo effect)
# normalize the duplicates by select track, select amplify, apply
# make one duplicate a left channel and the other a right channel
# set the levels of each track to -3dB
# select all tracks, mix and render
# normalize volume if needed
# select track, export as stereo wav 16bit PCM to expmap.wav
# note down the length (my test gave 1m56s)
ghc -e "1 * 60 + 56"
# to get the audio length in seconds (116)
# check the size of the kfb files (here I used 640 by 360)
# remember we have 311 kfb files
ls 00*.ppm | tac | xargs cat | ~/code/maximus_book/code/zoom 640 360 311 116 |
avconv -f yuv4mpegpipe -i - -i expmap.wav -acodec vorbis -ab 192k -vb 2M out.ogv
# finally!
mplayer out.ogv
- 引數:http://mathr.co.uk/mandelbrot/2014-12-17_kf-extras_expmap_wire.kfr
- 從 98 個 640x360 kfb 檔案渲染,生成一個 565x6075 的影像,在 GIMP 中縮小 4 倍以進行抗鋸齒。[2]
"How it works isn't too complex (most of the effort I put into making it stream data so it doesn't run out of memory for huge zoom sequences). The key loop that converts the flat image into a log-polar image runs like this:"
#pragma omp parallel for
for (int k = 0; k < expmap->circumference; ++k) {
double r = pow(0.5, 1.0 - expmap->row / (double) expmap->radius);
double t = 2 * pi * k / (double) expmap->circumference;
double i = r * cos(t) * expmap->height / 2.0 + expmap->width / 2.0;
double j = r * sin(t) * expmap->height / 2.0 + expmap->height / 2.0;
row[k] = kfb_get_nearest(expmap->kfb, i, j);
}
expmap->row++;
"Here width and height refer to the flat image, while circumference is the width of the output strip, and radius is the height of each section (one section is generated for each input file). The expmap->row variable is a counter that loops through concentric circles in the flat image, and there's some relatively simple maths to calculate the radius and angle for each point on the circle. Calculating the circumference and radius parameters is a bit more involved, here's the bit of code that does that with a few inline comments:"
expmap->circumference = expmap->height * pi / 2;
// 0.5 ^ (1 - 1 / radius) - 0.5 = |(0.5, 0)-(0.5*cos(t), 0.5*sin(t))|
// where t = 2 * pi / circumference
double t = 2 * pi / expmap->circumference;
double dx = 0.5 - 0.5 * cos(t);
double dy = 0.5 * sin(t);
double d = sqrt(dx * dx + dy * dy);
// (1 - 1 / radius) log 0.5 = log (d + 0.5)
// 1 - 1 / radius = log (d + 0.5) / log 0.5
// 1 / radius = 1 - log (d + 0.5) / log 0.5
expmap->radius = 1.0 / (1.0 - log(d + 0.5) / log(0.5));
The idea behind the maths is that ideally we want a uniform pixel aspect ratio, with pixels as square as possible. There's probably a neater and more direct way of calculating this, but I got it working so stopped looking for a better solution. Then the main loop steps through one row at a time (loading successive kfb files as necessary), keeping the previous row around to do the pseudo-de colouring I described in the previous blog post.
- 平面圖像 = 線性-線性比例影像(正常笛卡爾座標)= 曼德勃羅集部分的標準平面檢視。這裡寬度和高度指的是平面圖像。
- 對數極座標影像(expmap)
- 圓周是輸出條帶的寬度
- 半徑是每個部分的高度(為每個輸入檔案生成一個部分)
- expmap->row 變數是一個計數器,它遍歷平面圖像圓周中的同心圓,半徑引數更復雜一些,這裡有一段程式碼,它用了一些內聯註釋來實現:
- 指數對映 EXR 關鍵幀序列
- expmap
- 指數對映座標變換(對於匯出到 zoomasm 以進行高效的影片組裝很有用)
- 圍繞縮放中心的指數間隔環。見 影像 exponential_strip.svg