形態と関連コンポーネントの実践


検出コイン


不均一照明で撮影した画像では,臨界化演算を用いてコイン領域のみを分離し,接続要素を生成する.

ソリューションとキーコードの説明

def findContours(img):
	kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))

	img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
	img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

	(contours, hierarchy) = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_L1)

	for i in range(0, len(contours)):
		cntr = sorted(contours, key=cv2.contourArea, reverse=True)[i]
		cv2.drawContours(img, [cntr], 0, (255, 255, 255), -1)

	seed(9001)
	for i in range(0, len(contours)):
		cntr = sorted(contours, key=cv2.contourArea, reverse=True)[i]
		r = randint(0, 256)
		g = randint(0, 256)
		b = randint(0, 256)
		cv2.drawContours(img, [cntr], 0, (b, g, r), 1)
	return img, contours
複数の前処理処理処理後に実行されるfindContours関数.まず、構造要素を生成します.サイズは(3,3).その後、トポロジのオープン演算を実行し、クローズ演算を適用します.cv2.findContoursセクションでは、「プロファイル検索」モードでは、接続要素の一番外側のプロファイルのみが抽出されます.RETR EXTERNALに設定し、輪郭近似方法は既存の値cv 2です.CHAIN APPROX SIMPLEではなくcv 2.CHAIN APPROX TC89 L1.その後、ソート関数を使用して生成される等高線はdrawContoursで表すことができます.このとき、内部を全て充填するために、厚み値はマイナス-1とした.
ap = argparse.ArgumentParser()
ap.add_argument('-i', '--image', required = True, \
			help = 'Path to the input image')
args = vars(ap.parse_args())

filename = args['image']
iでコイン画像のパスを入力します.受信した値はfilename変数に格納されます.
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
	gray = cv2.GaussianBlur(gray, (5, 5), 0)
	th = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 31, 1)
第1部ではfindContoursを呼び出す前に必要な前処理手順を示します.まず,カラー画像を階調画像に変換し,ここで(5,5)カーネルサイズのGaussブルーを行った.その後adaptiveThresholdを用いて適応臨界化を行った.適応法では,MEAN法とGAUSSIAN法の両方が試行錯誤した場合,MEANの性能がより良く,従ってパラメータ値に変換した.複数ブロックサイズを試したところ、31日時点で全ての硬貨が検出されたため、パラメータ値は31に設定されていた.ThresholdTypeはcv 2です.THRESH BINARY INVに設定します.

実行結果

  • python extract_coins.py --image ../images/coins.jpgを使用してコマンドを発行する場合

    BGRタイプのコイン画像を入力すると、Pyplotライブラリを使用して必要に応じて画面に結果を出力できます.
  • コード#コード#


    詳細コードはGithubで確認できます.

    移動オブジェクトの検出


    オブジェクトの色に関係のない色から動きを判断し、背景から移動するオブジェクトを検出し、接続要素を生成します.

    ソリューションとキーコードの説明

    def movingObjectsDetect(img):
        kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
    
        img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
        img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
    
        (contours, hierarchy) = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
        seed(9001)
        img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
        for (i, c) in enumerate(contours):
            r = randint(0, 256)
            g = randint(0, 256)
            b = randint(0, 256)
            cv2.drawContours(img, [c], 0, (b, g, r), -1)
    
        return img
    実習5の最初の実習と同じように、先生は構造要素になり、大きさは(3,3)です.その後、トポロジのオープン演算を実行し、クローズ演算を適用します.cv2.findContoursセクションでは、「プロファイル検索」モードでは、接続要素の一番外側のプロファイルのみが抽出されます.RETR EXTERNALに設定し、輪郭近似方法はcv 2です.CHAIN APPROX TC89 L1.その後、randomを使用してobjectごとに任意のr、g、b値を生成し、アウトラインを描画するためにランダムな色で塗りつぶします.
    ap = argparse.ArgumentParser()
    ap.add_argument("-v", "--video", required=False, \
                        help="path to the video file")
    args = vars(ap.parse_args())
    
    fvideo = args.get("video")
    vでビデオを受信するパス.受信した値はfvideo変数に格納されます.値が入力されていない場合は、Webページのタイトルを入力としてプログラムを実行します.
    model = cv2.createBackgroundSubtractorMOG2(varThreshold=100)
    
    while True:
        (retval, frame) = camera.read()
        fgmask  = model.apply(frame)
    バックグラウンドモデルを生成するためにcreateBackgroundSubtractorMoG 2関数を使用した.3つのパラメータ値を選択的に入れることができ、まずvarThreshold値のみを指定し、100に設定します.次に、生成されたバックグラウンドモデルを使用して、第1のセクションで説明したmovingObjectDetectの入力値として使用して、移動するオブジェクトを検出します.

    実行結果


  • python extract_moving_objects.py --video ../videos/vtest.コマンドがaviの場合

    ビデオを入力とすると,各オブジェクトがランダムな色で検出されていることが確認できる.

  • python extract_moving_objects.コマンドがpyの場合

    ネットカメラを入力値に設定して保温カップを揺らすと、保温カップに対応するオブジェクトが薄緑色に近い色であることが検出され、また、様々な色の人体や他の小さいオブジェクトも検出された.
  • コード#コード#


    詳細コードはGithubで確認できます.