下記のコードは動画から特定色を検出し、その検出した特定色の一番面積の大きいところを四角で描画するものです。
このコードを指定した面積のみ特定色を取り出せるように変更したいのですが、どのようにコードを書けばよいでしょうか。
import cv2 import numpy as np def find_rect_of_target_color(image): hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV_FULL) h = hsv[:, :, 0] s = hsv[:, :, 1] v = hsv[:, :, 2] mask = np.zeros(h.shape, dtype=np.uint8) mask[(h > 240) & ((100 < s) & (s < 200)) & (v > 180)] = 255 mask, contours, hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) rects = [] for contour in contours: approx = cv2.convexHull(contour) rect = cv2.boundingRect(approx) rects.append(np.array(rect)) return rects capture = cv2.VideoCapture(0) while cv2.waitKey(30) < 0: _, frame = capture.read() rects = find_rect_of_target_color(frame) if len(rects) > 0: rect = max(rects, key=(lambda x: x[2] * x[3])) cv2.rectangle(frame, tuple(rect[0:2]), tuple(rect[0:2] + rect[2:4]), (0, 0, 255), thickness=2) cv2.imshow('red', frame) capture.release() cv2.destroyAllWindows()
・試したコード
import cv2 import numpy as np def find_rect_of_target_color(image): hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV_FULL) h = hsv[:, :, 0] s = hsv[:, :, 1] v = hsv[:, :, 2] mask = np.zeros(h.shape, dtype=np.uint8) mask[(h > 240) & ((100 < s) & (s < 200)) & (v > 180)] = 255 mask, contours, hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) rects = [] for contour in contours: approx = cv2.convexHull(contour) rect = cv2.boundingRect(approx) rects.append(np.array(rect)) return rects capture = cv2.VideoCapture(0) while cv2.waitKey(30) < 0: _, frame = capture.read() rects = find_rect_of_target_color(frame) for x, y, w, h in rects: area = w * h if area < 100: continue elif area >500: continue cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), thickness=2) cv2.imshow('red', frame) capture.release() cv2.destroyAllWindows()
・面積
-*- coding: utf-8 -*- import cv2 import numpy as np img = cv2.imread("/home/pi/picture/alarm9-1.png") hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV_FULL) h, s, v = cv2.split(hsv) mask = np.zeros_like(h) mask[(h > 240) & ((100 < s) & (s < 200)) & (v > 180)] = 255 # 輪郭を抽出する。 mask, contours, hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 各輪郭の面積を出力する。(デバッグ用) print(list(map(cv2.contourArea, contours))) cv2.waitKey(0) cv2.destroyAllWindows()
・出力結果
[1.5, 0.0, 0.0, 3.0, 2.5, 0.0, 0.5, 7.5, 49.0, 12.5, 0.0, 3.5, 0.0, 0.0, 0.0, 0.0, 4.5, 0.0, 0.0, 3.5, 19.0, 0.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.5, 0.0, 0.5, 1.0, 3.5, 5052.0, 8.5, 5.5, 2.0, 4.0, 4.0, 15.0, 25.5, 2.0, 8.5, 26.0, 5.5, 18.5, 2.0, 4.0, 44.5, 13.5, 33.0, 2.0, 2.0, 22.5, 7.0, 6.0, 5.5, 4.0, 14.5, 8.5, 2.0, 4.0, 2.0, 831.5, 4.5, 0.0, 0.0, 2.0, 4.0, 10.0, 6.0, 2.0, 6.0, 9.5, 2.0, 2.0, 17.0, 14.0, 12.0, 4.0, 2.0, 61.5, 4.0, 4.0, 23.0, 14.5, 4.0, 2.0, 11.5, 2.0, 2.0, 7.5, 43.5, 4.0, 13.0, 4.0, 2.0, 11.0, 4.0, 2.0, 6.0, 4.0, 2.0, 5.5, 6.0, 11.5]
回答4件
あなたの回答
tips
プレビュー