下記のコードはraspbery pi cameraで撮影した映像から特定色の部分を認識するコードです。
これについていくつかわからない部分があるので教えていただきたいです。
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] mask = np.zeros(h.shape, dtype=np.uint8) mask[(h > 240) & ((150 > s) & (s < 100))] = 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()
・その1
この部分のnp.zerosがわかりません。
調べたらh.shapeとdtype=np.unit8を指定して0で埋められた配列を返すとでました。しかし、0の配列を作るとどうなるのか、なぜ0にするのかがわかりません。そしてh.shapeは配列の型と調べたら出ましたが、具体的にどのような配列なのかがわかりません。
また,dtype=np.unit8についてもわからず、調べるとdtypeは出力配列の型でnp.unit=8は符号なしの8ビット整数型と出ましたが、00000000~11111111の範囲で表わすと言うことでしょうか。
mask = np.zeros(h.shape, dtype=np.uint8) mask[(h > 240) & ((150 > s) & (s < 100))] = 255 mask, contours, hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
・その2
この部分は確認に近いのですが、これはまずrectsの要素は0であり、cv2.findContoursでmask(入力画像)の赤い部分の輪郭を検出したものをcontourに入れて、cv2.convexHullとcv2.boundingRectで凹凸の凸部分を包み、その包状が入る最小の外接矩形を求めて、その要素をrectsに入れてそれを返すことで、要素がゼロであったrects=[]に要素を入れるということですか?
rects = [] for contour in contours: approx = cv2.convexHull(contour) rect = cv2.boundingRect(approx) rects.append(np.array(rect)) return rects
・その3
まず、rects = find_rect_of_target_color(frame)の分は映像(静止画像)であるframeをHSVに変換して、設定した値のところの輪郭を検出してその画像を囲む外接矩形を表示する処理を行う処理をしてrectsに入れているということでしょうか。
そして、このif len(rects) > 0:がよくわかりません。配列が0より大きいときにいかのそれ以降のコードが実行されるのかと考えましたが、それがあっていたとしてもどういうことなのかがよくわかりません。
また、 rect = max(rects, key=(lambda x: x[2] * x[3]))はrectsでいくつもの矩形のなかで一番大きいところだけを表示するようにしているのですか?
あと最後に cv2.rectangleのところで質問があり、長方形を描画と調べて出てきたのですが、この部分で初めて画像ないに長方形が表示されるのですか?輪郭を検出したり、矩形を表示したりいろいろ処理をしているのでわからなくなってしまいました。そしてこのコードでは入力画像はframeですがrects = find_rect_of_target_color(frame)の部分でrectsに静止画像であるframeを処理したものを入れているので、入力画像はrectsなのではないかと思ったのですが、違うのでしょうか。
_, 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)
いろいろ要領を得ない質問が多いと思いますが、答えることができる範囲で回答していただければ幸いです。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2019/11/01 05:19
2019/11/01 06:05
退会済みユーザー
2019/11/01 09:48