cv2.drawContours

1.1等高線とは
等高線は、同じ色またはグレースケールの連続した点(境界に接続されている)で接続された曲線と単純に見なすことができます。輪郭は、形状分析やオブジェクトの検出と認識に役立ちます。

  • 正確さのために、バイナリイメージが使用されます。しきい値処理またはキャニー境界検出を実行する必要があります。
  • 輪郭を見つける機能は、元の画像を変更します。後で元の画像を引き続き使用する場合は、元の画像を他の変数に保存する必要があります。
  • OpenCVでは、輪郭を見つけることは、黒い背景にある超白いオブジェクトのようなものです。探しているオブジェクトは白で、背景は黒である必要があることを覚えておく必要があります。
    バイナリ画像で輪郭を見つける方法。
    関数cv2.findContours()には3つのパラメーターがあり、1つ目は入力画像、2つ目は輪郭検索モード、3つ目は輪郭近似法です。3つの戻り値があり、1つ目は画像、2つ目は輪郭、3つ目は(輪郭)断層撮影構造です。輪郭(2番目の戻り値)は、画像内のすべての輪郭が格納されているPythonリストです。各等高線は、オブジェクトの境界点(x、y)の座標を含むNumpy配列です。
    1.2等高線の描画方法
    関数cv2.drawContours()を使用して等高線を描画できます。指定した境界点に応じて任意の形状を描くことができます。最初のパラメーターは元の画像、2番目のパラメーターは等高線(Pythonリスト)、3番目のパラメーターは等高線のインデックスです(-1に設定すると、すべての等高線が描画されます)。次のパラメータは、アウトラインの色と太さです。
    1つの画像にすべての輪郭を描きます。
import numpy as np
import cv2

img = cv2.imread('1024.jpg')
imgray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255,0)
image ,contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#绘制独立轮廓,如第四个轮廓
#imag = cv2.drawContour(img,contours,-1,(0,255,0),3)
#但是大多数时候,下面方法更有用
imag = cv2.drawContours(img,contours,3,(0,255,0),3)

while(1):
    cv2.imshow('img',img)
    cv2.imshow('imgray',imgray)
    cv2.imshow('image',image)
    cv2.imshow('imag',imag)
    if cv2.waitKey(1) == ord('q'):
        break
cv2.destroyAllWindows()

1.3
輪郭の近似方法前述のように、輪郭は同じグレー値を持つ形状の境界であり、形状の境界上のすべての(x、y)座標を格納します。実際、すべての点が必要なわけではありません。直線が必要な場合は、2つの端点を見つけるだけです。cv2.CHAIN_APPROX_SIMPLEを実装できます。輪郭上の冗長なポイントを削除し、輪郭を圧縮することで、メモリコストを節約します。
マトリックスを使用してデモンストレーションを行い、等高線リストの各座標に青い円を描きましょう。1つ目は合計734ポイントのcv2.CHAIN_APPROX_NONEを使用した効果を示し、2つ目は4ポイントしかないcv2.CHAIN_APPROX_SIMPLEを使用した結果です。

2.輪郭の特徴
2.1モーメント
画像のモーメントは、画像の重心と面積を計算するのに役立ちます。
関数cv2.moments()は、計算されたモーメントを辞書の形式で返します。

import numpy as np
import cv2

img = cv2.imread('1024.jpg',0)
ret,thresh = cv2.threshold(img,127,255,0)
image,contours,hierarchy=cv2.findContours(thresh,1,2)
cnt=contours[0]
M=cv2.moments(cnt)
print(M)

これらのモーメントの値に基づいて、オブジェクトの重心を計算できます:

cx=int(M['m10']/M['m00'])
cy=int(M['m01']/M['m00'])

2.2等高線面積
は、関数cv2.contourArea()、またはモーメント(0次モーメント)M ['m00']を使用して計算できます。

area=cv2.contourArea(cnt)

2.3輪郭の円周
は、弧長とも呼ばれます。これは、関数cv2.arcLength()を使用して計算できます。この関数の2番目のパラメーターを使用して、オブジェクトの形状を閉じる(True)か開く(曲線)かを指定できます。

perimeter = cv2.arcLength(cnt,True)

