# Downscaling by skipping rows and columns – any example images?

I'm about to implement downscaling on a microcontroller. Source resolution is e.g. 720x576 (the 576i PAL resolution, other one possible: 480i, NTSC resolution), destination is 32x16. The goal is to have RGB LED matrix (of size 32x16) flowing with various colors, shapes, shadows, etc. – a half-abstract vs. half-meaningful effect, driven by a prepared PAL or NTSC video.

I will only be able to select every 22th pixel (720 / 36) and every 36th line (576 / 16) – the microcontroller will not be able to compute averages of groups of pixels etc. This way I will obtain 32x16 downscaled image to output to the LED matrix.

I cannot find any examples of how such downscaling will behave. Tried searching for "decimation" but no luck. Which program can I use to test this downscaling? Can I quickly code this somehow – if I would to code this, I would use libSDL1, generate set of files, but this is difficult (e.g. image loading). Maybe some snippet-solution is possible? Should I care about Nyquist frequency?

• Using a paint program that has a "nearest neighbor" resize mode would give you a quick approximation, though it may not select the exact same rows/columns as your code. I think it would be pretty easy to prototype in Python using pillow for image manipulation. – Nathan Reed Jan 10 '17 at 22:36
• Don't ntsc and pal have overscan areas - could you prepare your video with the decimated/filtered images in the overscan area? It would take 1 scan line of PAL to hold your entire image. – Daniel M Gessel Jan 11 '17 at 1:04
• "I cannot find any examples of how such downscaling will behave." Did you ever play old 3D games like Doom and see the hideous aliasing artefacts on walls/objects in the distance? That's what it will be like. – Simon F Jan 11 '17 at 9:40
• Note that PAL and NTSC are a 4:3 aspect ratio (despite NTSC seeming like 3:2 - it has non-square pixels at 720x480). 32x16 is 2:1, so you will either be stretching the video, or pillar boxing it. In my opinion, pillar box is far better, but given the abstractness of your description, maybe you'd prefer to stretch it? – user1118321 Jan 15 '17 at 3:34

"Downscaling by skipping rows and columns – any example images?"

You asked for example images: The following is a sequence of 50 frames from a well known (and hopefully freely available) sequence, subsampled as you suggested.

I think you might find simply subsampling/decimating to be a bit too noisy.

Are you sure you can't at least do some box filtering?

• I now established that I will use stm32f767 which – not looked myself yet – has DSP commands. I might do some computations after all, clock is 216 MHz and DMA is said to be flexible. I will read ADV7280 output clocked at 54 MHz, though (interlace -> progressive enabled). – Gortu Jan 13 '17 at 17:45

A basic nearest neighbour scale function would work like so. Here I also use 24:8 fixed point arithmetic to make it more micro friendly.

const int originalWidth = 320, originalHeight = 240;
int targetWidth = 50, targetHeight = 50;

char *pSource = sourceBuffer;
char *pDest = destBuffer;    // you can use RGB instead of char

int yStep = (originalWidth << 8) / targetWidth;
int xStep = (originalHeight << 8) / targetHeight;

for(int y = 0, sampleY = 0; y < targetHeight; y++, sampleY += yStep) {
// Point to start of scaled Y source line
char *pSourceLine = pSource + ((sampleY >> 8) * originalWidth);

// Output the line, scaling only in X (we already know scaled-Y)
for(int x = 0, sampleX = 0; x < targetWidth; x++, sampleX += xStep)
*pDest++ = pSourceLine[sampleX >> 8];
}


This will also work to scale image up as well as down, it should work on any input vs output size.