Darksoul71
26th August 2013, 09:39
Hi all,
may be this Python script is off some use for you. I found that the autocropping filter of Mplayer is quite generous with its value.
Compared to AutoCrop of AVISynth, the automated cropping of Handbrake and AVIDemux the values are often 6-10 pixels higher. This leads to questionable result because we are loosing much much image information than required.
When experimenting to automate the cropping process for my BD shrinking AutoIt script I discussed different approaches with Rumbah. At first I used also MPlayer but found Rumbah's approach of extracting images evenly distributed across the movie with ffmpeg and letting GraphicsMagic calculate the average cropping values much better. After some tinkering I copied the same approach packaged within a Python script for Linux.
Simply put the Python script posted below into a folder in your search path. Then call it with your video as argument. The script will then produce a cropping string matching the mplayer / mencoder systax to standard out.
So a typical bash statement could look like this:
CROPPING_STRING=$(autocrop "my_video.mkv")
The result in CROPPING_STRING would look like this: crop=1280:542:0:89
The rest is obvious I guess. External dependencies are ffmpeg and imagemagick. I tested the script with success under the latest Linux Mint with MATE desktop and Xubuntu 12.04 x64. Cropping is only done vertically and the cropped width is adjusted to multiple times of the value mod_by in the script. If you go for a higher value (e.g. 8 or 16) you will of course loose more image information.
If the border detection does not work perfectly for your sources you might need to adjust the fuzz value for the convert command (like 10 or 15%).
Best regards,
D$
autocrop.py:
#!/usr/bin/python
# -*- coding: utf8 -*-
# Crude Python script which performs some sort of automated cropping for various videos
# Outputs a cropping string which is compatible with mencoder and mplayer via -vf...
# Import Libraries
import sys, os
# Define value by which crop values need to be adjusted
mod_by=2
# Number of samples to be analyzed for cropping
sampleParts=20
# Get name of video file
vid_file = sys.argv[1]
# Clear up temporary jpg files
os.system ("rm -f /tmp/autocrop-*.jpg")
# Delete video info file
os.system ('rm -f /tmp/vid_info.txt')
# Get duration of video
os.system ('ffprobe "'+ vid_file + '" 2> /tmp/vid_info.txt')
vid_info = file ('/tmp/vid_info.txt', 'r')
for info in vid_info:
dur_pos = info.find ("Duration")
if dur_pos > 0:
duration = info[dur_pos+9:].strip().split(',')[0]
vid_info.close ()
# Delete video info file
os.system ('rm -f /tmp/vid_info.txt')
# Calculate complete time in seconds
dur_hrs = duration.split(':')[0]
dur_min = duration.split(':')[1]
dur_sec = duration.split(':')[2]
dur_hrs = int (dur_hrs) * 3600
dur_min = int (dur_min) * 60
dur_sec = float (dur_sec)
dur_complete = dur_hrs+dur_min+dur_sec
# Calculate segment length based on the amount of samples
segment = round (dur_complete / sampleParts)
# Generate sample jpg frames from source video
for i in range (1, sampleParts):
os.system ('ffmpeg -ss ' + str(i * segment) + ' -i "'+ vid_file + '" -vframes 1 -f image2 /tmp/autocrop-' + str(i) + '.jpg 2>1& >> /dev/null')
# Process all jpg files
# Obtain cropping information from the convert command
# The fuzzy switch with 15% is used to enhance the cropping results since omitting
# fuzzy results in worse cropping results
# For details check out here: http://www.imagemagick.org/Usage/crop/#trim
# The parameter -evaluate-sequence mean builds the average value across all
# generated sample frames
crop_info = os.popen ('nice -n 20 convert "/tmp/autocrop-*.jpg" -evaluate-sequence mean -fuzz 5% -trim info:-').read().strip()
# Process averaged crop infos
crop_resolution = crop_info.split (" ")[2]
resolution = crop_info.split (" ")[3]
crop_height = crop_resolution.split ("x")[1]
crop_top = resolution.split("+")[2]
height = resolution.split("+")[0].split("x")[1]
width = resolution.split("+")[0].split("x")[0]
# Convert strings to Integer
crop_height = int (crop_height)
crop_top = int (crop_top)
height = int (height)
width = int (width)
# Calculate crop height devideable by the mod_by value
crop_height_mod = crop_height - (crop_height % mod_by)
crop_factor = (crop_height % mod_by) / 2
crop_top = crop_top + crop_factor
crop_bottom = height - crop_height_mod - crop_top
print "crop=" + str(width) + ":" + str (crop_height_mod) + ":0:" + str(crop_top)
# Clear up temporary jpg files
os.system ("rm -f /tmp/autocrop-???.jpg")
may be this Python script is off some use for you. I found that the autocropping filter of Mplayer is quite generous with its value.
Compared to AutoCrop of AVISynth, the automated cropping of Handbrake and AVIDemux the values are often 6-10 pixels higher. This leads to questionable result because we are loosing much much image information than required.
When experimenting to automate the cropping process for my BD shrinking AutoIt script I discussed different approaches with Rumbah. At first I used also MPlayer but found Rumbah's approach of extracting images evenly distributed across the movie with ffmpeg and letting GraphicsMagic calculate the average cropping values much better. After some tinkering I copied the same approach packaged within a Python script for Linux.
Simply put the Python script posted below into a folder in your search path. Then call it with your video as argument. The script will then produce a cropping string matching the mplayer / mencoder systax to standard out.
So a typical bash statement could look like this:
CROPPING_STRING=$(autocrop "my_video.mkv")
The result in CROPPING_STRING would look like this: crop=1280:542:0:89
The rest is obvious I guess. External dependencies are ffmpeg and imagemagick. I tested the script with success under the latest Linux Mint with MATE desktop and Xubuntu 12.04 x64. Cropping is only done vertically and the cropped width is adjusted to multiple times of the value mod_by in the script. If you go for a higher value (e.g. 8 or 16) you will of course loose more image information.
If the border detection does not work perfectly for your sources you might need to adjust the fuzz value for the convert command (like 10 or 15%).
Best regards,
D$
autocrop.py:
#!/usr/bin/python
# -*- coding: utf8 -*-
# Crude Python script which performs some sort of automated cropping for various videos
# Outputs a cropping string which is compatible with mencoder and mplayer via -vf...
# Import Libraries
import sys, os
# Define value by which crop values need to be adjusted
mod_by=2
# Number of samples to be analyzed for cropping
sampleParts=20
# Get name of video file
vid_file = sys.argv[1]
# Clear up temporary jpg files
os.system ("rm -f /tmp/autocrop-*.jpg")
# Delete video info file
os.system ('rm -f /tmp/vid_info.txt')
# Get duration of video
os.system ('ffprobe "'+ vid_file + '" 2> /tmp/vid_info.txt')
vid_info = file ('/tmp/vid_info.txt', 'r')
for info in vid_info:
dur_pos = info.find ("Duration")
if dur_pos > 0:
duration = info[dur_pos+9:].strip().split(',')[0]
vid_info.close ()
# Delete video info file
os.system ('rm -f /tmp/vid_info.txt')
# Calculate complete time in seconds
dur_hrs = duration.split(':')[0]
dur_min = duration.split(':')[1]
dur_sec = duration.split(':')[2]
dur_hrs = int (dur_hrs) * 3600
dur_min = int (dur_min) * 60
dur_sec = float (dur_sec)
dur_complete = dur_hrs+dur_min+dur_sec
# Calculate segment length based on the amount of samples
segment = round (dur_complete / sampleParts)
# Generate sample jpg frames from source video
for i in range (1, sampleParts):
os.system ('ffmpeg -ss ' + str(i * segment) + ' -i "'+ vid_file + '" -vframes 1 -f image2 /tmp/autocrop-' + str(i) + '.jpg 2>1& >> /dev/null')
# Process all jpg files
# Obtain cropping information from the convert command
# The fuzzy switch with 15% is used to enhance the cropping results since omitting
# fuzzy results in worse cropping results
# For details check out here: http://www.imagemagick.org/Usage/crop/#trim
# The parameter -evaluate-sequence mean builds the average value across all
# generated sample frames
crop_info = os.popen ('nice -n 20 convert "/tmp/autocrop-*.jpg" -evaluate-sequence mean -fuzz 5% -trim info:-').read().strip()
# Process averaged crop infos
crop_resolution = crop_info.split (" ")[2]
resolution = crop_info.split (" ")[3]
crop_height = crop_resolution.split ("x")[1]
crop_top = resolution.split("+")[2]
height = resolution.split("+")[0].split("x")[1]
width = resolution.split("+")[0].split("x")[0]
# Convert strings to Integer
crop_height = int (crop_height)
crop_top = int (crop_top)
height = int (height)
width = int (width)
# Calculate crop height devideable by the mod_by value
crop_height_mod = crop_height - (crop_height % mod_by)
crop_factor = (crop_height % mod_by) / 2
crop_top = crop_top + crop_factor
crop_bottom = height - crop_height_mod - crop_top
print "crop=" + str(width) + ":" + str (crop_height_mod) + ":0:" + str(crop_top)
# Clear up temporary jpg files
os.system ("rm -f /tmp/autocrop-???.jpg")