back to chris' bitpool

the pgmfindclip homepage

automatically find a clipping border for a sequence of pgm images

(a fine companion for transcode on Linux)

Purpose

This tool tries to find a suitable clipping border for a series of gray images. It is very useful to automatically extract clipping values for transcoding a movie if the source frame is encoded with black bars.

A border around an image is defined by a rectangular and homogenous valued area extending from each edge of the image (e.g. the black bars around a movie frame). For each image the largest clip border is determined and the smallest common region of the image series is returned. Empty images or images with no valid clipping region are ignored.

To cope with noisy regions in the black border areas, the region finding algorithm does not simply cut away all regions with purely zero values, but it uses a threshold in the absolut gradient sum along rows and columns as a hint for the begin of real image contents.

You need a frame processing tool like transcode to actually perform the clipping operation.

The program assumes that all images have the same size!

Download

Revision: 1.13 (18.05.2003) pgmfindclip-1.13.tgz

Install

Compile the source code with the given Makefile and place the resulting binary in your PATH.

Usage

You first have to generate a gray image sequence from your movie. The combination of the -K and -y ppm switches in transcode is very useful in this situation:

transcode .... -K -y ppm -o sample

It is very important to extract frames from different regions of the movie. It is usually a bad idea to extract the first couple of frames of a movie since they often contain a black screen or logos that would lead to wrong clipping borders. A better and still efficient solution is to pick all the files of the movie's title set (the VTSxxx.VOB files) and use the VOB mode of transcode to extract a single frame from each file (bash syntax!):

for a in *.vob; do transcode -i $a -x vob -z -K -y ppm -o sample -c 32-33 ; done

Note that I skip a couple of frames (here 32) because decoding of movie frames at the beginning of a vob file is not always possible correctly. (The set of VOB files is a locigal unit but the files itself are only splitted due to file/filesystem size constraints (=1GB)). Also note the -z option to flip the frames.

Then you can run pgmfindclip with:

pgmfindclip sample*.pgm

The clipping border is returned as a list of 4 comma separated values:

<top>,<left>,<bottom>,<right>

This is the correct syntax for the clipping option (-J) of transcode:

CLIP=`pgmfindclip sample*pgm`
transcode .... -j $CLIP ....

Threshold adjustment

Fully automatic clipping is not always easy. Noise in the source material or strange encoding techniques are the major sources of failure for pgmfindclip. But the tool offers you many options to manually adjust the 'automatic' process:

If the detected borders are too large or too small then you should adjust the threshold values: e.g.

pgmfindclip -t 80,200

sets the x-threshold to 80 and y-threshold to 200. "What values should I choose?", you may ask. Unfortunately there is no easy answer. You have to experiment with different values. There are also some tools that will help you:

The -v option enables the verbose mode and prints the gradient sums for each row and column of the image. Study these values and try to figure out if the sequence of values jumps at a certain point from lower to higher values. Place the threshold value between these values.

Another more visual analysis tool is enabled with the -p (for plot) option. You need an installed GNUplot for this. A gradient sum plot along the columns (x) and the rows (y) is generated and stored in EPS files. You can view this with you favorite PostScript viewer (like gv):

In the right image the case is clear. There a large peaks at the border. The horizontal case on the left is not as clear but the peaks at the border are still larger than the given threshold (dotted line).

Constrain the result

pgmfindclip has various options to constrain the calculated clipping result. You can force that the resulting image is a multiple of a given factor. Also the border can be rounded to another factor. This is useful if you want to process the clipped image with a video coder that imposes such restrictions on the input format:

Give the modulo for the target image size with the -f option. The modulo for the border is given with -b. pgmfindclip will issue an error message if the combined aligning of frame and border is not possible. The frame size will be reduced to meet the restrictions and thus the border will be enlarged. You can swap this behaviour with the -e (expand) option. Then the frame might be larger than the determined clip region.

pgmfindclip -f 16 sample*.pgm

This example enforces a modulo of 16 in both directions.

More Features

Options

Switch Purpose Default
-t <thres>[,<ythres>] Set threshold values 100,100
-s <safety>[,<ysafety>] Add a safety border 0,0 (none)
-b <modulo>[,<ymodulo>] Align clip borders 1,1 (none)
-f <modulo>[,<ymodulo>] Align output frame size 1,1 (none)
-o <offset>[,<yoffset>] Offset threshold search begin 0,0 (none)
-e Expand and do not shrink with -f  
-y Input PGM files are mplayer yuv files  
-v Enable verbose mode  
-p Plot threshold diagrams to *x.eps and *y.eps (Requires GNUplot)  
-w Draw the found border region in each image and save them as PGM files *-m.pgm