クックブック

ここには,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 が返されます.