
Recherche avancée
Autres articles (83)
-
Qu’est ce qu’un éditorial
21 juin 2013, parEcrivez votre de point de vue dans un article. Celui-ci sera rangé dans une rubrique prévue à cet effet.
Un éditorial est un article de type texte uniquement. Il a pour objectif de ranger les points de vue dans une rubrique dédiée. Un seul éditorial est placé à la une en page d’accueil. Pour consulter les précédents, consultez la rubrique dédiée.
Vous pouvez personnaliser le formulaire de création d’un éditorial.
Formulaire de création d’un éditorial Dans le cas d’un document de type éditorial, les (...) -
Multilang : améliorer l’interface pour les blocs multilingues
18 février 2011, parMultilang est un plugin supplémentaire qui n’est pas activé par défaut lors de l’initialisation de MediaSPIP.
Après son activation, une préconfiguration est mise en place automatiquement par MediaSPIP init permettant à la nouvelle fonctionnalité d’être automatiquement opérationnelle. Il n’est donc pas obligatoire de passer par une étape de configuration pour cela. -
Les autorisations surchargées par les plugins
27 avril 2010, parMediaspip core
autoriser_auteur_modifier() afin que les visiteurs soient capables de modifier leurs informations sur la page d’auteurs
Sur d’autres sites (10377)
-
Python cv2 script that scans a giant image to a video. Why do I need pad two extra lines
27 avril 2022, par MahrarenaI wrote a script that scans a giant image to make a video. Normally I just post my scripts straight to my Code Review account, but this script is ugly, needs to be refactored, implements only horizontal scrolling and most importantly I just fixed a bug but I don't completely understand why it works.


Example :


Original image (Google Drive)


Video Output (Google Drive)


As you can see from the video, everything is working properly except the fact that I don't know how it works.


Full working code



import cv2
import numpy as np
import random
import rpack
from fractions import Fraction
from math import prod

def resize_guide(image_size, target_area):
 aspect_ratio = Fraction(*image_size).limit_denominator()
 horizontal = aspect_ratio.numerator
 vertical = aspect_ratio.denominator
 unit_length = (target_area/(horizontal*vertical))**.5
 return (int(horizontal*unit_length), int(vertical*unit_length))

fourcc = cv2.VideoWriter_fourcc(*'mp4v')
FRAME = np.zeros((1080, 1920, 3), dtype=np.uint8)

def new_frame():
 return np.ndarray.copy(FRAME)

def center(image):
 frame = new_frame()
 h, w = image.shape[:2]
 yoff = round((1080-h)/2)
 xoff = round((1920-w)/2)
 frame[yoff:yoff+h, xoff:xoff+w] = image
 return frame

