- 概要
- 関連記事
- 輪郭抽出する
- 輪郭の特徴
- 輪郭の面積 – cv2.contourArea
- 輪郭の点の数
- 輪郭の周囲の長さ – cv2.arcLength
- 輪郭の重心 – cv2.moments
- 輪郭に外接する長方形 – cv2.boundingRect
- 輪郭に外接する回転した長方形 – cv2.minAreaRect
- 輪郭に外接する円 – cv2.minEnclosingCircle
- 輪郭に外接する三角形 – cv2.minEnclosingTriangle
- 輪郭に外接する楕円 – cv2.fitEllipse
- 輪郭に対して直線フィッティング – cv2.fitLine
- 輪郭の凸包 – cv2.convexHull
- 輪郭が凸包かどうか – cv2.isContourConvex
- 輪郭を少ない点で近似する – cv2.approxPolyDP
概要
OpenCV の findContours() で抽出した輪郭に対して行える処理をまとめました。
関連記事
findContours() の使い方については以下の記事を参考にしてください。
OpenCV – findContours で画像から輪郭を抽出する方法 – pystyle
輪郭抽出する
サンプルとして以下の画像を使用します。


輪郭の特徴
findContours() で抽出された複数の輪郭から抽出対象の輪郭を選択するために、輪郭の点の数や面積といった情報を利用します。
コード | |
---|---|
面積 | cv2.contourArea |
点の数 | len |
輪郭の周囲の長さ | cv2.arcLength |
輪郭のモーメント | cv2.moments |
輪郭に外接する長方形 | cv2.boundingRect |
輪郭に外接する回転した長方形 | cv2.minAreaRect |
輪郭に外接する円 | cv2.minEnclosingCircle |
輪郭に外接する三角形 | cv2.minEnclosingTriangle |
輪郭に外接する楕円 | cv2.fitEllipse |
輪郭に対して直線フィッティング | cv2.fitLine |
輪郭の凸包 | cv2.convexHull |
輪郭が凸包かどうか | cv2.isContourConvex |
輪郭を少ない点で近似する | cv2.approxPolyDP |
輪郭の面積 – cv2.contourArea
cv2.contourArea() で輪郭の面積を計算できます。
- 引数
- contour: 形状が
(NumPoints, 1, 2)
の numpy 配列。輪郭。 - oriented: True の場合、輪郭の点の順序が反時計回りの場合は正、時計回りの場合は負の値を返す。False の場合はいずれも正の値を返す。
- contour: 形状が
- 返り値
- points: 輪郭の面積
contour: 0, area: 4900.0 contour: 1, area: 3362.0 contour: 2, area: 10743.0 contour: 3, area: 3784.0 contour: 4, area: 1923.0
面積が閾値未満の輪郭の削除する
list(filter(lambda x: cv2.contourArea(x) > 閾値, contours))
で面積が閾値以上の輪郭のみ残せます。
面積が最大の輪郭を取得する
max(contours, key=lambda x: cv2.contourArea(x))
で面積が最大の輪郭を取得できます。
輪郭の点の数
len()
で輪郭を構成する点の数を取得できます。
contour: 0, number of points: 4 contour: 1, number of points: 165 contour: 2, number of points: 171 contour: 3, number of points: 6 contour: 4, number of points: 10
点の数で図形の種類を判定する
点の数で図形の種類を判定する場合、判定前に輪郭をより少ない数の点で構成される輪郭で近似したほうがよいでしょう。


輪郭の周囲の長さ – cv2.arcLength
cv2.arcLength() で輪郭の周囲の長さを計算できます。
- 引数
- curve: (NumPoints, 1, 2) の numpy 配列。輪郭。
- closed: 輪郭が閉じているかどうか
- 返り値
- retval: 輪郭の長さ
contour: 0, arc length: 280.00 contour: 1, arc length: 279.97 contour: 2, arc length: 387.50 contour: 3, arc length: 245.24 contour: 4, arc length: 209.68
輪郭の重心 – cv2.moments
cv2.moments() で輪郭のモーメントを計算できます。モーメントから輪郭の重心を計算できます。
contour: 0, centroid: (60.00, 286.00) contour: 1, centroid: (327.25, 274.33) contour: 2, centroid: (202.01, 224.00) contour: 3, centroid: (299.50, 139.00) contour: 4, centroid: (215.34, 74.50)
輪郭に外接する長方形 – cv2.boundingRect
cv2.boundingRect() で輪郭に外接する長方形を計算できます。
- 引数
- points: (NumPoints, 1, 2) の numpy 配列。輪郭。
- 返り値
- retval: (左上の x 座標, 左上の y 座標, 幅, 高さ) であるタプル。輪郭に外接する長方形。
contour: 0, topleft: (25, 251), width: 71, height: 71 contour: 1, topleft: (286, 247), width: 83, height: 83 contour: 2, topleft: (144, 166), width: 118, height: 117 contour: 3, topleft: (256, 96), width: 88, height: 87 contour: 4, topleft: (182, 44), width: 63, height: 62

