GIMPからcvInpaint処理(Python経由で)~画像の小キズ隠しに~

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

コメントを残す

メールアドレスが公開されることはありません。