[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()