我的第一个项目是在相对静止的背景上检测移动物体,然后检测它们的平均颜色以对它们进行分类。至少有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()
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
您可以通过首先创建与输入图像尺寸相同且像素值设置为零的新图像来创建mask。
然后使用像素值255将轮廓绘制到此图像上。生成的图像可用作mask。
mask = np.zeros(frame.shape, np.uint8)
cv2.drawContours(mask, c, -1, 255, -1)
然后,mask可以用作cv.mean之类的参数
mean = cv.mean(frame, mask=mask)
只需提醒一句,RGB颜色的平均值并不总是有意义的。也许尝试转换为HSV色彩空间,并仅使用H通道检测对象的颜色。
图像上的解决方案
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()
要消除噪音,您可以只取轮廓的中心,并采用较小的矩形进行检查。