|
|
2016/6/27(Mon) 16:35:22|NO.76007
cvsmoothとかgblurでの画像のばかしが重いです。
何か軽くていい方法はありませんか?
お願いします!
|
|
2016/6/28(Tue) 17:39:48|NO.76011
そんなに重いとは感じませんね。
waitとかをfpsに合わせて調整してみてはどうでしょうか。
例えば
await 24 とか。
|
|
2016/6/28(Tue) 19:17:32|NO.76012
色反転など簡単な画像処理の場合は私は機械語を使っています。
ぼかしのアルゴリズムは知らないのですが、複雑な処理でければ機械語をおすすめします。
画像処理系で一番実装が簡単なのはvramのポインタを渡す方法です。
C言語などでぼかし処理の関数を作って、関数を示す機械語をcallfuncで実行します。
色反転を毎ループ行う処理を機械語に移植してHSPで書いたことがあるのですが、
HSPの機能で書いたときの数百倍は速く動作しました。
|
|
2016/6/28(Tue) 20:00:18|NO.76013
スレ内容とは関係ないけど
>>C言語などでぼかし処理の関数を作って、関数を示す機械語をcallfuncで実行します。
「機械語」なのかな? 少し違う気がします。
|
|
2016/6/28(Tue) 20:31:33|NO.76014
>「機械語」なのかな? 少し違う気がします。
これといって良い説明が思いつかなかったので、「機械語」と表現しました。
(「関数を示す」というのは余計だったかもしれません。)
できるだけ広範囲の処理を機械語(のバイナリデータ)で持っておいて、
それをcallfuncで呼び出せば、HSPのプロセッサとは独立した形で動作するので
高速化できる、といった感じです。
改めて読むと私の説明下手ですね。
とりあえず質問者さんに伝われば良いのですが......
|
|
2016/6/28(Tue) 21:15:54|NO.76015
ちょっと機械語とか分かりません...
|
|
2016/6/28(Tue) 21:56:16|NO.76016
「明らかに速度が低下している」というレベルの重さということは、ゲーム等の演出のために、
強度の高いぼかし処理を何回も連続して行っているのでしょうか?
それでしたら、演出のために何フレーム使うのかをあらかじめ決めておいて、そのフレームの数だけ
ぼかし画像を最初に作っておけば良いのではないでしょうか?
質問の意図を誤解していたら申し訳ありませんが、こんな↓感じで作ってみました。
#const anm_flames 20 //フレーム数
#const anm_x 400 //アニメさせる画像の横幅。メモリ節約のため、できれば小さめにした方がいい
#const anm_y 300 //アニメさせる画像の縦幅。同上
#const w_time 50 //アニメ時のウェイト
#const s_power 4 //ぼかしの強さ
#include "hspcv.as"
buffer 1,anm_x,anm_y,0 //元画像置き場
buffer 2,anm_x*anm_flames,anm_y,0 //加工後の画像をまとめて置いておく場所
buffer 3,anm_x,anm_y,0 //cvバッファからの転送用
gsel 1 : pos 0,0 : picload "hoge.jpg",1
cvbuffer 0,anm_x,anm_y
repeat anm_flames
gsel 1
cvputimg 0
cvsmooth CV_GAUSSIAN,1+cnt*s_power*2,1+cnt*s_power*2,,0
gsel 3
cvgetimg 0,0
gsel 2
pos anm_x*cnt,0
gcopy 3,0,0,anm_x,anm_y
loop
//不要になったバッファを破棄
buffer 1,1,1,0
buffer 3,1,1,0
cvbuffer 0,1,1
screen 0,anm_x,anm_y,0
gsel 0
celdiv 2,anm_x,anm_y
repeat anm_flames
pos 0,0
celput 2,cnt
//celput 2,anm_flames-1-cnt //ぼかしが徐々に晴れていくという演出にしたい場合は、上の行を←これに置き換える
await w_time
loop
//不要になったバッファを破棄
buffer 2,1,1,0