輪郭に外接する回転した長方形 – cv2.minAreaRect
cv2.minAreaRect() で輪郭に外接する回転した長方形を計算できます。
- 引数
- points: (NumPoints, 1, 2) の numpy 配列。輪郭。
- 返り値
- retval: ((中心の x 座標, 中心の y 座標), (長方形の幅, 長方形の高さ), 回転角度) であるタプル。回転した長方形の情報。
返り値は、回転した長方形の回転中心、大きさ、回転角度です。cv2.boxPoints() により、これを長方形の 4 点の座標に変換できます。
- 引数
- box: 回転した長方形の情報。
- points: 引数で結果を受け取る場合、指定する。
- 返り値
- points: (4, 2) の numpy 配列。回転した長方形の 4 点の座標。
contour: 0, center: (60.00, 286.00), width: 70.00, height: 70.00, angle: -90.00 contour: 1, center: (327.00, 288.00), width: 82.00, height: 82.00, angle: -90.00 contour: 2, center: (202.50, 224.00), width: 117.00, height: 116.00, angle: -0.00 contour: 3, center: (299.50, 139.00), width: 61.52, height: 61.52, angle: -45.00 contour: 4, center: (220.50, 74.50), width: 55.15, height: 55.15, angle: -45.00

輪郭に外接する円 – cv2.minEnclosingCircle
cv2.minEnclosingCircle() で輪郭に外接する円を計算できます。
- 引数
- points: (NumPoints, 1, 2) の numpy 配列。輪郭。
- 返り値
- center: 円の中心
- radius: 円の半径

輪郭に外接する三角形 – cv2.minEnclosingTriangle
cv2.minEnclosingTriangle() で輪郭に外接する三角形を取得できます。
- 引数
- points: (NumPoints, 1, 2) の numpy 配列。輪郭。
- triangle: 引数で結果を受け取る場合、指定する。
- 返り値
- retval: 三角形の面積
- triangle: (3, 1, 2) の numpy 配列。三角形の輪郭。

輪郭に外接する楕円 – cv2.fitEllipse
cv2.fitEllipse() で輪郭に外接する楕円を計算できます。外接する楕円の計算には、輪郭は最低 5 点以上で構成されている必要があります。
- 引数
- points: (NumPoints, 1, 2) の numpy 配列。輪郭。
- 返り値
- center: 楕円の中心
- length: 楕円の長軸、短軸の長さ
- angle: 楕円の回転角度

輪郭に対して直線フィッティング – cv2.fitLine
cv2.fitLine() で輪郭に対して直線フィッティングが行えます。
- 引数
- points: (NumPoints, 1, 2) の numpy 配列。輪郭。
- distType: 距離関数
- param: 距離関数の係数。0 の場合、自動で決める。
- reps: 半径の解像度。
- aeps: 角度の解像度。
- 返り値
- vx、vy: vy/vx が直線の傾き
- x0, y0: 直線が通る点
返り値から直線の式は次のように求められます。
y = 0.00/1.00(x - 60.00) + 286.00 y = 0.71/0.71(x - 327.25) + 287.75 y = 0.00/1.00(x - 203.02) + 224.00 y = 299.50 y = 0.00/1.00(x - 212.60) + 74.50

輪郭の凸包 – cv2.convexHull
cv2.convexHull() で輪郭の凸包を計算できます。
- 引数
- points: (NumPoints, 1, 2) の numpy 配列。輪郭
- hull: 輪郭に外接する凸包 (引数経由で受け取る場合)
- clockwise: 輪郭が時計回りかどうか
- returnPoints: 輪郭に外接する凸包を返すかどうか
- 返り値
- hull: (NumPoints, 1, 2) の numpy 配列。輪郭に外接する凸包

輪郭が凸包かどうか – cv2.isContourConvex
cv2.isContourConvex() で輪郭が凸包かどうかを判定できます。
- 引数
- contour: (NumPoints, 1, 2) の numpy 配列。輪郭。
- 返り値
- retval: 輪郭が凸多角形の場合は True、そうでない場合は False を返す。
contour: 0, is_convex: True contour: 1, is_convex: False contour: 2, is_convex: False contour: 3, is_convex: True contour: 4, is_convex: False

No1, 2 の図形は凸多角形であるが、結果は False となっています。 このように、輪郭検出した点は凸多角形になっていない場合があります。
輪郭を少ない点で近似する – cv2.approxPolyDP
cv2.approxPolyDP() で曲線など多数の点で構成される輪郭をより少ない点で近似できます。 処理は、Ramer-Douglas-Peucker アルゴリズム に従います。
- 引数
- curve: (NumPoints, 1, 2) の numpy 配列。輪郭
- epsilon: アルゴリズムで使用する許容距離
- closed: 輪郭が閉じているかどうか
- approxCurve: 引数で結果を受け取る場合、指定する。
- 返り値
- approxCurve: 近似した輪郭
引数の epsilon は、通常、輪郭の周囲の長さ * ratio
を使用します。ratio を大きい値にするほど点の数は削減できますが、近似の精度が大雑把になります。逆に小さい値にするほど近似の精度がよくなりますが、点の数があまり削減できません。
contour 0: before: 4, after: 4 contour 1: before: 165, after: 3 contour 2: before: 171, after: 16 contour 3: before: 6, after: 4 contour 4: before: 10, after: 7

ratio による近似精度の変化
ratio を変えることで次の sin 曲線の近似がどう変化するか確認します。ratio
を大きくするほど荒く近似されることがわかります。
eps: 0.76, number of points; 4 eps: 0.08, number of points; 8 eps: 0.01, number of points; 18

コメント