だから私はOpen CVとPythonを一緒に学び始めることを決めました!
私の最初のプロジェクトは、比較的静止した背景で動くオブジェクトを検出し、それらの平均色を検出して並べ替えることです。検出するオブジェクトが少なくとも10個あり、カラービデオを処理しています。
これまでのところ、背景を削除して輪郭を特定することができました(オプションで各輪郭の中心を取得します)が、今では各輪郭の内部の平均色または平均色を取得するのに苦労しています。この種の質問についてはいくつかのトピックがありますが、それらのほとんどはCで書かれています。どうやらcv.mean()
を使用できますが、この関数にフィードするための作業マスクを取得できません。難しいことではないと思いますが、行き詰まっています…乾杯!
import numpy as np
import cv2
video_path = 'test.h264'
cap = cv2.VideoCapture(video_path)
fgbg = cv2.createBackgroundSubtractorMOG2()
while (cap.isOpened):
ret, frame = cap.read()
if ret==True:
fgmask = fgbg.apply(frame)
(contours, hierarchy) = cv2.findContours(fgmask, cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
for c in contours:
if cv2.contourArea(c) > 2000:
cv2.drawContours(frame, c, -1, (255,0,0), 3)
cv2.imshow('foreground and background',fgmask)
cv2.imshow('rgb',frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
画像の解
1)輪郭を見つける(この場合は長方形、長方形でない輪郭は作成がはるかに難しい)
2)等高線の座標を見つける
3)輪郭から画像を切り取ります
4)個々のチャネルを合計し、その中のピクセル数で(または平均関数で)割ります
import numpy as np
import cv2
img = cv2.imread('my_image.jpg',1)
cp = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(cp,150,255,0)
cv2.imshow('img',thresh)
cv2.waitKey(0)
im2,contours,hierarchy = cv2.findContours(thresh.astype(np.uint8), 1, 2)
cnts = contours
for cnt in cnts:
if cv2.contourArea(cnt) >800: # filter small contours
x,y,w,h = cv2.boundingRect(cnt) # offsets - with this you get 'mask'
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow('cutted contour',img[y:y+h,x:x+w])
print('Average color (BGR): ',np.array(cv2.mean(img[y:y+h,x:x+w])).astype(np.uint8))
cv2.waitKey(0)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
ノイズを除去するには、輪郭の中心を取り、小さい方の長方形を調べます。
非長方形の輪郭については、cv2.fillPoly関数-> 非長方形の輪郭のクロッピング を見てください。 しかし、その少し遅いアルゴリズム(しかし何も制限されません)
長方形以外の輪郭に興味がある場合は、マスクが必要であり、マスク/背景が常に長方形であるため、不要なものに対して平均をとるので、平均を行うことに注意する必要があります