| |
|
2016/6/28(Tue) 22:12:58|NO.76018
表現が変わっても問題ないのなら第2と第3引数のカーネルサイズ小さくしたり
タイプにCV_BLURを選んだりするのはどうでしょう
cvsmoothはOpenCVのcvSmoothへの薄いラッパーでOpenCV自体C++やSIMD intrinsicsで割と最適化されてるので
機械語使うにしても何倍も早くするっていうのは結構難しいんじゃないかと思います
|
|
2016/6/28(Tue) 22:18:42|NO.76019
追記です。
こちらは「ぼかした画像はあまりきめ細かく描く必要はないだろう」ということで、
メモリ節約のためにぼかし後の画像を縮小して保持しておき、表示時に拡大する方法にしています。
#const anm_flames 20 //フレーム数
#const anm_x 400 //アニメさせる画像の横幅
#const anm_y 300 //アニメさせる画像の縦幅
#const anm_x2 200 //縮小後の画像の横幅。実際に表示する際はanm_xまで拡大する
#const anm_y2 150 //縮小後の画像の縦幅。実際に表示する際はanm_yまで拡大する
#const w_time 50 //アニメ時のウェイト
#const s_power 4 //ぼかしの強さ
#include "hspcv.as"
buffer 1,anm_x,anm_y,0 //元画像置き場
buffer 2,anm_x2*anm_flames,anm_y2,0 //加工後の画像をまとめて置いておく場所
buffer 3,anm_x,anm_y,0 //cvバッファからの転送用
gsel 1 : pos 0,0 : picload "hoge.jpg",1
cvbuffer 0,anm_x,anm_y
repeat anm_flames
gsel 1
cvputimg 0
cvsmooth CV_GAUSSIAN,1+cnt*s_power*2,1+cnt*s_power*2,,0
gsel 3
cvgetimg 0,0
gsel 2
pos anm_x2*cnt,0
gzoom anm_x2,anm_y2,3,0,0,anm_x,anm_y
loop
//不要になったバッファを破棄
buffer 3,1,1,0
cvbuffer 0,1,1
screen 0,anm_x,anm_y,0
gsel 0
celdiv 2,anm_x2,anm_y2
zoomx=double(anm_x)/double(anm_x2)
zoomy=double(anm_y)/double(anm_y2)
repeat anm_flames
//cnt0=cnt
cnt0=anm_flames-1-cnt //ぼかしが徐々に晴れていくという演出にしたい場合は、上の行を←これに置き換える
pos 0,0
if cnt0=0 {
gcopy 1,0,0,anm_x,anm_y //ぼかし無しの場合は、元画像をそのまま表示
} else {
celput 2,cnt0,zoomx,zoomy
}
await w_time
loop
//不要になったバッファを破棄
buffer 1,1,1,0
buffer 2,1,1,0

| |
|
2016/6/29(Wed) 09:57:11|NO.76022
確か縮小してからぼかしても見た目変わらなかったような・・・
|
|
2016/6/30(Thu) 18:34:42|NO.76035
>スペース様
おお、縮小してからぼかしたら、だいぶ早くなりました。
ありがとうございます。
#const anm_flames 20 //フレーム数
#const anm_x 400 //アニメさせる画像の横幅
#const anm_y 300 //アニメさせる画像の縦幅
#const anm_x2 200 //縮小後の画像の横幅。実際に表示する際はanm_xまで拡大する
#const anm_y2 150 //縮小後の画像の縦幅。実際に表示する際はanm_yまで拡大する
#const w_time 50 //アニメ時のウェイト
#const s_power 4 //ぼかしの強さ
#include "hspcv.as"
buffer 1,anm_x,anm_y,0 //元画像置き場
buffer 2,anm_x2*anm_flames,anm_y2,0 //加工後の画像をまとめて置いておく場所
buffer 3,anm_x,anm_y,0 //cvバッファ間とのやりとり用
gsel 1 : pos 0,0 : picload "hoge.jpg",1
cvbuffer 0,anm_x2,anm_y2
repeat anm_flames
gsel 3
pos 0,0
gzoom anm_x2,anm_y2,1,0,0,anm_x,anm_y
cvputimg 0
cvsmooth CV_GAUSSIAN,1+cnt*s_power*2,1+cnt*s_power*2,,0
cvgetimg 0,0
gsel 2
pos anm_x2*cnt,0
gcopy 3,0,0,anm_x2,anm_y2
loop
//不要になったバッファを破棄
buffer 3,1,1,0
cvreset
screen 0,anm_x,anm_y,0
gsel 0
celdiv 2,anm_x2,anm_y2
zoomx=double(anm_x)/double(anm_x2)
zoomy=double(anm_y)/double(anm_y2)
repeat anm_flames
cnt0=cnt
//cnt0=anm_flames-1-cnt //ぼかしが徐々に晴れていくという演出にしたい場合は、上の行を←これに置き換える
pos 0,0
if cnt0=0 {
gcopy 1,0,0,anm_x,anm_y
} else {
celput 2,cnt0,zoomx,zoomy
}
await w_time
loop
//不要になったバッファを破棄
buffer 1,1,1,0
buffer 2,1,1,0

