如何从 python 中的 cv2.VideoCapture 获取每个帧作为图像
How to get each frame as an image from a cv2.VideoCapture in python
我想从视频中获取每一帧作为图像。背景如下。我写了一个能够识别手势的神经网络。现在我想开始一个视频流,其中每个 image/frame 流都通过神经网络。为了使其适合我的神经网络,我想渲染每一帧并将图像缩小到 28*28 像素。最后它看起来应该类似于:https://www.youtube.com/watch?v=JfSao30fMxY
我通过网络搜索发现我可以使用 cv2.VideoCapture 来获取流。但是我怎样才能挑选帧的每个图像,渲染它并将结果打印回屏幕上。到目前为止,我的代码看起来像这样:
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
# Todo: each Frame/Image from the video should be saved as a variable and open imageToLabel()
# Todo: before the image is handed to the method, it needs to be translated into a 28*28 np Array
# Todo: the returned Label should be printed onto the video (otherwise it can be )
i = 0
while (True):
# Capture frame-by-frame
# Load model once and pass it as an parameter
ret, frame = cap.read()
i += 1
image = cv2.imwrite('database/{index}.png'.format(index=i), frame)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2BGRAY)
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
def imageToLabel(imgArr, checkpointLoad):
new_model = tf.keras.models.load_model(checkpointLoad)
imgArrNew = imgArr.reshape(1, 28, 28, 1) / 255
prediction = new_model.predict(imgArrNew)
label = np.argmax(prediction)
return label
frame
是您从流中获得的 RGB 图像。
gray
为灰度转换后的图像。
我想您的网络因其形状而采用灰度图像。因此,您需要先将图像大小调整为 (28,28),然后将其传递给您的 imageToLabel 函数
resizedImg = cv2.resize(gray,(28,28))
label = imageToLabel(resizedImg,yourModel)
现在您知道了预测,您可以使用例如 frame
绘制它cv2.putText()
然后绘制框架 returns 而不是 frame
编辑:
如果你想为你的网络使用图像的一部分,你可以像这样切片图像:
slicedImg = gray[50:150,50:150]
resizedImg = cv2.resize(slicedImg,(28,28))
label = imageToLabel(resizedImg,yourModel)
如果您不太熟悉 python 中的索引,您可能想看看 this
此外,如果您希望它看起来像链接视频中的样子,您可以从中绘制一个矩形,例如(50,50) 到 (150,150) 即绿色 (0,255,0)
cv2.rectangle(frame,(50,50),(150,150),(0,255,0))
我想从视频中获取每一帧作为图像。背景如下。我写了一个能够识别手势的神经网络。现在我想开始一个视频流,其中每个 image/frame 流都通过神经网络。为了使其适合我的神经网络,我想渲染每一帧并将图像缩小到 28*28 像素。最后它看起来应该类似于:https://www.youtube.com/watch?v=JfSao30fMxY 我通过网络搜索发现我可以使用 cv2.VideoCapture 来获取流。但是我怎样才能挑选帧的每个图像,渲染它并将结果打印回屏幕上。到目前为止,我的代码看起来像这样:
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
# Todo: each Frame/Image from the video should be saved as a variable and open imageToLabel()
# Todo: before the image is handed to the method, it needs to be translated into a 28*28 np Array
# Todo: the returned Label should be printed onto the video (otherwise it can be )
i = 0
while (True):
# Capture frame-by-frame
# Load model once and pass it as an parameter
ret, frame = cap.read()
i += 1
image = cv2.imwrite('database/{index}.png'.format(index=i), frame)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2BGRAY)
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
def imageToLabel(imgArr, checkpointLoad):
new_model = tf.keras.models.load_model(checkpointLoad)
imgArrNew = imgArr.reshape(1, 28, 28, 1) / 255
prediction = new_model.predict(imgArrNew)
label = np.argmax(prediction)
return label
frame
是您从流中获得的 RGB 图像。
gray
为灰度转换后的图像。
我想您的网络因其形状而采用灰度图像。因此,您需要先将图像大小调整为 (28,28),然后将其传递给您的 imageToLabel 函数
resizedImg = cv2.resize(gray,(28,28))
label = imageToLabel(resizedImg,yourModel)
现在您知道了预测,您可以使用例如 frame
绘制它cv2.putText()
然后绘制框架 returns 而不是 frame
编辑:
如果你想为你的网络使用图像的一部分,你可以像这样切片图像:
slicedImg = gray[50:150,50:150]
resizedImg = cv2.resize(slicedImg,(28,28))
label = imageToLabel(resizedImg,yourModel)
如果您不太熟悉 python 中的索引,您可能想看看 this
此外,如果您希望它看起来像链接视频中的样子,您可以从中绘制一个矩形,例如(50,50) 到 (150,150) 即绿色 (0,255,0)
cv2.rectangle(frame,(50,50),(150,150),(0,255,0))