def image_scanning(file, fps=60, pan_increment=64, horizontal_increment=8):
 image = cv2.imread(file)
 height, width = image.shape[:2]
 assert width*height >= 1920*1080
 video_writer = cv2.VideoWriter(file+'.mp4', fourcc, fps, (1920, 1080))
 fit_height = True
 if height < 1080:
 width = width*1080/height
 image = cv2.resize(image, (width, 1080), interpolation = cv2.INTER_AREA)
 aspect_ratio = width / height
 zooming_needed = False
 if 4/9 <= aspect_ratio <= 16/9:
 new_width = round(width*1080/height)
 fit = cv2.resize(image, (new_width, 1080), interpolation = cv2.INTER_AREA)
 zooming_needed = True
 
 elif 16/9 < aspect_ratio <= 32/9:
 new_height = round(height*1920/width)
 fit = cv2.resize(image, (1920, new_height), interpolation = cv2.INTER_AREA)
 fit_height = False
 zooming_needed = True
 
 centered = center(fit)
 for i in range(fps):
 video_writer.write(centered)
 if fit_height:
 xoff = round((1920 - new_width)/2)
 while xoff:
 if xoff - pan_increment >= 0:
 xoff -= pan_increment
 else:
 xoff = 0
 frame = new_frame()
 frame[0:1080, xoff:xoff+new_width] = fit
 video_writer.write(frame)
 else:
 yoff = round((1080 - new_height)/2)
 while yoff:
 if yoff - pan_increment >= 0:
 yoff -= pan_increment
 else:
 yoff = 0
 frame = new_frame()
 frame[yoff:yoff+new_height, 0:1920] = fit
 video_writer.write(frame)
 
 if zooming_needed:
 if fit_height:
 width_1, height_1 = new_width, 1080
 else:
 width_1, height_1 = 1920, new_height
 new_area = width_1 * height_1
 original_area = width * height
 area_diff = original_area - new_area
 unit_diff = area_diff / fps
 for i in range(1, fps+1):
 zoomed = cv2.resize(image, resize_guide((width_1, height_1), new_area+unit_diff*i), interpolation=cv2.INTER_AREA)
 zheight, zwidth = zoomed.shape[:2]
 zheight = min(zheight, 1080)
 zwidth = min(zwidth, 1920)
 frame = new_frame()
 frame[0:zheight, 0:zwidth] = zoomed[0:zheight, 0:zwidth]
 video_writer.write(frame)
 
 if (width - 1920) % horizontal_increment:
 new_width = ((width - 1920) // horizontal_increment + 1) * horizontal_increment + 1920
 frame = np.zeros([height, new_width, 3], dtype=np.uint8)
 frame[0:height, 0:width] = image
 width = new_width
 image = frame
 
 if height % 1080:
 new_height = (height // 1080 + 2) * 1080
 frame = np.zeros([new_height, width, 3], dtype=np.uint8)
 frame[0:height, 0:width] = image
 height = new_height - 1080
 image = frame
 
 y, x = 0, 0
 for y in range(0, height, 1080):
 for x in range(0, width-1920, horizontal_increment):
 frame = image[y:y+1080, x:x+1920]
 video_writer.write(frame)
 x = width - 1920
 frame = image[y:y+1080, x:x+1920]
 for i in range(round(fps/3)):
 video_writer.write(frame)
 cv2.destroyAllWindows()
 video_writer.release()
 del video_writer



I don't know why I need to pad two extra lines instead of one, meaning if I change this :


if height % 1080:
 new_height = (height // 1080 + 2) * 1080
 frame = np.zeros([new_height, width, 3], dtype=np.uint8)
 frame[0:height, 0:width] = image
 height = new_height - 1080
 image = frame



To this :


if height % 1080:
 new_height = (height // 1080 + 1) * 1080
 frame = np.zeros([new_height, width, 3], dtype=np.uint8)
 frame[0:height, 0:width] = image
 height = new_height
 image = frame



The program raises exceptions :


OpenCV: FFMPEG: tag 0x34363268/'h264' is not supported with codec id 27 and format 'mp4 / MP4 (MPEG-4 Part 14)'
OpenCV: FFMPEG: fallback to use tag 0x31637661/'avc1'
---------------------------------------------------------------------------
error Traceback (most recent call last)
 in <module>
----> 1 image_scanning("D:/collages/91f53ebcea2a.png")

 in image_scanning(file, fps, pan_increment, horizontal_increment, fast_decrement)
 122 x += horizontal_increment
 123 frame = image[y:y+1080, x:x+1920]
--> 124 video_writer.write(frame)
 125 cv2.destroyAllWindows()
 126 video_writer.release()

error: Unknown C++ exception from OpenCV code
</module>


I guess it was caused by indexing error because the last line would not have enough pixels so padding the height of the image to a multiple of 1080 should work.


But that's not the case, I need to pad two lines, why is that ? I really don't understand why it is working.



No, I really wrote all of it, I understand all the principles, the ideas are all mine, but there is one small problem in implementation. I don't know why I need extra pixels in the bottom to make it work, because if I don't pad the height to a multiple of 1080, I can't get the bottom line, the lowest potion of height % 1080 would be lost.


If I tried to get the lowest part, the program will raise exceptions even if I pad the height to a multiple of 1080, I think it is related to indexing but I don't fully understand it, turns out I need to pad the height and add extra pixels, even 1 pixel would work.


I don't know why it raises exceptions and how add extra pixels got rid of the exception, but I understand everything else perfectly clear, after all I wrote it.


There's a bug in my program, I don't know what caused it, and I want you to help me debugging, and that's the entire point of the question !


-
FFmpeg Cropping Fps Drop
7 mai 2022, par JamesFFmpeg Commands works but having a problem in fps drop also using libx264 for encoding any idea to get this good


"-y" "-noautorotate" "-ss" "301" "-t" "11" "-i" "/mnt/shared/Pictures/[BTCLOD.COM] COSTA RICA IN 4K 60fps HDR (ULTRA HD)-1080p60.mp4" \
"-strict" "experimental" "-vf" "crop=w=606:h=1080:x=657:y=0" \
"-vcodec" "libx264" "-crf" "18" "-r" "15" "-b:v" "2500k" \
"-acodec" "copy" "-ab" "128k" "-sample_fmt" "s16" \
"-ss" "0" "-t" "11" "/storage/emulated/0/VEditor/VideoCroper/[BTCLOD.COM] COSTA RICA IN 4K 60fps HDR (ULTRA HD)-1080p60-0-6.mp4"



-
How to get the first audio channel from a video with ffmpeg-python ?
31 mai 2022, par giskI would like to get the very first audio channel from a video using ffmpeg-python.


I tried with this :


out, _ = (
 ffmpeg
 .input(filename)
 .output('pipe:', loglevel=0, format='s16le', acodec='pcm_s16le', ac=1, ar='8k')
 .run(capture_stdout=True)
 )
 """ extract audio signal """
 self.signal = (
 np
 .frombuffer(out, np.int16) 
 )



but I am not sure whether this is correct.


I had a look here, but I could not find a solution : https://trac.ffmpeg.org/wiki/AudioChannelManipulation


Any suggestion ? Thanks !


EDIT :


I tried @rotem solution and it seems to work. However, I have another issue which seems related to the -ac flag. For some videos, the numpy output has the right length (i.e., it matches the original audio length). For others, I get a wrong one. However, if I set -ac to 2 for these videos, I get the correct signal length. Do you know why is this happening ?


This is the metadata of the video (duration : 2 minutes and 11 seconds) which outputs the correct numpy array size with setting -ac to 2


'streams' : ['index' : 0, 'codec_name' : 'h264', 'codec_long_name' : 'H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10', 'profile' : 'High', 'codec_type' : 'video', 'codec_tag_string' : 'avc1', 'codec_tag' : '0x31637661', 'width' : 1920, 'height' : 1080, 'coded_width' : 1920, 'coded_height' : 1080, 'closed_captions' : 0, 'film_grain' : 0, 'has_b_frames' : 0, 'pix_fmt' : 'yuv420p', 'level' : 40, 'color_range' : 'tv', 'color_space' : 'bt709', 'color_transfer' : 'bt709', 'color_primaries' : 'bt709', 'chroma_location' : 'left', 'field_order' : 'progressive', 'refs' : 1, 'is_avc' : 'true', 'nal_length_size' : '4', 'id' : '0x1', 'r_frame_rate' : '30/1', 'avg_frame_rate' : '176805000/5894849', 'time_base' : '1/90000', 'start_pts' : 0, 'start_time' : '0.000000', 'duration_ts' : 11789698, 'duration' : '130.996644', 'bit_rate' : '16999840', 'bits_per_raw_sample' : '8', 'nb_frames' : '3929', 'extradata_size' : 34, 'disposition' : 'default' : 1, 'dub' : 0, 'original' : 0, 'comment' : 0, 'lyrics' : 0, 'karaoke' : 0, 'forced' : 0, 'hearing_impaired' : 0, 'visual_impaired' : 0, 'clean_effects' : 0, 'attached_pic' : 0, 'timed_thumbnails' : 0, 'captions' : 0, 'descriptions' : 0, 'metadata' : 0, 'dependent' : 0, 'still_image' : 0, 'tags' : 'creation_time' : '2022-05-30T15:00:39.000000Z', 'language' : 'eng', 'handler_name' : 'VideoHandle', 'vendor_id' : '[0][0][0][0]', 'index' : 1, 'codec_name' : 'aac', 'codec_long_name' : 'AAC (Advanced Audio Coding)', 'profile' : 'LC', 'codec_type' : 'audio', 'codec_tag_string' : 'mp4a', 'codec_tag' : '0x6134706d', 'sample_fmt' : 'fltp', 'sample_rate' : '48000', 'channels' : 2, 'channel_layout' : 'stereo', 'bits_per_sample' : 0, 'id' : '0x2', 'r_frame_rate' : '0/0', 'avg_frame_rate' : '0/0', 'time_base' : '1/48000', 'start_pts' : 696, 'start_time' : '0.014500', 'duration_ts' : 6285214, 'duration' : '130.941958', 'bit_rate' : '256004', 'nb_frames' : '6138', 'extradata_size' : 2, 'disposition' : 'default' : 1, 'dub' : 0, 'original' : 0, 'comment' : 0, 'lyrics' : 0, 'karaoke' : 0, 'forced' : 0, 'hearing_impaired' : 0, 'visual_impaired' : 0, 'clean_effects' : 0, 'attached_pic' : 0, 'timed_thumbnails' : 0, 'captions' : 0, 'descriptions' : 0, 'metadata' : 0, 'dependent' : 0, 'still_image' : 0, 'tags' : 'creation_time' : '2022-05-30T15:00:39.000000Z', 'language' : 'eng', 'handler_name' : 'SoundHandle', 'vendor_id' : '[0][0][0][0]'], 'format' : 'filename' : 'videos4/test_01.mp4', 'nb_streams' : 2, 'nb_programs' : 0, 'format_name' : 'mov,mp4,m4a,3gp,3g2,mj2', 'format_long_name' : 'QuickTime / MOV', 'start_time' : '0.000000', 'duration' : '130.996600', 'size' : '282621379', 'bit_rate' : '17259768', 'probe_score' : 100, 'tags' : 'major_brand' : 'mp42', 'minor_version' : '0', 'compatible_brands' : 'isommp42', 'creation_time' : '2022-05-30T15:00:39.000000Z', 'com.android.version' : '12', 'com.android.capture.fps' : '30.000000'.


This is instead, the metadata of the video (duration 5 minutes) which gives the right result length with setting -ac to 1 :


'streams' : ['index' : 0, 'codec_name' : 'h264', 'codec_long_name' : 'H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10', 'profile' : 'High', 'codec_type' : 'video', 'codec_tag_string' : 'avc1', 'codec_tag' : '0x31637661', 'width' : 1920, 'height' : 1080, 'coded_width' : 1920, 'coded_height' : 1080, 'closed_captions' : 0, 'film_grain' : 0, 'has_b_frames' : 0, 'sample_aspect_ratio' : '1:1', 'display_aspect_ratio' : '16:9', 'pix_fmt' : 'yuv420p', 'level' : 40, 'field_order' : 'progressive', 'refs' : 1, 'is_avc' : 'true', 'nal_length_size' : '4', 'id' : '0x1', 'r_frame_rate' : '30/1', 'avg_frame_rate' : '33862500/1128779', 'time_base' : '1/90000', 'start_pts' : 0, 'start_time' : '0.000000', 'duration_ts' : 27090696, 'duration' : '301.007733', 'bit_rate' : '16999542', 'bits_per_raw_sample' : '8', 'nb_frames' : '9030', 'extradata_size' : 26, 'disposition' : 'default' : 1, 'dub' : 0, 'original' : 0, 'comment' : 0, 'lyrics' : 0, 'karaoke' : 0, 'forced' : 0, 'hearing_impaired' : 0, 'visual_impaired' : 0, 'clean_effects' : 0, 'attached_pic' : 0, 'timed_thumbnails' : 0, 'captions' : 0, 'descriptions' : 0, 'metadata' : 0, 'dependent' : 0, 'still_image' : 0, 'tags' : 'language' : 'und', 'handler_name' : 'VideoHandler', 'vendor_id' : '[0][0][0][0]', 'side_data_list' : ['side_data_type' : 'Display Matrix', 'displaymatrix' : '\n00000000 : 0 65536 0\n00000001 : -65536 0 0\n00000002 : 0 0 1073741824\n', 'rotation' : -90], 'index' : 1, 'codec_name' : 'aac', 'codec_long_name' : 'AAC (Advanced Audio Coding)', 'profile' : 'LC', 'codec_type' : 'audio', 'codec_tag_string' : 'mp4a', 'codec_tag' : '0x6134706d', 'sample_fmt' : 'fltp', 'sample_rate' : '48000', 'channels' : 2, 'channel_layout' : 'stereo', 'bits_per_sample' : 0, 'id' : '0x2', 'r_frame_rate' : '0/0', 'avg_frame_rate' : '0/0', 'time_base' : '1/48000', 'start_pts' : 0, 'start_time' : '0.000000', 'duration_ts' : 14448640, 'duration' : '301.013333', 'bit_rate' : '256000', 'nb_frames' : '14110', 'extradata_size' : 2, 'disposition' : 'default' : 1, 'dub' : 0, 'original' : 0, 'comment' : 0, 'lyrics' : 0, 'karaoke' : 0, 'forced' : 0, 'hearing_impaired' : 0, 'visual_impaired' : 0, 'clean_effects' : 0, 'attached_pic' : 0, 'timed_thumbnails' : 0, 'captions' : 0, 'descriptions' : 0, 'metadata' : 0, 'dependent' : 0, 'still_image' : 0, 'tags' : 'language' : 'und', 'handler_name' : 'SoundHandler', 'vendor_id' : '[0][0][0][0]'], 'format' : 'filename' : 'videos4/video_02.mp4', 'nb_streams' : 2, 'nb_programs' : 0, 'format_name' : 'mov,mp4,m4a,3gp,3g2,mj2', 'format_long_name' : 'QuickTime / MOV', 'start_time' : '0.000000', 'duration' : '301.014000', 'size' : '649577064', 'bit_rate' : '17263703', 'probe_score' : 100, 'tags' : 'major_brand' : 'isom', 'minor_version' : '512', 'compatible_brands' : 'isomiso2avc1mp41', 'encoder' : 'Lavf58.27.103'