2.4輪郭の近似
輪郭形状を、より少ない点で構成される別の輪郭形状に近似します。新しい輪郭の点の数は、設定した精度によって決まります。使用するダグラス-ピューカーアルゴリズムは、自分でGoogleで検索できます。
画像内で長方形を見つけたいが、画像のさまざまな理由により、完全な長方形を取得できず、「悪い形状」を取得するとします。これで、この関数を使用してこの形状を近似できます。2番目のパラメータはイプシロンです。 、これは元の輪郭からおおよその輪郭までの最大距離であり、精度パラメータです。

epsilon=0.1*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)

2.5凸包凸包
は輪郭に似ていますが、異なる場合がありますが、同じ結果が得られる場合があります。関数cv2.convexHull()を使用して、曲線に凸包の欠陥があるかどうかを検出し、欠陥を修正できます。一般的に言えば、凸曲線は常に凸であり、少なくとも平坦です。くぼみがある場合、それは凸状欠陥と呼ばれます。たとえば、下の図の手では、赤い曲線は手の凸包を示しており、凸包は二重矢印でマークされています。

hull = cv2.convexHull(points,hull,clockwise,returnPoints)

パラメータ:

  • 渡したい輪郭をポイントします
  • 船体出力、通常は必要ありません
  • 時計回りの方向フラ​​グ。Trueに設定されている場合、出力凸包は時計回りです。それ以外の場合は、反時計回りです。
  • returnPointsのデフォルト値はTrueです。凸包上の点の座標を返します。Falseに設定すると、凸包の点に対応する輪郭上の点を返します。
    上図の凸包を取得するには、次のコマンドを使用できます。
hull=cv2.convexHull(cnt)

ただし、凸状の欠陥を取得する場合は、returnPointsをFalseに設定する必要があります。上記の長方形を例にとると、最初にcntから彼の輪郭を見つけます。ここで、returnPointsをTrueに設定して凸包を見つけます。得られるのは、長方形の4つのコーナーポイントです。returnPointsをFalseに設定して、等高線ポイントのインデックスを取得します。
2.6
凸性の検出関数cv2.isContourConvex()は、曲線が凸状であるかどうかを検出できます。TrueまたはFalseのみを返すことができます。

k=cv2.isContourConvex(cnt)

2.7
外接長方形直線の外接長方形、回転のない真っ直ぐな長方形。オブジェクトが回転しているかどうかは考慮されません。したがって、外接する長方形の面積は最小ではありません。関数cv2.boundingRect()を使用して検索できます

#(x,y)为矩形左上角的坐标,(w,h)是矩形的宽和高
x,y,w,h=cv2.boundingRect(cnt)
img=cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)

回転する外接する四角形。この外接する四角形は、オブジェクトの回転を考慮しているため、面積が最小になります。関数cv2.minAreaRect()を使用します。返されるのはBox2D構造で、長方形の上隅の座標(x、y)と、長方形の幅と高さ(w、h)、および回転角が含まれています。ただし、この長方形を描画するには、長方形の4つのコーナーポイントが必要です。これは、関数cv2.boxPoints()によって取得できます。
緑は真っ直ぐな長方形、赤は回転する長方形です。

2.8最小外接円
関数cv2.minEncloseingCircle()は、オブジェクトの外接円を見つけるのに役立ちます。これは、オブジェクトを含めることができる円の最小領域です。

(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
img = cv2.circle(img,center,radius,(0,255,0),2)

2.9楕円のフィッティング
関数cv2.ellipse()を使用すると、戻り値は実際には回転する外接長方形の内接円になります。

ellipse = cv2.fitEllipse(cnt)
img = cv2.ellipse(img,ellipse,(0,255,0),2)

2.10直線フィッティング
一連の点に応じて直線をフィッティングできます。また、画像の白い点に直線をフィッティングすることもできます。

rows,cols = img.shape[:2]
[vx,vy,x,y]=cv2.fitLine(cnt,cv2.DIST_L2,0,0.01,0.01)
lefty=int((x*vy/vx)+y)
righty=int(((cols-x)*vy/vx)+y)
img = cv2.line(img,(cols-1,righty),(0,lefty),(0,255,0),2)

 

 

Matlab、Python、C ++でプログラミング、機械学習、コンピュータービジョン理論の実装とガイダンス、学部と修士の両方の学位、塩漬け魚の取引、専門家の回答を知ってください。QQ番号757160542に連絡してください。

 

おすすめ

転載: blog.csdn.net/weixin_36670529/article/details/113927254