GIMP+Python オプティカルフローであそぶ その2 CVtypes編



GIMP2.4用のプラグインとして動かしてみました。
できたところまでメモ。
二つのレイヤーに ピーマンを少し動かした状態で描く。

http://boxheadroom.com/wp/wp-content/uploads/2008/03/p1.jpg
http://boxheadroom.com/wp/wp-content/uploads/2008/03/p2.jpg

マウス右ボタン -> フィルター ->Python ー>ofblur5
こんなダイアログが表示されます。
http://boxheadroom.com/wp/wp-content/uploads/2008/03/d.jpg

と、動きの大きい部分(動きの絶対値)が選択されます。
http://boxheadroom.com/wp/wp-content/uploads/2008/03/select.jpg

(直後は画面に反映されてません。画像左下のクイックマスクボタンで切り替えすると反映されます)
http://boxheadroom.com/wp/wp-content/uploads/2008/03/select2.jpg
(左下、小さい赤い四角が見えてる場所)

ここまで。
欲しかった結果と違うなぁ~ と、最初はガッカリしたんですが、いろんなサンプル画像で遊んでみたら 使い方によっては面白いかも。

ところで、GIMPには、ピーマンのブラシが標準装備されていて、今回のサンプル画像はそれを使ってるのですが。。。なぜマスコットキャラクターではなく、ピーマン?
(こんなときは便利ですが。)

以下は作業メモ+プラグインのソースコード。

インテルから配布されてるOpenCV Pythonバインドだと、GIMPからPythonへのデータ転送が遅いので、もう一度CVtypesのお世話になることに。
(swig版に比べると、起動が遅くなるのですが。。。)

ここまでのあらすじ


今回のコード。自分用なので、print文 デバッグも残してあります。

#!/usr/bin/env python

from gimpfu import *
import CVtypes as cv
import math
from itertools import izip
gettext.install("gimp20-python", gimp.locale_directory, unicode=True)

