[Python] Python folium.raster_layers.VideoOverlay() video not filling bounding box

Discussão em 'Python' iniciado por Stack, Fevereiro 2, 2025.

  1. Stack

    Stack Membro Participativo

    I'm trying to overlay an mp4 video onto a folium map using folium.raster_layers.VideoOverlay(). The result is a video I call DyeVideo.html. However, the image doesn't appear in the bounding box on the map, bounds=[[lat_min,lon_min],[lat_max,lon_max]]. DyeVideo.png, is a screenshot of the video file DyeVideo.html. See https://casconorwich.org/pages/files2.html to see the screenshot for this and others. The video does not fill the entire red bounding box. I will try to explain how this video was created. It only contains 5 png frames for now, but will eventually contain about 50.

    The data comes from running a numerical ocean model, FVCOM, to create the spread of dye that is inserted in the ocean in Casco Bay, Maine over time. The output is placed in an array of [lat,lon,dyeconcentration], where lat,lon is given at each vertex of a triangular mesh that has about 40,000 vertices. For each of 5 times, I create a png file using tripcolor():

    tpp = ax1.tripcolor(lat,lon,triangles,dye1[t1+k,:],cmap='jet',shading= 'gouraud')


    Then save tpp as a png file:

    img1=plt.savefig('tpp'+str(k+1)+str('.png'), format='png',dpi=400,bbox_inches='tight',pad_inches=0.0,transparent=True)


    To see how one of these 5 png images look on a folium map, I use folium.raster_layers.ImageOverlay as follows:

    array1 = asarray(img1)
    folium.raster_layers.ImageOverlay(
    image = array1, name='Dye overlay',
    bounds=[[lat_min,lon_min],[lat_max,lon_max]],
    opacity=0.6, origin='upper',
    mercator_project=True, cross_origin=False,
    zindex=1,overlay=True, control=True,
    show=True,
    ).add_to(map)


    One of the 5 overlays on the folium map is shown in a screenshot, DyeFrame1.png on my website. You can see that this single png image projects onto the folium map exactly as it should, filling the red rectangle of the bounding box. The next step is to build an mp4 video from the 5 png images, using cv2 VideoWriter:

    def images_to_video(image_folder, output_path, fps=0.6):
    #Converts a folder of png images into a video.
    images = [img for img in os.listdir(image_folder) if img.endswith("png")]
    images.sort() # Ensure images are in order
    frame = cv2.imread(os.path.join(image_folder, images[0]))
    width,height = frame.shape[1],frame.shape[0] # here,1984,1348
    video = cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*'mp4v'),fps, (width,height))

    for image in images:
    img_path = os.path.join(image_folder, image)
    frame = cv2.imread(img_path)
    video.write(frame)

    video.release()
    print("Video Frames2png.mp4 created successfully at:", output_path)
    if __name__ == "__main__":
    output_path = '/Users/true/Python1/DyeFrames/Frames2/Frames2png.mp4'
    images_to_video(image_folder, output_path)
    map.save('DyeFrames2.html')


    So the result, Frames2png.mp4, is just a video of 5 frames of png files, each of which fit perfectly in the red bounding box.

    Finally, the folium.raster_layers.VideoOverlay() is used to overlay the video Frames2png.mp4 onto the folium map:

    video = folium.raster_layers.VideoOverlay(
    video_url= Frames2png.mp4,
    bounds=[[lat_min,lon_min],[lat_max,lon_max]],
    transparent=True,
    keepAspectRatio=False,
    mercator_project=True,
    name="Dye Video",
    opacity=0.6,
    attr="Dye Overlay",
    overlay= True,
    autoplay=True,
    control=True,
    loop=True,
    playsInline=True,
    )
    video.add_to(map)
    map.save('DyeVideo.html')


    The result is DyeVideo.html, which does not fit correctly in the red bounding box. Everything works great except for the folium.raster_layers.VideoOverlay().

    I have used ffmpeg to remove any unwanted borders from the png images and Frames2png.mp4. I have also used ffmpeg to resize Frames2png.mp4 in numerous ways to increase height, etc, allowing aspect-ratio to change as necessary. In each case the bounding box seems to have no control over the size and position of the video on the folium map. When I look at the folium.raster_layers.py file, I see nothing there that would help. I'm wondering if others have had a similar problem or can give some advice. I just want to overlay a video onto a map.

    Continue reading...

Compartilhe esta Página