| |
|
2016/7/1(Fri) 21:07:37|NO.76043
遅くなってすみません。
私は動画みたいに動きがある物をリアルタイムにぼかしたいんです。
でも、リアルタイムでぼかすとどうしても動作が重くなっちゃって...
こんな言い方ですみません...
|
|
2016/7/1(Fri) 23:53:05|NO.76046
この↓サイトを参考に、ちょっとやってみました
http://www.sm.rim.or.jp/~shishido/befog.html
最初に「上下左右にどのくらいの輝度でコピーするのか」をあらわすテーブルを作り、
そのテーブルに基づいて輝度を変化させて、ズラし加算コピーを行う、という方法を使っています。
//smooth_init %1,%2 :ぼかしテーブルの初期化。smoothを実行する前にこれを実行。
// %1はぼかし強度。
// %2は明るさ補正(実数→整数の変換の際に小数点以下が切り捨てられる都合上、ぼかしが強くなるほど暗くなるので)
//smooth %1 :バッファ%1の内容をぼかして表示
#module
#deffunc smooth_init int _power,int hosei
power=_power
ddim rate0,power*2+1,power*2+1
ddim rate1,power*2+1,power*2+1
dim rate,power*2+1,power*2+1
rate0(power,power)=1.0
repeat power
repeat power*2+1
cnt0=cnt
repeat power*2+1
if rate0(cnt0,cnt)!=0 {
rate1(cnt0-1,cnt)=rate1(cnt0-1,cnt)+rate0(cnt0,cnt)/12.0
rate1(cnt0,cnt-1)=rate1(cnt0,cnt-1)+rate0(cnt0,cnt)/12.0
rate1(cnt0+1,cnt)=rate1(cnt0+1,cnt)+rate0(cnt0,cnt)/12.0
rate1(cnt0,cnt+1)=rate1(cnt0,cnt+1)+rate0(cnt0,cnt)/12.0
rate1(cnt0,cnt)=rate1(cnt0,cnt)+rate0(cnt0,cnt)*2.0/3.0
}
loop
loop
repeat power*2+1
cnt0=cnt
repeat power*2+1
rate0(cnt0,cnt)=rate1(cnt0,cnt)
rate1(cnt0,cnt)=0.0
loop
loop
loop
repeat power*2+1
cnt0=cnt
repeat power*2+1
rate(cnt0,cnt)=int(255.0*rate0(cnt0,cnt))
if rate(cnt0,cnt)!=0 : rate(cnt0,cnt)=limit(rate(cnt0,cnt)+hosei,1,255)
loop
loop
//メモリ解放
dim rate0,1
dim rate1,1
return
#deffunc smooth int buf
buf0=ginfo_sel
gsel buf
x=ginfo_winx
y=ginfo_winy
gsel buf0
redraw 0
color 0,0,0 : boxf
repeat power*2+1
cnt0=cnt
repeat power*2+1
if rate(cnt0,cnt)!=0 {
gmode 5,x,y,rate(cnt0,cnt)
pos 0-power+cnt0,0-power+cnt
gcopy buf
}
loop
loop
redraw 1
return
#global
//以下サンプル
//バッファ2に読み込んだ画像をバッファ1に横スクロール表示させ、リアルタイムでぼかしてスクリーン0に表示
screen 0,400,300,0
buffer 1,400,300,0
buffer 2,600,480,0
gsel 2 : pos 0,0
picload "hoge.jpg",1
gsel 0
smooth_init 20,2
repeat 100
gsel 1
pos 0,0 : gcopy 2,cnt,0,400,300
gsel 0
smooth 1
await 1000/30
loop
stop
ぼかし強度を変化させるには再度smooth_initを実行すれば良いのですが、ぼかし強度が大きくなるほど
処理に時間がかかります。
素人が作ったものゆえツッコミどころ多いかもしれませんが、お役に立てれば。

| |
|
2016/7/2(Sat) 00:06:34|NO.76047
沢渡さん、本当にありがとうございます。
うぬぬぬ...
11 FPSくらいしか出ていない。
やっぱりぼかしはどうしても重いのかなぁ。
|
|
2016/7/2(Sat) 12:31:17|NO.76049
「動きがある物」のぼかした状態の素材も用意して、それを動かすというのはどうでしょうか。
|
|