Posts Tagged “mplayer”

ACFUN上经常有一些考验暂停党的图集视频,内含各种哔哔和◯◯,但是对于反射弧比较长,暂停苦手的人们来说,只得反复折腾得肉牛满面。而我这种暂停四级考试完全不合格的人更是鸭梨很大。于是想到求助perl, imgseekmplayer,把视频中的所有图片提取出来。思路很简单,就是首先用mplayer将视频内容转为一帧一帧的png或jpg图片(视频分帧),再用Image::Seek来通过图片内容的相似度比较去除重复图片。写了一段简单的perl代码(wapauser.pl):

#!/usr/bin/perl

use strict;
use constant SCORE => -30;
use File::Temp qw(tempfile tempdir);
use Image::Imlib2;
use Image::Seek qw(loaddb cleardb add_image query_id remove_id);
use POSIX ':sys_wait_h';

our ($id, $db, $dir);

sub init {
	$id = 0;
	$dir = tempdir('wapauserXXXX', CLEANUP => 1, DIR => '.');
	$db = tempfile('wapauserXXXX', DIE => $dir, SUFFIX => 'db');
	loaddb($db);
	cleardb();
}

sub gao {
	my $file = shift;
	my $img = Image::Imlib2->load($file);
	add_image($img, $id);
	my @result = query_id($id, 2);
	if (!$id || $result[1]->[1] > SCORE) {
		++$id;
		link $file, sprintf './output/%04d.png', $id;	# or `cp`
	} else {
		remove_id($id);	# important
	}
}

sub wapauser {
	my ($file, @args) = @_;
	init();
	if (my $pid = fork) {
		wait;
		opendir(my $dh, $dir);
		my @pngs = grep {/\.png/} readdir($dh);
		closedir($dh);
		for my $png (sort @pngs) {
			gao("$dir/$png");
		}
	} else {
		chomp(my $path = `which mplayer`);
		unshift @args, '-vo', "png:outdir=$dir", '-nosound';
		print STDERR "path = $path\nfile = $file\n", join("  ", @args), "\n";
		close STDOUT;
		close STDERR;
		exec $path, $file, @args;
	}
}

wapauser(@ARGV);

拿某个长度4min的flv视频测试了一下,第一步和第二部分别花了4min的时间,最后从6000多帧中提取了70多张不同的图片。实验表明,SCORE的阀值大概取到-25~-30比较合适,具体的值还是要反复尝试。大多数相同的图结果都在-35以上,但也有可能只有-31。不同的图通常区别都在-15以内,但是只有一些小区别的几张图(你们懂的)之间的区别可能有负的二十多。总的来说还有以下问题:

  • 视频分帧结束后才开始图片去重,实际上两步可以同时进行,分步的结果就是得先消耗很大的临时空间来存储成千上万帧的图片,上面的测试就吃掉了4G的硬盘;
  • 生成的图片是非常大png,这也是为什么会吃掉那么多磁盘的原因,当然这可以通过设置参数z=<0-9>改成压缩较高的png,或者用参数-vo jpeg,并设置参数quality=<0-100>改成较小的jpg;
  • 这种方法只能处理完全静态的图集视频,对其它视频要么无能为力,要么作用很有限;
  • 生成的图片质量取决的视频质量,所有除非是高清视频,否则图片质量不会太好;
  • SCORE阀值的设置……凡是涉及到阀值的问题总是很头疼的,稍微高点低点,效果可能就差很多,这就像调试蓝田的热水一般(典故见附件)。

附件:我刚进浙大不久时的一篇文章《走进浙大—揭开蓝田浴室之谜》,想起来当时我们一看见校医院的救护车从蓝田方向开来就会说“又有人洗澡被烫伤了”……

发信人: botanyh (botany), 信区: Joke
标 题: 走进浙大—揭开蓝田浴室之谜ZZ
发信站: 缥缈水云间 (Mon Oct 30 11:33:02 2006), 站内

Comments 9 Comments »

要装扮一下自己的blog,最重要就是选择一个合适的主题。wordpress有着无数的免费与收费主题,但是要找到一个自己心满意足的却并非易事。当然如果你是一个css高手的话,自然能轻松搞定一切,可惜我不是,我只能找一个足够合适的主题作为一个高起点。首先当然是从wordpress的Free Themes Directory入手,很可惜,我在这里要么是搜不到满足我条件的主题,要么是安装后实际效果不理想。于是我开始求助搜索引擎,并搜到了更多的主题,依然很可惜,这些主题或者不符合我口味,或者定制性太差,或者同我blog内容结合在一起比较违和。最后,我开始用关键字搜一些同好用workpress架的blog,看看他们都用啥主题,企图rob一个合适的。搜寻过程拜到各种技术宅,包括自己写主题,插件的,还有自己做出一套华丽的素材的,无限orz。我就这样找啊找啊,找了整整三天之后,我才找到现在用的主题——mandigo

mandigo是一个在我看来非常不错的主题,首先它是fixed-width的,这样可以有效逃避自己精心打扮的blog在别人浏览器里崩掉的悲剧。它的定制性也不错,本身就有好几套不同的配色可以选择,还支持随机配色,不过我当然是毫不犹豫地选了现在的这个pink配色。最主要的还是对title和background图片个性化的支持。title的图片也支持随机功能,只要把备选图片放到指定目录下就可以了,都不用自己来实现了。

最后就是挑选背景图片了,总是搬运来搬运去的,也该到自己动动手的时候了。当然事实是我在自己的收藏,百度、google的搜索结果中都没能找到中意的。不过搜索中发现《东方活动写真馆》的截图主调确实和blog满搭配,于是自己用《东方活动写真馆》做一个。考虑到只用一张截图实在太单调了,于是用许多截图平铺起来。

首先获得截图,每秒钟来一张,利用mplayer可以轻松搞定。我写的比较圡,我想应该可以用一行脚本搞定的。

for i in `seq $1`
do
    mplayer -ss $i -noframedrop -nosound -vo png -frames 1 /media/temp/VIDEO_TS/VTS_02_1.VOB
    mv 00000001.png $i.png
done

然后利用imagemagick处理获得的截图,把过多的白边去掉,然后缩小图片并存成jpg。imagemagick是一个强大的图像处理工具,并且有很好的perl支持。

#!/usr/bin/perl -w

use strict;
use warnings;
use Image::Magick;

for my $file (@ARGV) {
    my $image = Image::Magick->new;
    $image->Read($file);
    $image->Crop(
        width => 700, height => 400,
        x => 80, y => 50);
    $image->Scale(
        width => 420, height => 240);
    $file =~ s/png$/jpg/;
    $image->Write($file);
}

最后随机选一些图片纵向平铺合成一张大的背景图片,依然通过perl脚本,借助imagemagick实现。这一步要人肉做的话不知有多痛苦……

#!/usr/bin/perl -w

use strict;
use warnings;
use Image::Magick;

sub randfile() {
    return sprintf '%08d.jpg', 15 + int rand 227;
}

srand;
my $n = 16;
my $size = sprintf '420x%d', 240 * $n;
print $size;
my $image = Image::Magick->new;
$image->Set(size => $size);
$image->Read('NULL:blank');
for (my $i = 0; $i < $n; ++$i) {
    my $img = Image::Magick->new;
    my $file = &randfile;
    print "$file\n";
    $img->Read($file);
    $image->Composite(
        image => $img, compose => 'Over',
        x => 0, y => 240 * $i);
}
$image->Write('gao2.jpg');

然后多随机几次,选个感觉最好的,上传并设置为blog的背景图片,大功告成^ ^

Comments 6 Comments »