'Split video into images with OpenCV on Django
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!
Solution 1:[1]
Try using
filename = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | YScharf |
