在 Django 上使用 OpenCV 将视频分割为图像
我有一个 REST api,我的用户可以上传 base64 编码的视频。上传后,我想将视频分割成帧来训练人工智能。这是我的序列化程序的当前版本:
# My models
class UserProfile(models.Model):
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
captureDateTime = models.CharField(_('Capture datetime'), blank=True, null=True, max_length=100)
class UserUploadedData(models.Model):
profile = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
rawData = models.TextField(_('Raw Data'), blank=True, null=True)
file = models.FileField(_('File'), blank=True)
def save(self, *args, **kwargs):
super(UserUploadedData,self).save(*args, **kwargs)
# My serializers
class UserUploadedDataSerializer(serializers.ModelSerializer):
profile = serializers.SlugRelatedField(source="parent.id", slug_field='profile', read_only=True)
class Meta:
model = UserUploadedData
fields = "__all__"
class UserProfileSerializer(serializers.Serializer):
customerId = serializers.SlugRelatedField(source='user', queryset=get_user_model().objects.all(), many=False, slug_field='customerId')
uploadedData = UserUploadedData(many=True)
def __video_to_frames(self, userUploadedData):
print("Video to frames: ")
print(userUploadedData.file.path)
# Start capturing the feed
cap = cv2.VideoCapture(userUploadedData.file.path)
# Find the number of frames
video_length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) - 1
print ("Number of frames: ", video_length)
count = 0
print ("Converting video..\n")
# Start converting the video
while cap.isOpened():
# Extract the frame
ret, frame = cap.read()
if not ret:
continue
if count % 12 == 0:
# Write the results back to output location.
filename = datetime.now().strftime('%Y.%m.%d.%H.%M.%S')
path = "media/"+filename+"-"+str(count+1)+'.jpg'
print(path)
cv2.imwrite(path, frame)
f = open(path, 'r')
print(type(f))
tempImageFile = ContentFile(File(f.read())) # this is were things go wrong...
UserUploadedData.objects.create(profile=userUploadedData.profile, file=tempImageFile)
count = count + 1
# If there are no more frames left
if (count > (video_length-1)):
# Release the feed
cap.release()
break
print ("Converting video.. done!\n")
return
def create(self, validated_data):
#print(validated_data)
user = validated_data.get('user')
profile = UserProfile.objects.create(user=user, captureDateTime=validated_data)
dataArray = validated_data.get('profile').get('data')
for bioData in dataArray:
rawData = bioData.get('rawData')
format, mediastr = rawData.split(';base64,')
ext = format.split('/')[-1]
decodedMedia = base64.b64decode(mediastr)
if ext.lower() == 'mp4':
print("Split video...")
filename = datetime.now().strftime('temp_%Y.%m.%d.%H.%M.%S')
tempVideoFile = ContentFile(decodedMedia, name=filename+'.'+ext)
object = UserUploadedData.objects.create(profile=profile, file=tempVideoFile, **bioData)
# Save all converted images
self.__video_to_frames(object)
else:
print("Save image")
filename = datetime.now().strftime('%Y.%m.%d.%H.%M.%S')
file = ContentFile(decodedMedia, name=filename+'.'+ext)
object = UserUploadedData.objects.create(profile=profile, file=file, **bioData)
return profile
错误跟踪如下:
Number of frames: 25
Converting video..
media/2022.03.20.22.58.14-1.jpg
<class '_io.TextIOWrapper'>
Internal Server Error: /bis/v1/customer/save/
(...)
File "C:\Users\me\Documents\Sources\python\project\app\serializers.py", line 67, in __video_to_frames
tempImageFile = ContentFile(File(f.read()))
File "C:\Python38\lib\encodings\cp1252.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 251: character maps to <undefined>
目前,MP4 文件已正确保存,但单个图像未:(
感谢您的帮助!
I have a REST api where my user can upload base64 encoded videos. Upon upload, i'd like to split the video into frames to train an AI. Here is my current version of my serializer:
# My models
class UserProfile(models.Model):
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
captureDateTime = models.CharField(_('Capture datetime'), blank=True, null=True, max_length=100)
class UserUploadedData(models.Model):
profile = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
rawData = models.TextField(_('Raw Data'), blank=True, null=True)
file = models.FileField(_('File'), blank=True)
def save(self, *args, **kwargs):
super(UserUploadedData,self).save(*args, **kwargs)
# My serializers
class UserUploadedDataSerializer(serializers.ModelSerializer):
profile = serializers.SlugRelatedField(source="parent.id", slug_field='profile', read_only=True)
class Meta:
model = UserUploadedData
fields = "__all__"
class UserProfileSerializer(serializers.Serializer):
customerId = serializers.SlugRelatedField(source='user', queryset=get_user_model().objects.all(), many=False, slug_field='customerId')
uploadedData = UserUploadedData(many=True)
def __video_to_frames(self, userUploadedData):
print("Video to frames: ")
print(userUploadedData.file.path)
# Start capturing the feed
cap = cv2.VideoCapture(userUploadedData.file.path)
# Find the number of frames
video_length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) - 1
print ("Number of frames: ", video_length)
count = 0
print ("Converting video..\n")
# Start converting the video
while cap.isOpened():
# Extract the frame
ret, frame = cap.read()
if not ret:
continue
if count % 12 == 0:
# Write the results back to output location.
filename = datetime.now().strftime('%Y.%m.%d.%H.%M.%S')
path = "media/"+filename+"-"+str(count+1)+'.jpg'
print(path)
cv2.imwrite(path, frame)
f = open(path, 'r')
print(type(f))
tempImageFile = ContentFile(File(f.read())) # this is were things go wrong...
UserUploadedData.objects.create(profile=userUploadedData.profile, file=tempImageFile)
count = count + 1
# If there are no more frames left
if (count > (video_length-1)):
# Release the feed
cap.release()
break
print ("Converting video.. done!\n")
return
def create(self, validated_data):
#print(validated_data)
user = validated_data.get('user')
profile = UserProfile.objects.create(user=user, captureDateTime=validated_data)
dataArray = validated_data.get('profile').get('data')
for bioData in dataArray:
rawData = bioData.get('rawData')
format, mediastr = rawData.split(';base64,')
ext = format.split('/')[-1]
decodedMedia = base64.b64decode(mediastr)
if ext.lower() == 'mp4':
print("Split video...")
filename = datetime.now().strftime('temp_%Y.%m.%d.%H.%M.%S')
tempVideoFile = ContentFile(decodedMedia, name=filename+'.'+ext)
object = UserUploadedData.objects.create(profile=profile, file=tempVideoFile, **bioData)
# Save all converted images
self.__video_to_frames(object)
else:
print("Save image")
filename = datetime.now().strftime('%Y.%m.%d.%H.%M.%S')
file = ContentFile(decodedMedia, name=filename+'.'+ext)
object = UserUploadedData.objects.create(profile=profile, file=file, **bioData)
return profile
The error trace is the following:
Number of frames: 25
Converting video..
media/2022.03.20.22.58.14-1.jpg
<class '_io.TextIOWrapper'>
Internal Server Error: /bis/v1/customer/save/
(...)
File "C:\Users\me\Documents\Sources\python\project\app\serializers.py", line 67, in __video_to_frames
tempImageFile = ContentFile(File(f.read()))
File "C:\Python38\lib\encodings\cp1252.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 251: character maps to <undefined>
At the moment, the MP4 file is saved corrected, but the individual images are not :(
Thanks for your help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尝试使用
文件名 = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
Try using
filename = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')