View Single Post
Old 25th November 2011, 04:43   #4  |  Link
vampiredom
Registered User
 
Join Date: Aug 2008
Posts: 233
Converting from one non-square pixel format to another

Most times, when converting from one non-square pixel format to another, we are converting PAL to NTSC or vice versa – or converting to/from a scaled format like SVCD. These types of standards conversions usually require only changing the height or width and leaving the other alone. Note: Any interlaced sources must be deinterlanced (or "bobbed") before scaling the height.

As far as scaling is concerned, these kinds of standards conversion are extremely easy and there really is no math required by the user:

Code:
# Restore a 480x480 SVCD to full size for DVD output
Spline36Resize(720,480)

# Scale the image from 720x480 NTSC -> PAL
Spline36Resize(720,576)

# Scale the image from 704x576 PAL -> NTSC
Spline36Resize(704,480)
Of course, for real NTSC<->PAL conversion, you need to choose a good deinterlacer and then convert the framerate from 60Hz <-> 50Hz, but we are only discussing scaling here.

Let's look at one case where we are not doing NTSC <-> PAL and where some math is required for the conversion.

Our source here will be HDV 1440x1080 @ PAR 4/3, which is widescreen. We will convert this to a 720x480 widescreen NTSC DVD two different ways; once with pillarboxing, and again with cropping.

First, we'll set the basic parameters common to both versions:

Code:
# Assume a 1440x1080 16:9 HDV source
SourceWidth  = width()
SourceHeight = height()
SourcePAR    = 1.333333

TargetWidth  = 720
TargetHeight = 480
TargetPAR    = 1.212121

Since the DAR of 720x480 widescreen DVD is slightly wider, the pillarboxed version will resize the video to 704x480 and add 8 pixel borders on each side. Here is VersionA:

Code:
# Scale factor based on heights = 0.444444
ScaleFactor  =  Float(TargetHeight) / Float(SourceHeight)

# Determine the width to scale to (no need to determine height)
ScaleWidth = Float(SourceWidth) * SourcePAR * ScaleFactor / TargetPAR

# Round to mod4 -> 704
ScaleWidth = Round(ScaleWidth * 4) / 4

# Determine the border size
PadX = (TargetWidth - ScaleWidth) / 2

VersionA = Spline36Resize(ScaleWidth, TargetHeight).AddBorders(PadX, 0, PadX, 0)
Now, if do it without adding borders, we'll have to crop a tiny bit from the top and bottom to preserve the aspect ratio accurately. We'll crop the source (as opposed to cropping the output) for a little more accuracy and increased performance. Here is VersionB:

Code:
# Scale factor based on widths = 0.5
ScaleFactor  =  Float(TargetWidth) / Float(TargetHeight)

# Determine the cropped height relative to the source
TargetDAR  = Float(TargetWidth) * TargetPAR / Float(TargetHeight)
CropHeight = Float(SourceWidth) * SourcePAR  / TargetDAR

# Round to mod2 -> 1056
CropHeight = Round(CropHeight * 2) / 2

# Determine the cropping amount for the top and bottom edges
CropY = (SourceHeight - CropHeight) / 2

VersionB = Crop(0,CropY,0,-CropY).Spline36Resize(TargetWidth, TargetHeight)
Both versions should be accurate conversions of the source.

Last edited by vampiredom; 27th November 2011 at 07:05. Reason: Added text and examples
vampiredom is offline   Reply With Quote