Home > Blockchain >  How can I show an image plotting pixel by pixel using python?
How can I show an image plotting pixel by pixel using python?

Time:06-09

I have an image of size 1000x1000(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?

CodePudding user response:

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

CodePudding user response:

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 1000x1000 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
  • Related