skip to Main Content

I have an image of size 1000×1000(Grayscale). I want to start with a white canvas and plot the pixel value one by one on that canvas and create a video out of it.
How can we achieve this?

2

Answers


  1. This is pseudocode, but might help:

    # assume x is 2d array with image of interest
    _x = np.zeros_like(x)  # temp emptyarray
    for i in range(x.shape[0]):
       for j in range(x.shape[1]):
          _x[i,j] = x[i,j]   # copy data (fill the temp array gradually)
          ...  # pass _x to plotting library
    
    Login or Signup to reply.
  2. There are many ways of doing this. I’ll just show 2 ways:

    • using OpenCV and its built-in VideoWriter, and
    • using PIL/Pillow and ffmpeg externally

    You can use OpenCV and its VideoWriter like this:

    #!/usr/bin/env python3
    
    import numpy as np
    import cv2
    
    # Load image in greyscale
    im = cv2.imread('paddington.png', cv2.IMREAD_GRAYSCALE)
    h, w = im.shape
    
    # Make empty white RGB canvas same size
    # I don't think VideoWriter likes greyscale frames, only 3-channel ones
    canvas = np.full((h,w,3), 255, np.uint8)
    
    # Create video writer
    fourcc = cv2.VideoWriter_fourcc(*'MJPG')
    out = cv2.VideoWriter("output.avi", fourcc, 30.0, im.shape)
    
    cnt = 0
    for y in range(h):
       for x in range(w):
    
          # Copy a grey pixel from image to RGB canvas
          canvas[y,x,:] = im[y,x], im[y,x], im[y,x]
    
          # Write every 100th frame to video to speed it up
          if cnt % 100 ==  0:
             out.write(canvas)
    
          # Count frames
          cnt += 1
          
    out.release()
    

    enter image description here


    Or, if you prefer – or cannot install OpenCV – you can use PIL/Pillow and ffmpeg like this for the same result:

    #!/usr/bin/env python3
    ################################################################################
    # Run like this:
    #
    # ./plotPaddington2.py | ffmpeg -y -f rawvideo -pix_fmt gray8 -video_size 400x400 -i - -c:v h264 -pix_fmt yuv420p video.mov
    ################################################################################
    
    from PIL import Image
    import sys
    
    # Load image in greyscale
    im = Image.open('paddington.png').convert('L')
    h, w = im.size
    
    # Make empty white canvas same size
    canvas = Image.new('L', im.size, 'white')
    
    cnt = 0
    for y in range(h):
       for x in range(w):
    
          # Copy a pixel from image to canvas
          canvas.putpixel((x,y), im.getpixel((x,y)))
    
          # Write every 100th frame to video to speed it up
          if cnt % 100 ==  0:
             sys.stdout.buffer.write(canvas.tobytes())
    
          # Count frames
          cnt += 1
    

    Then you would pipe the output of this script into ffmpeg (with adjusted size parameters to match your video:

    ./plotPaddington2.py | ffmpeg -y -f rawvideo -pix_fmt gray8 -video_size 400x400 -i - -c:v h264 -pix_fmt yuv420p video.mov
    

    Note that if you have an image of 1000×1000 pixels and you create a new frame of video for each and every pixel, you will get 1,000,000 frames of video. If you show 30 frames/second, which is pretty normal for video, your video will take 9 hours to complete… so I plotted every 100th frame:

    hours = WIDTH * HEIGHT / (30 fps * 3600 seconds/hr) = 9.2 hrs
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search