opencv pythonのcv.estimatePolyDPを詳しく解説します

OpenCV Python では、cv.estimatePolyDP はポリゴン近似を行う関数です。Douglas-Peucker アルゴリズムを使用して、ポリゴンのポイントの数を減らします。

この関数は、入力ポリゴンと近似の精度を示すパラメーターの 2 つのパラメーターを受け取ります。入力ポリゴンは点の配列であり、estimate_accuracy は輪郭の近似を制御する精度パラメータです。

この関数は、入力ポリゴンの重要な角度を保持し、不要な頂点を削除することで、ポリゴンの生成に必要なポイントの数を減らします。画像処理における輪郭検出や解析に利用でき、ポリゴン点の数を減らすことで形状の検出・認識が容易になります。

以下は、OpenCV Python で cv.estimatePolyDP を使用してポリゴンを近似する方法を示す簡単な例です。

import cv2 as cv
import numpy as np

# 读取图像
img = cv.imread("polygon.jpg")

# 转换为灰度图像
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# 二值化图像
ret, thresh = cv.threshold(gray, 127, 255, cv.THRESH_BINARY)

# 找到轮廓
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

# 逼近多边形
approx = cv.approxPolyDP(contours[0], 0.01 * cv.arcLength(contours[0], True), True)

# 绘制轮廓和逼近多边形
cv.drawContours(img, [contours[0]], 0, (0, 255, 0), 2)
cv.drawContours(img, [approx], 0, (255, 0, 0), 2)

# 显示图像
cv.imshow("Image", img)
cv.waitKey(0)
cv.destroyAllWindows()

この例では、まず画像を読み取り、グレースケールに変換します。次に、cv.threshold を使用してそれを 2 値化画像に変換し、cv.findContours を使用してその輪郭を見つけます。次に、cv.estimatePolyDP を使用してポリゴンを近似します。最後に、cv.drawContours を使用して、元の輪郭と近似ポリゴンを画像上に描画します。

実際には、近似プロセスで最良の結果が得られるように、近似精度パラメータを適切な値で調整する必要があることに注意してください。

cv.estimatePolyDP 関数には、次の 3 つのパラメータがあります。

  • カーブ: 入力ポリゴンの輪郭。
  • ε: 近似精度パラメータ。近似精度の限界を示します。このパラメータは正の数で、値が小さいほど近似が高くなります。通常、このパラメータを計算するには輪郭周囲の特定の割合を使用することをお勧めします。一般的なスケーリング係数は 0.01 です。
  • Closed: 出力近似ポリゴンが閉じているかどうかを示すブール値パラメータ。ブール値が True の場合、出力ポリゴンは閉じられます。False の場合、線セグメントのみが返されます。

実際の使用では、近似精度を制御する機能を最大限に活用するために、特定のアプリケーション シナリオや画像条件に応じてイプシロンの値を調整する必要があります。

関数の戻り値は、cv.drawContours 関数を使用して画像上に描画できる近似多角形の出力点配列形式であることに注意してください。

cv.estimatePolyDP 関数はポリゴンの頂点座標の配列を返し、cv.contourArea 関数を使用してこれらの頂点座標に基づいてポリゴンの面積を計算できます。cv.contourArea 関数は閉じた輪郭の面積を計算するためにのみ使用できるため、閉じた多角形の輪郭を出力するために cv.estimatePolyDP 関数を呼び出すときは、closed パラメーターを True に設定する必要があることに注意してください。

具体的なコード実装方法は以下の通りです。

# 输入轮廓 contour,逼近精度 epsilon 和封闭参数 closed,返回逼近多边形的面积
def compute_approxPolyDP_area(contour, epsilon, closed=True):
    # 计算逼近多边形的顶点坐标
    approx = cv.approxPolyDP(contour, epsilon, closed)
    # 计算逼近多边形的面积
    area = cv.contourArea(approx)
    return area

このうち、入力パラメータ contour は入力輪郭の頂点座標配列、epsilon は近似精度パラメータ、closed は閉パラメータ、出力結果領域は近似多角形の領域です。

OpenCV の関数 cv2.minAreaRect および cv2.boxPoints を使用すると、輪郭で囲まれた最小の長方形枠を計算し、長方形枠の 4 つの頂点座標を取得できます。次に、Python の四角形操作ライブラリ Shapely を使用して、四角形と輪郭の交差する面積を計算できます。

具体的な手順は次のとおりです。

  1. cv2.findContours 関数を使用して、入力輪郭の頂点座標配列を取得します。
# img 为输入图像
contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
  1. cv2.minAreaRect 関数を使用して、輪郭で囲まれた最小の長方形ボックスとその 4 つの頂点の座標を計算します。
rect = cv2.minAreaRect(contours[0])  # 计算最小矩形框
box = cv2.boxPoints(rect)  # 得到矩形框的四个顶点坐标
box = np.int0(box)  # 转换为整型
  1. Shapely ライブラリを使用して、長方形と輪郭の交差面積を計算します。
from shapely.geometry import Polygon

# 计算矩形和轮廓交集的面积
intersection_area = 0
if len(contours) > 0:
    polygon = Polygon(contours[0].reshape(-1, 2))
    rect_polygon = Polygon(box.reshape(-1, 2))
    intersection = rect_polygon.intersection(polygon)
    if intersection.geom_type == 'Polygon':
        intersection_area = intersection.area

このうち、Polygon 関数はポリゴン オブジェクトを作成するために使用され、intersection 関数は 2 つのポリゴンの交差を計算するために使用されます。最後のintersection_area変数は、長方形と輪郭の交差部分の面積です。

完全なコードは次のとおりです。

import cv2
import numpy as np
from shapely.geometry import Polygon

# 读取输入图像
img = cv2.imread('input.jpg', 0)

# 计算轮廓
contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 计算最小矩形框
rect = cv2.minAreaRect(contours[0])
box = cv2.boxPoints(rect)
box = np.int0(box)

# 计算矩形和轮廓交集的面积
intersection_area = 0
if len(contours) > 0:
    polygon = Polygon(contours[0].reshape(-1, 2))
    rect_polygon = Polygon(box.reshape(-1, 2))
    intersection = rect_polygon.intersection(polygon)
    if intersection.geom_type == 'Polygon':
        intersection_area = intersection.area

# 输出交集面积
print("Intersection area:", intersection_area)

このうち、input.jpg は入力画像のファイル名で、他の画像に置き換えることができます。

OpenCVの関数cv2.boundingRectを使用して、多角形近似によって得られた輪郭の外接四角形を計算すると、得られる座標は最小の四角形の左上隅の座標と幅と高さになります。つまり、boundingRect によって取得される四角形は、多角形を含む最大の四角形ではなく、多角形を完全にカバーできる最小の四角形です。

簡単に言うと、boundingRectで得られる長方形枠は、ポリゴンが占有するスペースを最小限に抑えられる長方形枠です。実際のアプリケーションでは、通常、boundingRect 関数を使用して、後続のグラフィックス処理、オブジェクト認識、およびその他の操作のために多角形の境界ボックスを取得します。

Guess you like

Origin blog.csdn.net/qq_27487739/article/details/131320356