OpenCV Memo - eiichiromomma/CVMLAB GitHub Wiki

(OpenCV) Memo

OpenCVメモ書き

楕円フィッティングへの引数の点列がおかしいのでメモ

定義(リファレンスより)

Python: cv.FitEllipse2(points)->Box2D

と点列を渡せばよいだけ。非常にシンプルになった。

点列は

Nx2 numpy array (Python interface)

とある。

使ってみる

import cv2 as cv
import numpy as np
points = [](/eiichiromomma/CVMLAB/wiki/)
points = np.append(points, [-2,0](/eiichiromomma/CVMLAB/wiki/-2,0),axis=1)
points = np.append(points, [-1,-2](/eiichiromomma/CVMLAB/wiki/-1,-2),axis=0)
points = np.append(points, [1,-1](/eiichiromomma/CVMLAB/wiki/1,-1),axis=0)
points = np.append(points, [0,-2](/eiichiromomma/CVMLAB/wiki/0,-2),axis=0)
points = np.append(points, [1,1.5](/eiichiromomma/CVMLAB/wiki/1,1.5),axis=0)

として

elipse = cv.fitEllipse(points)

を実行すると

error: (-215) points.checkVector(2) >= 0 && (points.depth() == CV_32F || points.depth() == CV_32S) in function fitEllipse

とエラー。これはnp.float32じゃないせいなので

points = np.float32(points)
array([[-2. ,  0. ],
       [-1. , -2. ],
       [ 1. , -1. ],
       [ 0. , -2. ],
       [ 1. ,  1.5]], dtype='float32')

として elipse = cv.fitEllipse(points) とすると error: (-210) The matrix can not be converted to point sequence because of inappropriate element type in function cvPointSeqFromMat とエラー。

findContour等点列を返す関数を見てみると次元がもう一つ多いarrayを返している。 という訳で

import cv2 as cv
import numpy as np
points = [[](/eiichiromomma/CVMLAB/wiki/[)]
points = np.append(points, [[-2,0](/eiichiromomma/CVMLAB/wiki/[-2,0)],axis=2)
points = np.append(points, [[-1,-2](/eiichiromomma/CVMLAB/wiki/[-1,-2)],axis=1)
points = np.append(points, [[1,-1](/eiichiromomma/CVMLAB/wiki/[1,-1)],axis=1)
points = np.append(points, [[0,-2](/eiichiromomma/CVMLAB/wiki/[0,-2)],axis=1)
points = np.append(points, [[1,1.5](/eiichiromomma/CVMLAB/wiki/[1,1.5)],axis=1)
points = np.float32(points)
elipse = cv.fitEllipse(points)

で通った。

elipse
((-0.3513513505458832, 0.0810810774564743),
 (3.269087791442871, 4.394386291503906),
 170.78253173828125)

てな具合で(x0, y0, a, b, theta)が返ってきた。

中身はこんな具合。

In [26]: points
Out[26]: 
array([[[-2. ,  0. ],
        [-1. , -2. ],
        [ 1. , -1. ],
        [ 0. , -2. ],
        [ 1. ,  1.5]]], dtype='float32')

In [27]: points.shape
Out[27]: (1, 5, 2)

便利そうな関数

cvFastArctan

定義

float cvFastArctan( float y, float x );

概要

arctan(y/x)を高速に算出するらしい。恐らく内部テーブル。 返り値は0~360で精度は0.1度。degree形式

cvCartToPolar

定義

void cvCartToPolar( const CvArr* x, const CvArr* y, CvArr* magnitude,
                    CvArr* angle=NULL, int angle_in_degrees=0 );

概要

x行列とy行列の各成分についてmagnitude(I)=sqrt( x(I)^2^+y(I)^2^ ),angle(I)=atan( y(I)/x(I) ) を計算してmagnitude行列とangle行列に返すらしい。cvDFTのパワー出力はこっちで演算すべきところ。 angleは要らなければNULLで良い。angle_in_degrees=0ならラジアン、1ならdegreeで0から360の0.1精度。

cvGetTickCount

定義

int64 cvGetTickCount( void );

概要

ticsを返す。 cvGetTickFrequency( void )と組合せて大まかな実時間計測が出来る。cvGetTickFrequencyが返すのはusあたりのTick数。

開始時に

int64 starttick=cvGetTickCount();

として終了時に

printf("%lfms\n",(cvGetTickCount()-startTicks)/cvGetTickFrequency()/1000.0);

とすれば実行時間が表示できる。

cvEqualizeHist

定義

void  cvEqualizeHist( const CvArr* src, CvArr* dst );

概要

ヒストグラムの均等化。画像が暗くてコントラストが緩い場合に使う。 あくまでも表示用と考えた方が無難。