HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2016
0627
こしあんぼかしが重い15未解決


こしあん

リンク

2016/6/27(Mon) 16:35:22|NO.76007

cvsmoothとかgblurでの画像のばかしが重いです。
何か軽くていい方法はありませんか?
お願いします!



この記事に返信する


jsAster

リンク

2016/6/28(Tue) 17:39:48|NO.76011

そんなに重いとは感じませんね。

waitとかをfpsに合わせて調整してみてはどうでしょうか。
例えば
await 24 とか。



cats

リンク

2016/6/28(Tue) 19:17:32|NO.76012

色反転など簡単な画像処理の場合は私は機械語を使っています。
ぼかしのアルゴリズムは知らないのですが、複雑な処理でければ機械語をおすすめします。
画像処理系で一番実装が簡単なのはvramのポインタを渡す方法です。
C言語などでぼかし処理の関数を作って、関数を示す機械語をcallfuncで実行します。
色反転を毎ループ行う処理を機械語に移植してHSPで書いたことがあるのですが、
HSPの機能で書いたときの数百倍は速く動作しました。



KA

リンク

2016/6/28(Tue) 20:00:18|NO.76013

スレ内容とは関係ないけど

>>C言語などでぼかし処理の関数を作って、関数を示す機械語をcallfuncで実行します。

「機械語」なのかな? 少し違う気がします。



cats

リンク

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



zakki

リンク

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くらいしか出ていない。
やっぱりぼかしはどうしても重いのかなぁ。



cats

リンク

2016/7/2(Sat) 00:24:32|NO.76048

一応こんなのも作ってみましたが、どうでしょうか。
画像処理素人&最適化無しなので高速化はあまり期待できませんが......
http://cats.genin.jp/code/img.html#code01



774

リンク

2016/7/2(Sat) 12:31:17|NO.76049

「動きがある物」のぼかした状態の素材も用意して、それを動かすというのはどうでしょうか。



ONION software Copyright 1997-2023(c) All rights reserved.