0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

 
この記事はアドカレに参加しています。

luajitでボックスブラー

luajitでボックスブラーをやっていきます。
とはいえ、luajitもスクリプト言語。速度はあまり期待できないです。

ボックスブラーとは

ボックスブラーとはその名の通りボックス(箱)の形でぼかしていく画像処理です。任意ピクセルとその周囲の平均から色を求めていきます。

アルゴリズム

先人の方達が素晴らしいアルゴリズムを共有してくださっています。
今回はそれをそのまま使います。
言語不問で実装する高速な移動平均処理
フィルタ処理の高速化アルゴリズム(縦横に処理を分ける)
gaussian フィルタ
 
要点は二つあります。
1.二次元的な処理を一次元的な処理(縦と横の二回)に分ける。
2.移動平均処理で、計算回数を減らす。

コード

.anmとして使用できます。

--[[

blur.anm
	ボックスブラーです。

]]

--track0:size,1,1000,100,1

local ffi=require"ffi"

pcall(ffi.cdef,[[
    typedef struct Pixel_ {
      uint8_t b,g,r,a;
    } Pixel;
  ]])

local work,data,w,h=obj.getpixeldata"work",obj.getpixeldata()
local c=ffi.cast("Pixel*",data)
local r=ffi.cast("Pixel*",work)
local function f(a)
 if(a<0)then return 0
 elseif(a>255)then return 255
 else return math.floor(a)
 end
end

local ha=obj.track0--正の整数
local ha2=ha*2

--横方向にぼかしていく
for y=0,h-1 do
 local to,ix={0,0,0,0},y*w
 for i=0,ha-1 do
   to[1]=to[1]+c[ix+i].r
   to[2]=to[2]+c[ix+i].g
   to[3]=to[3]+c[ix+i].b
   to[4]=to[4]+c[ix+i].a
 end
 for x=0,w-1 do
  if(x<w-ha)then
   to[1]=to[1]+c[ix+ha].r
   to[2]=to[2]+c[ix+ha].g
   to[3]=to[3]+c[ix+ha].b
   to[4]=to[4]+c[ix+ha].a
  end
  if(x>=ha)then
   to[1]=to[1]-c[ix-ha].r
   to[2]=to[2]-c[ix-ha].g
   to[3]=to[3]-c[ix-ha].b
   to[4]=to[4]-c[ix-ha].a
  end
  r[ix].r=f(to[1]/ha2)
  r[ix].g=f(to[2]/ha2)
  r[ix].b=f(to[3]/ha2)
  r[ix].a=f(to[4]/ha2)
  ix=ix+1
 end
end

--縦方向にぼかしていく
local haw=ha*w
for x=0,w-1 do
 local to,ix={0,0,0,0},x
 for i=0,ha-1 do
   to[1]=to[1]+r[ix+i*w].r
   to[2]=to[2]+r[ix+i*w].g
   to[3]=to[3]+r[ix+i*w].b
   to[4]=to[4]+r[ix+i*w].a
 end
 for y=0,h-1 do
  if(y<h-ha)then
   to[1]=to[1]+r[ix+haw].r
   to[2]=to[2]+r[ix+haw].g
   to[3]=to[3]+r[ix+haw].b
   to[4]=to[4]+r[ix+haw].a
  end
  if(y>=ha)then
   to[1]=to[1]-r[ix-haw].r
   to[2]=to[2]-r[ix-haw].g
   to[3]=to[3]-r[ix-haw].b
   to[4]=to[4]-r[ix-haw].a
  end
  c[ix].r=f(to[1]/ha2)
  c[ix].g=f(to[2]/ha2)
  c[ix].b=f(to[3]/ha2)
  c[ix].a=f(to[4]/ha2)
  ix=ix+w
 end
end


obj.putpixeldata(data)


おわりに

luajitでボックスブラーをやりました。
実際に使用してみると分かりますが、とても重いです。実用性を考慮するならば素直にdllでマルチスレッドとかsimdとかしたほうがいいです。
ところで、gpuで高速化できるとか聞いたのですが、本当なんですかね…?
最近オンボの限界を感じます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?