我是Python新手,目前正在学习它。我目前正在使用OpenCV haarcascade进行面部检测(已完成)目前正在尝试获取录制视频中每帧的RGB像素,并将其作为每帧信号的平均RGB值输出到图形中。但我遇到的问题是,图形只显示前几秒获得的RGB值,停在那里,输出可能不是平均值。
我见过一些样本使用.append来获得RGB图像的平均值,并尝试过将获得的RGB值平均到每帧,在线图中给出3个不同的值,但出来的图只给出了前几秒的RGB值,并停在那里(录制的视频大约20秒长),输出的结果不是RGB值的平均值。
下面的Python代码是我正在使用的代码。我非常感谢任何形式的帮助和建议。谢谢。
import cv2
from PIL import Image
import datetime
import matplotlib.pyplot as plt
from statistics import mean
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
cap = cv2.VideoCapture('Video1.MOV')
b = []
g = []
r = []
while True:
ret, img = cap.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5)
for x, y, w, h in faces:
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
face = img[y: y + h, x: x + w]
face_gray = gray[y: y + h, x: x + w]
t_now = datetime.datetime.now().time()
print('The Time is:{}'.format(t_now))
B,G,R = face[150, 150]
print('BLUE:{}'.format(B), 'GREEN:{}'.format(G), 'RED:{}'.format(R))
print('Size of ROI:{}'.format(face.shape))
b.append(B)
g.append(G)
r.append(R)
plt.xlabel('Time(s)')
plt.ylabel('RGB Signals')
plt.plot(b, g, label = "line 1, Blue", color = 'blue')
plt.plot(g, label = "line 2, Green", color = 'green')
plt.plot(r, label = "line 3, Red", color = 'red')
plt.legend()
plt.show()
cv2.imshow('video image', img)
fps = cap.get(cv2.CAP_PROP_FPS)
print('FPS:{}'.format(fps))
key = cv2.waitKey(10)
if key == 27:
break
cap.release()
cv2.destroyAllWindows()
1条答案
按热度按时间ewm0tg9j1#
在线上:
你只得到了检测到的人脸内一个坐标为150,150的像素的亮度值。我认为这不是你想要的。在你的问题中,你写的是你对整个帧的亮度值感兴趣,但我猜你只是指检测到的人脸周围的边界框内的值。
此外,得到的值并不代表任何平均值,因为在你的代码中你没有使用任何计算平均值的方法。你提到的“append”方法实际上是用来在列表的末尾插入一个元素的。
你可以检查 face 变量的形状:你会注意到前两个值描述了像素区域的大小,第三个值表示通道的数量-在我们的例子中,由于图像是RGB的,通道的数量将是3。所以你需要引用特定的通道并将它们分配给变量B,G,R.您可以计算平均值,例如使用numpy包中的mean函数。
我在下面包含了整个代码:
但是,如果你想计算整个帧的像素值,而不仅仅是bbox内部的像素值,只需在内部循环中将 face 替换为 img。
当然,您的代码还有其他可以改进的小问题,例如,您可以将创建图形的行移动到循环的外部,以便在最后只得到一个图形。