def ofblur5(img, lyr,lyr0,lyr1):
#def ofblur5(img, lyr,lyr0,lyr1,sxy):
   import sys
   import os
   p=os.path.abspath(os.path.dirname(sys.argv[0]))
   fp=file(p+"\test.txt","a")
   #print >>fp,p
   #sys.stdout,tmp= fp,sys.stdout
   #print code
   #img=gimp.image_list()[0]
   #lyr=img.active_layer
   #s=img.selection
   w,h=x1,y1=lyr.width,lyr.height
   w0,h0=lyr0.width,lyr0.height
   w1,h1=lyr1.width,lyr1.height

   if  w0!=w1 or h0!=h1 :
       print >>fp,"size not match"
       return

   pr0=lyr0.get_pixel_rgn(0,0,w0,h0)
   pr1=lyr1.get_pixel_rgn(0,0,w0,h0)

   cvimg0 = cv.cvCreateImage( cv.CvSize( w0,h0), 8, pr0.bpp )
   cvimg1 = cv.cvCreateImage( cv.CvSize( w0,h0), 8, pr1.bpp )
   sstr0=cv.cvImageAsString(cvimg0)
   sstr1=cv.cvImageAsString(cvimg1)
   if len(sstr0)==len(pr0[:,:]) :
       sstr0[:]=pr0[ : , : ]
   else :
       ws=cvimg0.contents.widthStep
       for y in xrange(h):
           i0=y*ws
           i1=i0+w
           sstr0[ i0 : i1 ]=pr0[ : , y]

   #print >>fp, cvimg1.contents.widthStep," ",len(pr1[ : , 1])
   if len(sstr1)==len(pr1[:,:]) :
       sstr1[:]=pr1[ : , : ]

   else :
       ws=cvimg1.contents.widthStep
       for y in xrange(h):
           i0=y*ws
           i1=i0+w
           sstr1[ i0 : i1 ]=pr1[ : , y]

   """for y  in xrange(h):
       for x in xrange(w):
           src_img[x,y]=cv.cvScalar(*[ord(x) for x in pr0[x,y]])
   """

   block_size = 16;
   shift_size = 1;

   rows = int (math.ceil (h / float(block_size)))
   cols = int (math.ceil (w/ float(block_size)))
   velx = cv.cvCreateMat (rows, cols, 5) #CV_32FC1
   vely = cv.cvCreateMat (rows, cols, 5) #CV_32FC1
   cv.cvSetZero (velx)
   cv.cvSetZero (vely)

   #cvReleaseImage(img)
   gray0 = cv.cvCreateImage( cv.CvSize( w0,h0), 8, 1 )
   gray1 = cv.cvCreateImage( cv.CvSize( w0,h0), 8, 1 )
   if pr0.bpp==3 :
       cv.cvCvtColor(cvimg0, gray0, cv.CV_RGB2GRAY)
   elif pr0.bpp==4 :
       cv.cvCvtColor(cvimg0, gray0, cv.CV_RGBA2GRAY)

   if pr1.bpp==3 :
       cv.cvCvtColor(cvimg1, gray1, cv.CV_RGB2GRAY)
   elif pr1.bpp==4 :
       cv.cvCvtColor(cvimg1, gray1, cv.CV_RGBA2GRAY)

   #--------------------------------
   #main
   blocksize = cv.CvSize (block_size ,block_size )
   shiftsize = cv.CvSize (shift_size,shift_size)
   max_range = cv.CvSize (50, 50)
   cv.cvCalcOpticalFlowBM (gray0,gray1, blocksize, shiftsize,
                      max_range,0,velx,vely)

   fx=cv.cvMatAsFloat(velx)
   fy=cv.cvMatAsFloat(vely)
   #--------------------------------

   if pr0.bpp==3 :
       cv.cvCvtColor(gray0, cvimg0,  cv.CV_GRAY2RGB)
   elif pr0.bpp==4 :
       cv.cvCvtColor(gray0, cvimg0,  cv.CV_GRAY2RGBA)
       cv.cvOrS(cvimg0, cv.CvScalar(0,0,0,255.0), cvimg0)
   if pr1.bpp==3 :
       cv.cvCvtColor(gray1, cvimg1,  cv.CV_GRAY2RGB)
   elif pr1.bpp==4 :
       cv.cvCvtColor(gray1, cvimg1,  cv.CV_GRAY2RGBA)
       cv.cvOrS(cvimg1, cv.CvScalar(0,0,0,255.0), cvimg1)
   #pr0[ : , : ]=sstr0[ : ]
   #pr1[ : , : ]=sstr1[ : ]

   cvsmall=cv.cvCreateImage( cv.CvSize( cols,rows), 8, 1 )
   smallstr=cv.cvImageAsString(cvsmall)
   ws=cvsmall.contents.widthStep

   if len(smallstr)==cols*rows :
       smallstr[:]="".join( chr(int(abs(i)+abs(j))*2) for i,j in izip(fx,fy))
   else :
       for y in xrange(rows):
           i0=y*ws
           i1=i0+cols
           b=y*cols
           smallstr[i0 : i1] = "".join( chr(int(abs(i)+abs(i))*2)  for i, j in izip(fx[b:b+cols],fy[b:b+cols]))

   cvlarge= cv.cvCreateImage( cv.CvSize(w, h ), 8, 1 )
   cv.cvResize( cvsmall, cvlarge, cv.CV_INTER_CUBIC )
   largestr=cv.cvImageAsString(cvlarge)
   #print >>fp, largestr
   pdb.gimp_selection_all(img)
   s0=img.selection
   prs=s0.get_pixel_rgn(0,0,w , h )
   prs[:,:]=largestr[:]
   #prs[:,:]="xff"*(w*h)
   s0.flush()
   #cv.cvNamedWindow("test")
   #cv.cvShowImage("test",cvlarge)

   """
   ax=sxy
   ay=sxy
   dox=1
   doy=1
   displace_type=1

   pdb.plug_in_displace(img, dw, ay, ay, dox, doy, mapx, mapy, displace_type)
   """
   #sys.stdout=tmp

register(
       "python-fu-ofblur5",
       N_("python-fu-ofblur5 opencv"),
       "python-fu-pfblur4 opencv",
       "boxheadroom",
       "boxheadroom",
       "2008",
       N_("_ofblur5"),
       "RGB*, GRAY*",
       [
           (PF_IMAGE, "img",       "Input image", None),
           (PF_DRAWABLE, "lyr", "Input layer", None),
           (PF_DRAWABLE, "img0", "current image", None),
           (PF_DRAWABLE, "img1", "previous ", None),
           #(PF_SLIDER, "sxy", _("_blur  strength"), 5.0, (0, 20, 0.1)),

       ],
       [],
       ofblur5,
       menu="<Image>/Filters/Python",
       domain=("gimp20-python", gimp.locale_directory)
   )

main()
Tags: , , ,

Related posts

タグ: , , ,

コメントは受け付けていません。