end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

opencv.contourArea() と arcLength() で領域の面積と周囲の長さを算出

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()

↑こう書くと↓こう変換され、また、算出されます

f:id:end0tknr:20120723195236j:plain:w350

f:id:end0tknr:20171104233709p:plain:w270 f:id:end0tknr:20171104233712p:plain:w270

$ 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