opencv.findContours() による 画像の境界(輪郭)探索 - end0tknr's kipple - 新web写経開発
↑このエントリのおまけ、というか、記載漏れ
#!/usr/local/bin/python # -*- coding: utf-8 -*- from PIL import Image import cv2 from datetime import datetime import matplotlib matplotlib.use('Agg') import matplotlib.pylab as plb import numpy as np import sys def main(): org_file = sys.argv[1] img_org = cv2.imread(org_file) # グレースケール化 img_tmp = cv2.cvtColor(img_org, cv2.COLOR_BGR2GRAY) # 2値化 # - cv2.findContours()は、黒と背景、白を物体として判定する為 # cv2.THRESH_BINARY_INV で 2値化し、ネガポジ反転 # - cv2.THRESH_BINARY は単なる2値化 ret, img_tmp = cv2.threshold(img_tmp, 250, # 閾値 256, # 画素値の最大値 cv2.THRESH_BINARY_INV) # 2値化type time_str = datetime.now().strftime("%Y%m%d_%H%M%S") tmp_file = 'tmp_' + time_str + '.png' cv2.imwrite(tmp_file, img_tmp) # 境界線探索 # - 第2引数: # - cv2.RETR_EXTERNAL は最外周のみ探索 # - cv2.RETR_TREE は全境界(輪郭? 等高線?)を探索 # - 返り値: # - contours : 探索された境界 # - hierarchy: 境界が複数ある場合の階層 ret, contours, hierarchy = cv2.findContours(img_tmp, cv2.RETR_EXTERNAL, # cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE ) # cv2.CHAIN_APPROX_NONE ) i = 0 for contour in contours: # B G R color = \ ( 0, 0,255) if i % 6 == 0 else \ ( 0,255, 0) if i % 6 == 1 else \ (255, 0, 0) if i % 6 == 2 else \ ( 0,255,255) if i % 6 == 3 else \ (255,255, 0) if i % 6 == 4 else (255, 0,255) # 境界の描画 ( img_org データに contours データをマージ ) cv2.drawContours(img_org, contours, i, # 表示する輪郭. 全表示は-1 color, 2) # 等高線の太さ area = cv2.contourArea(contours[i]) arclen = cv2.arcLength(np.array(contours[i]), True) # 対象領域が閉曲線の場合、True print "AREA=" + str(area) + "\tARC_LEN=" + str(arclen) i += 1 if i > 3: break new_file = 'new_' + time_str + '.png' cv2.imwrite(new_file, img_org) if __name__ == '__main__': main()
↑こう書くと↓こう変換され、また、算出されます
$ python foo.py 42_2.jpg AREA=84122.0 ARC_LEN=1304.79393649 AREA=377.0 ARC_LEN=72.284270525 AREA=13.0 ARC_LEN=41.3137083054