0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

OpenCV2で佐々木希の顔パーツのpixel面積を計算してみた

Last updated at Posted at 2021-08-13

参考にしたサイト

以下のウェブサイトに掲載されているコードを骨子として、スクリプトファイルを書き起こしてみました。

作成したスクリプト・ファイルの機能をまとめました。
コードの全文は、この記事の最後に掲載しています。

  • 画像ファイルをコマンドライン引数で受け取る
  • 何も出力されないか、かろうじて視認できる点しか書き込まれないものが大量に吐かれるので、面積が100ピクセル以上のものだけ、検出した輪郭を青線で元の画像に書き込んで、1輪郭1ファイル出力する
  • 左上に領域ID番号と面積(pixel単位)を書き込む
  • 面積が100未満の領域の輪郭を含めて、検出されたすべての領域の輪郭detected_all_the_contours_result.pngにすべてまとめて出力する

実行結果

Terminal
% python3 object_area_calc.py --file_name nozomi_1.jpg > nozomi_1_area_calc_result.txt
% wc -l nozomi_1_area_calc_result.txt                                                 
     345 nozomi_1_area_calc_result.txt
%
Terminal
% open detected_all_the_contours_resultnozomi_1.jpg.png 

Terminal
% open resultnozomi_1.jpg133.png

Terminal
% open resultnozomi_1.jpg93.png

Terminal
% head -50 nozomi_1_area_calc_result.txt
ID 0 Area 0.0
ID 1 Area 0.0
ID 2 Area 0.0
ID 3 Area 5.5
ID 4 Area 5.5
ID 5 Area 2.0
ID 6 Area 4.0
ID 7 Area 5.5
ID 8 Area 7.5
ID 9 Area 7.5
ID 10 Area 5.5
ID 11 Area 4.0
ID 12 Area 16.5
ID 13 Area 2.0
ID 14 Area 13.5
ID 15 Area 6.0
ID 16 Area 2.0
ID 17 Area 4.0
ID 18 Area 10.0
ID 19 Area 2.0
ID 20 Area 2.0
ID 21 Area 0.0
ID 22 Area 8.5
ID 23 Area 8.5
ID 24 Area 0.0
ID 25 Area 0.0
ID 26 Area 7.0
ID 27 Area 0.0
ID 28 Area 0.0
ID 29 Area 2.0
ID 30 Area 2.0
ID 31 Area 11.0
ID 32 Area 2.0
ID 33 Area 0.0
ID 34 Area 69.5
ID 35 Area 2.0
ID 36 Area 6.0
ID 37 Area 4.0
ID 38 Area 7.0
ID 39 Area 2.0
ID 40 Area 4.0
ID 41 Area 2.0
ID 42 Area 2.0
ID 43 Area 2.5
ID 44 Area 4.0
ID 45 Area 2.0
ID 46 Area 4.0
ID 47 Area 4.0
ID 48 Area 7.5
ID 49 Area 2.0
%

ID 344が大きな面積を占めている

Terminal
% tail nozomi_1_area_calc_result.txt
ID 335 Area 2.0
ID 336 Area 2.0
ID 337 Area 2.0
ID 338 Area 4.0
ID 339 Area 2.0
ID 340 Area 6.0
ID 341 Area 4.0
ID 342 Area 2.0
ID 343 Area 0.0
ID 344 Area 76917.5
%
Terminal
% open resultnozomi_1.jpg344.png   

スクリプトファイルに起こしたコード

object_area_calc.py
import cv2

from typing import Tuple, Optional
import os
import cv2
import numpy as np
import cv2
import argparse

# 動画ファイル名をコマンドライン引数から受け取る
parser = argparse.ArgumentParser(description='')    #
parser.add_argument('--file_name')
args = parser.parse_args()

img_file = args.file_name

im = cv2.imread(img_file)
im_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
retval, im_bw = cv2.threshold(im_gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

# 輪郭の検出
contours, hierarchy = cv2.findContours(im_bw, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

# 輪郭を1つずつ書き込んで出力
# 何も出力されないか、かろうじて視認できる点しか書き込まれないものは、画像に出力しない
# 面積が100ピクセル以上のものみ、青色で輪郭を1件ずつ個別のファイルに出力。
# 検出されたすべての面積は、その輪郭のいかんによらず、detected_all_the_contours_resultにすべてまとめて出力する。
for i in range(len(contours)):
	print('ID', i, 'Area', cv2.contourArea(contours[i]))
	if cv2.contourArea(contours[i]) >= 100:
		im_con = im.copy()
		im_con = cv2.drawContours(im_con, contours, i, (255, 191, 0), 10) # dep skyblue RGB(0, 191, 255)
		message =  "ID, {0} :  Area {1}".format(i, cv2.contourArea(contours[i]))
		cv2.putText(im_con, str(message),  (0, 50), cv2.FONT_HERSHEY_TRIPLEX, 1, (0, 0, 255), 1, cv2.LINE_AA)
		cv2.imwrite('result' + img_file + str(i) + '.png', im_con)
	else:
		pass 

# 検出されたすべての輪郭を画像に書き込んでファイル出力
all_counours_engraved_img = cv2.drawContours(im_con, contours, -1, (0, 250, 154), 3)
cv2.imwrite('detected_all_the_contours_result' + img_file + '.png', all_counours_engraved_img)

以下の記事につづく・・・

( 追記 )

ラムダ式を使って面積を降順ソートしたり、一番大きな面積のパーツを探したりすると便利。

面積が大きい順に並べる(降順ソート)

( 参考 )

import cv2
import numpy as np

img = cv2.imread("test.png", cv2.IMREAD_GRAYSCALE)

#輪郭の抽出
contours, hierarchy = cv2.findContours(img,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

#面積の降順にソート
contours.sort(key=lambda x: cv2.contourArea(x), reverse=True)

out = np.zeros_like(img)
cv2.drawContours(out, [contours[0]], -1, color=255, thickness=-1)
cv2.drawContours(out, [contours[1]], -1, color=128, thickness=-1)
cv2.drawContours(out, [contours[2]], -1, color=64, thickness=-1)

面積が一番大きい領域を調べる

( 参考 )

max_contour = max(contours, key=lambda x: cv2.contourArea(x))
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?