Open electronicsdiy opened 3 years ago
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)): im_con = im.copy() im_con = cv2.drawContours(im_con, contours, i, (255, 191, 0), 10) # dep skyblue RGB(0, 191, 255) #検出したパーツが、画面全体に占める面積比を求める #この画像ファイルを真っ黒にしたnumpy.array行列オブジェクトを作成 im_con2 = im.copy() img_gray = cv2.cvtColor(im_con2, cv2.COLOR_BGR2GRAY) this_image_file_size_all_element_zero_image = np.zeros_like(img_gray) #https://code-graffiti.com/opencv-contour-detection-in-python/ #第5引数で輪郭線の太さを指定。-1を指定すると塗りつぶしになる。色はスカラー0で黒((0,0,0)と同義)、255で白((255,255,255)と同義) cv2.drawContours(this_image_file_size_all_element_zero_image, contours, i, color=255, thickness=-1) # 白黒割合の確認 image_size = this_image_file_size_all_element_zero_image.size #画面全体の面積 white_pixels = cv2.countNonZero(this_image_file_size_all_element_zero_image) #すぐ上のdarwCounterでパーツ領域だけ白で塗りつぶされている。NonZeroの値が、その白い画素部分 black_pixels = int(this_image_file_size_all_element_zero_image.size)-int(white_pixels) #cv2.countZeroメソッドがないので、全体から白領域を引いて黒領域の面積を得る area_percentage = (white_pixels/image_size)*100 # 小数点第2位まで出力 area_percentage_str = format(area_percentage, '.2f') message0 = "ID : {0} , Area {1}%".format(i, area_percentage_str) message1 = "Area {0} of All Area {1}".format(cv2.contourArea(contours[i]), image_size) print(message0) print(message1+"\n") if cv2.contourArea(contours[i]) >= 100: cv2.putText(im_con, str(message0), (0, 50), cv2.FONT_HERSHEY_TRIPLEX, 1, (0, 0, 255), 1, cv2.LINE_AA) cv2.putText(im_con, str(message1), (0, 80), cv2.FONT_HERSHEY_TRIPLEX, 1, (0, 0, 255), 1, cv2.LINE_AA) cv2.imwrite('result_' + img_file + str(i) + '.png', im_con) cv2.putText(this_image_file_size_all_element_zero_image, str(message0), (0, 50), cv2.FONT_HERSHEY_TRIPLEX, 1, 255, 1, cv2.LINE_AA) cv2.putText(this_image_file_size_all_element_zero_image, str(message1), (0, 80), cv2.FONT_HERSHEY_TRIPLEX, 1, 255, 1, cv2.LINE_AA) cv2.imwrite('result_black_and_white_' + img_file + str(i) + '.png', this_image_file_size_all_element_zero_image) else: pass # 検出されたすべての輪郭を画像に書き込んでファイル出力 im_new = cv2.imread(img_file) #im_conには、ループ処理の最終回でcv2.putTextで書き込んだ内容が残っている。新しいイメージオブジェクトを取得。 all_counours_engraved_img = cv2.drawContours(im_new, contours, -1, (0, 250, 154), 3) #cv2.imwrite('detected_all_the_contours_result' + img_file + '.png', all_counours_engraved_img) #この画像ファイルを真っ黒にしたnumpy.array行列オブジェクトを作成 im_con3 = im_new.copy() img_gray2 = cv2.cvtColor(im_con3, cv2.COLOR_BGR2GRAY) all_element_zero_image = np.zeros_like(img_gray2) #第5引数で輪郭線の太さを指定。-1を指定すると塗りつぶしになる。色はスカラー0で黒((0,0,0)と同義)、255で白((255,255,255)と同義) cv2.drawContours(all_element_zero_image, contours, -1, color=255, thickness=-1) # 白黒割合の確認 image_size = this_image_file_size_all_element_zero_image.size #画面全体の面積 white_pixels2 = cv2.countNonZero(all_element_zero_image) #すぐ上のdarwCounterでパーツ領域だけ白で塗りつぶされている。NonZeroの値が、その白い画素部分 black_pixels = int(all_element_zero_image.size)-int(white_pixels2) #cv2.countZeroメソッドがないので、全体から白領域を引いて黒領域の面積を得る all_area_percentage = (white_pixels2/image_size)*100 # 小数点第2位まで出力 all_area_percentage_str = format(all_area_percentage, '.2f') message2 = "ID : NA , Area {0}%".format(all_area_percentage_str) message3 = "Area {0} of All Area {1}".format(white_pixels2, image_size) print(message2) print(message3+"\n") # 原画像(カラー色)に検出されたすべてのパーツの輪郭と面積比率を記入した画像 cv2.putText(im_con3, str(message2), (0, 50), cv2.FONT_HERSHEY_TRIPLEX, 1, (0, 0, 255), 1, cv2.LINE_AA) cv2.putText(im_con3, str(message3), (0, 80), cv2.FONT_HERSHEY_TRIPLEX, 1, (0, 0, 255), 1, cv2.LINE_AA) cv2.imwrite('All_detected_parts_' + img_file + '.png', im_con3) # 上記を白黒にした画像 cv2.putText(all_element_zero_image, str(message2), (0, 50), cv2.FONT_HERSHEY_TRIPLEX, 1, 255, 1, cv2.LINE_AA) cv2.putText(all_element_zero_image, str(message3), (0, 80), cv2.FONT_HERSHEY_TRIPLEX, 1, 255, 1, cv2.LINE_AA) cv2.imwrite('All_detected_parts_black_and_white_' + img_file + '.png', all_element_zero_image)
Reference website
Output
Code