[pukiwiki]
//今日の一行ニュース
//[[使うのが惜しい 顔がついた「こけしマッチ」って?:http://www.excite.co.jp/News/bit/E1225272377472.html]]
//これは楽しげ
//防災科学技術研究所(略称:防災科研)
//http://www.bosai.go.jp/
//*[[大加速度地震動時における片揺れ現象(トランポリン効果)の発見:http://www.bosai.go.jp/news/press_release/20081031_01.pdf]]
OpenCVのinpaint関数をGIMPから(Python経由で)使えるようにしてみました。
処理結果はこちらのサンプルみたいな感じ。
-[[【動画】inpaint処理結果サンプル:http://video.nifty.com/cs/catalog/video_metadata/catalog_071111041075_1.htm]]
あまり大げさなことは出来ませんが、小さいノイズを消したりするのに便利なので、個人的に手放せません。
以下コード
[/pukiwiki]
[pukiwiki]
関連
-[[不要オブジェクトの除去 cvInpaint Cサンプルコード(opencv.jp):http://opencv.jp/sample/special_transforms.html#inpaint]]
-[[Gimp Python Documentation:http://www.jamesh.id.au/software/pygimp/pygimp.html]]
オマケ
-[[知って得する5つの『GIMP』トリック:http://www.lifehacker.jp/2008/10/gimp.html]]
「四角選択ー>角丸」 一週間早く知りたかったー
*わかってる不具合
なんでこうなるの?
-フィルタ動作後、レイヤーが非表示になったままです。
表示してやると、処理が画面に反映されます
-アンドゥーがききません。
*下記のプログラムが動くまでの道のり
–GIMP (レタッチソフト)
[[GIMP2を使おう:http://www.geocities.jp/gimproject/gimp2.0.html]]
–Python
[[GIMP2.4 win32版のプラグインをPythonで書く インストール編:http://boxheadroom.com/2007/12/16/gimp_python]]
–OpenCV
–CVtypes PythonからOpenCVを使うためのライブラリ
今回はパッチなしで動くようにしてみました。
[[「CVtypes.py」OpenCVをctypes経由で使う:http://boxheadroom.com/2007/12/19/cvtypes]]
—-
*その他のメモ
cvSetDataなどを使い、以前よりも、ちょっとだけ、GIMPとOpenCVの間の画像データのやりとりが速くなったはず。
[/pukiwiki]
#!/usr/bin/env python from gimpfu import * import CVtypes as cv import ctypes import sys gettext.install("gimp20-python", gimp.locale_directory, unicode=True) def cvImageAsString(img): btype = ctypes.c_char * img[0].imageSize return btype.from_address(img[0].imageData) _cvDLL = ctypes.cdll.cv100 cvInpaint =cv.cfunc('cvInpaint',_cvDLL, None, ('src', ctypes.c_void_p, 1), # const CvArr* src ('mask', ctypes.c_void_p, 1), # CvArr* dst ('dst', ctypes.c_void_p, 1), # CvArr* dst ('flags', ctypes.c_int, 1), # int flags ('inpaintRadius', ctypes.c_double, 1), # double threshold1 ) def cvinpaint(img,layer): r=10 gimp.progress_init("cvInPaint") gimp.progress_update(0.5) #percnt 0 ->1.0 flag,x0,y0,x1,y1=gimp.pdb.gimp_selection_bounds(img) ox,oy=layer.offsets x0-=ox; x1-=ox; y0-=oy; y1-=oy if not flag : return x0=max(x0-r,0) y0=max(y0-r,0) x1=min(x1+r,layer.width) y1=min(y1+r,layer.height) r=float(r) w=x1-x0; h=y1-y0 p0=layer.get_pixel_rgn(x0,y0,w,h) src_img = cv.cvCreateImage( cv.CvSize( w,h), 8, p0.bpp ) cv.cvSetData(src_img,str(p0[:,:]),w*p0.bpp) #--------------- stp=src_img[0].widthStep sstr=cvImageAsString(src_img) stp2=w*p0.bpp idx0=0 for y in xrange(y0,y1): idx1=idx0+stp2 p0[x0:x1,y]=sstr[idx0:idx1] idx0+=stp #--------------- if layer.bpp==4 : src4=src_img src_img=cv.cvCreateImage( cv.CvSize( w,h), 8, 3) cv.cvCvtColor( src4, src_img,cv.CV_BGRA2BGR ) gimp.progress_update(0.6) #percnt 0 ->1.0 layer.visible=False sel=img.selection ps=sel.get_pixel_rgn(x0+ox,y0+oy,w,h) mask_img = cv.cvCreateImage( cv.CvSize( w,h), 8, 1) cv.cvSetData(mask_img,str(ps[:,:]),w) dst_img = cv.cvCloneImage (src_img) gimp.progress_update(0.7) #percnt 0 ->1.0 cvInpaint (src_img, mask_img, dst_img, cv.CV_INPAINT_TELEA, r) gimp.progress_update(0.8) #percnt 0 ->1.0 if p0.bpp==4 : cv.cvCvtColor( dst_img, src4, cv.CV_BGR2BGRA ) cv.cvReleaseImage(dst_img) cv.cvOrS(src4, cv.CvScalar(0,0,0,255.0), src4) dst_img=src4 dstr=cvImageAsString(dst_img) stp=dst_img[0].widthStep stp2=w*p0.bpp idx0=0 for y in xrange(y0,y1): idx1=idx0+stp2 p0[x0:x1,y]=dstr[idx0:idx1] idx0+=stp cv.cvRelease(dst_img) cv.cvRelease(mask_img) cv.cvRelease(src_img) layer.visible=True gimp.displays_flush() gimp.progress_update(1.0) #img.undo_group_end() register( "python-fu-cvinpaint", N_("CvInPaint OpenCV"), "Adds a layer of fog to the image.", "BoxHeadRoom", "BoxHeadroom.com", "2007", N_("_CvInPaint..."), "RGB*, GRAY*", [ (PF_IMAGE, "image", "Input image", None), (PF_DRAWABLE, "drawable", "Input drawable", None), ], [], cvinpaint, menu="<Image>/Filters/OpenCV", domain=("gimp20-python", gimp.locale_directory) ) main()