How I Correct Perspective When Filming TV Screens

This article tells the story of how and why I film my tournament gameplay by pointing my phone at a CRT television.

Find all my vods at: vods.kevbot.xyz/

It Started with Someone Else's Blog Post

A few years ago, I came across this interesting blog post (archived) by Silveira Neto, which was posted to hacker news. He writes about some "sneak peek" promo footage of a Zelda game. When the game creators made this video, rather than capturing the game directly, the footage has devs playing beside the physical TV. The actual gameplay took up only about a quarter of the frame and was at a slightly odd angle. Neto wanted to improve the visibility of the gameplay.

A diagram from the blog post, showing the transformation applied to the footage.

Neto calculated the four pixel coordinates (the red numbers pictured) that make up the corners of the television – the desired frame. The shape is a quadrilateral, but not a rectangle. We know that the TV in question is perfectly rectangular with a 16:9 aspect ratio.

Knowing, this he took the original video and exported all frames as individual images via an imagemagick command, re-mapping the pixels of the inner screen to an un-skewed frame. Then he re-combined all the edited frames back to a video. And it worked nicely! You can see the output on the bottom of the picture. The ouptut resolution is somewhat low low, as we are essentially zooming into a video. But the video is now viewed head-on and with nothing else in the frame. All we see is the gameplay.

Back on hacker news, in response to the blogpost, a commenter simplified the perspective correction process via an ffmpeg command. ffmpeg is a command line image processing program that is used for just about everything video-related behind the scenes. this was the hacker news comment

Well... you can do that with only ffmpeg.

ffmpeg -i zelda_720p.mp4 -vf perspective=60:90:589:147:50:415:582:418 output.mp4

Wow, that looks pretty simple. Here is the ffmpeg documentation on the perspective argument: https://ffmpeg.org/ffmpeg-filters.html#perspective

My Solution

I leveraged the above blog post to make my python and ffmpeg script. I call it vodhelper.py.

Melee, In contrast to the blogpost, is played on older CRTs at a 4:3 aspect ratio[1]. So I had to use that as my aspect ratio instead of 16:9 as seen in the Zelda footage.

The operative part of my ffmpeg command looks like:

perspective={points},scale=876:720,setdar=73/60

I also made a helper script to allow me to select the 4 corners of the CRT TV in my gameplay footage.

So when I come home from tournaments I

  1. Copy the footage from my phone to my computer
  2. Run vodhelper.py
    1. input the start.gg url and date of tournament
    2. input the names of my opponents
    3. for each video
      1. select the 4 corners of the crt in my special interface
      2. verify I got the perspective right via preview of the output via ffplay
      3. if it looks wrong, retry from step c
  3. Combine the videos in a video editor, making other corrections where needed (e.g. brightness, volume, adding pictures).
  4. Upload to youtube.

Other info:

  1. If you set your video camera's shutter speed to 60 when filming a 60hz CRT screen, you won't get all the weird lines going up and down the screen. My phone (Pixel 6a), using the app Open Camera can modify the camera's shutter speed. Even though I can set the shutter speed to 60, I cannot also set the Frames Per Second to 60. I'm locked to 30 FPS. It's good enough, though.
  2. Here's a google sheet comparing different ways I've recorded my gameplay while at tournaments. I've settled on pointing my phone at the screen from a phone stand because It's the lowest friction setup to do while at the tournament. Capture cards, slippi, and other solutions are cool, but as a competitor I don't want to distract myself fiddling with a bunch of equipment. Although I did have a pretty cool setup at one point with an AverMedia Live Gamer Portable: LGP Diagram.

Footnotes

[1] Techincally, Melee's native aspect ratio is 73:60, which is a bit taller than 4:3, see this reddit post for more great info. My videos were 9% too wide, until I moved to the correct aspect ratio.