クックブック

ここには,OpenCV の Python バインディングの特徴を示すコードを集めました.

画像の変換

>>> import cv
>>> im = cv.LoadImageM("building.jpg")
>>> print type(im)
<type 'cv.cvmat'>
>>> cv.SaveImage("foo.png", im)

画像のリサイズ

OpenCV で画像をリサイズするには,適切なサイズの出力画像を作成してから, Resize を呼び出します.

>>> import cv
>>> original = cv.LoadImageM("building.jpg")
>>> thumbnail = cv.CreateMat(original.rows / 10, original.cols / 10, cv.CV_8UC3)
>>> cv.Resize(original, thumbnail)

ラプラシアンの計算

>>> import cv
>>> im = cv.LoadImageM("building.jpg", 1)
>>> dst = cv.CreateImage(cv.GetSize(im), cv.IPL_DEPTH_16S, 3)
>>> laplace = cv.Laplace(im, dst)
>>> cv.SaveImage("foo-laplace.png", dst)

GoodFeaturesToTrack の利用

画像中の強い特徴点の上位 10 個を求めるには, GoodFeaturesToTrack を次のように使います:

>>> import cv
>>> img = cv.LoadImageM("building.jpg", cv.CV_LOAD_IMAGE_GRAYSCALE)
>>> eig_image = cv.CreateMat(img.rows, img.cols, cv.CV_32FC1)
>>> temp_image = cv.CreateMat(img.rows, img.cols, cv.CV_32FC1)
>>> for (x,y) in cv.GoodFeaturesToTrack(img, eig_image, temp_image, 10, 0.04, 1.0, useHarris = True):
...    print "good feature at", x,y
good feature at 198.0 514.0
good feature at 791.0 260.0
good feature at 370.0 467.0
good feature at 374.0 469.0
good feature at 490.0 520.0
good feature at 262.0 278.0
good feature at 781.0 134.0
good feature at 3.0 247.0
good feature at 667.0 321.0
good feature at 764.0 304.0

GetSubRect の利用

GetSubRect は,画像の矩形部分を返します.データのコピーは一切発生しません.

>>> import cv
>>> img = cv.LoadImageM("building.jpg")
>>> sub = cv.GetSubRect(img, (60, 70, 32, 32))  # sub is 32x32 patch within img
>>> cv.SetZero(sub)                             # clear sub to zero, which also clears 32x32 pixels in img

CreateMat の利用と,要素へのアクセス

>>> import cv
>>> mat = cv.CreateMat(5, 5, cv.CV_32FC1)
>>> cv.Set(mat, 1.0)
>>> mat[3,1] += 0.375
>>> print mat[3,1]
1.375
>>> print [mat[3,i] for i in range(5)]
[1.0, 1.375, 1.0, 1.0, 1.0]

ROS image message から OpenCV

このチュートリアルを参照してください: ROS 画像と OpenCV 画像を変換するための CvBridge の利用

PIL Image から OpenCV

(PIL の詳細については PIL ハンドブック を参照してください.)

>>> import Image, cv
>>> pi = Image.open('building.jpg')       # PIL image
>>> cv_im = cv.CreateImageHeader(pi.size, cv.IPL_DEPTH_8U, 3)
>>> cv.SetData(cv_im, pi.tostring())
>>> print pi.size, cv.GetSize(cv_im)
(868, 600) (868, 600)
>>> print pi.tostring() == cv_im.tostring()
True

OpenCV から PIL Image

>>> import Image, cv
>>> cv_im = cv.CreateImage((320,200), cv.IPL_DEPTH_8U, 1)
>>> pi = Image.fromstring("L", cv.GetSize(cv_im), cv_im.tostring())
>>> print pi.size
(320, 200)

NumPy と OpenCV

配列インタフェース を用いて,OpenCV の CvMat を NumPy で利用します.

>>> import cv, numpy
>>> mat = cv.CreateMat(3, 5, cv.CV_32FC1)
>>> cv.Set(mat, 7)
>>> a = numpy.asarray(mat)
>>> print a
[[ 7.  7.  7.  7.  7.]
 [ 7.  7.  7.  7.  7.]
 [ 7.  7.  7.  7.  7.]]

NumPy の配列を OpenCV で利用することができます:

>>> import cv, numpy
>>> a = numpy.ones((480, 640))
>>> mat = cv.fromarray(a)
>>> print mat.rows
480
>>> print mat.cols
640

同様に,OpenCV の関数を NumPy 配列に直接適用できます.例えば:

>>> picture = numpy.ones((640, 480))
>>> cv.Smooth(picture, picture, cv.CV_GAUSSIAN, 15, 15)

2次元配列が与えられると, fromarray 関数(または,上述の間接的なバージョン)が,同じサイズでシングルチャンネルの CvMat を返します. また, j \times k \times l の 3 次元配列の場合,サイズが j \times kl チャンネルの CvMat が返されます.

その他, allowND オプション付きで fromarray を利用すると,常に CvMatND が返されます.

OpenCV から pygame

OpenCVの画像を pygame surface に変換します:

>>> import pygame.image, cv
>>> src = cv.LoadImage("lena.jpg")
>>> src_rgb = cv.CreateMat(src.height, src.width, cv.CV_8UC3)
>>> cv.CvtColor(src, src_rgb, cv.CV_BGR2RGB)
>>> pg_img = pygame.image.frombuffer(src_rgb.tostring(), cv.GetSize(src_rgb), "RGB")
>>> print pg_img
<Surface(512x512x24 SW)>

OpenCV と OpenEXR

OpenEXR の Python バインディング を利用すると,簡単な画像ビューアを作成できます:

import OpenEXR, Imath, cv
filename = "GoldenGate.exr"
exrimage = OpenEXR.InputFile(filename)

dw = exrimage.header()['dataWindow']
(width, height) = (dw.max.x - dw.min.x + 1, dw.max.y - dw.min.y + 1)

def fromstr(s):
    mat = cv.CreateMat(height, width, cv.CV_32FC1)
    cv.SetData(mat, s)
    return mat

pt = Imath.PixelType(Imath.PixelType.FLOAT)
(r, g, b) = [fromstr(s) for s in exrimage.channels("RGB", pt)]

bgr = cv.CreateMat(height, width, cv.CV_32FC3)
cv.Merge(b, g, r, None, bgr)

cv.ShowImage(filename, bgr)
cv.WaitKey()