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), 站内

这一期的节目,让我们把镜头对准杭州市西北角这所理工院校蓝田住宿区的男生浴室。

从表面上看,这只是一个普通、新建的浴室。四周密布的管道small便槽,连着蓬头的喷管,无一不向人们诉说着它那理工科特有的阳刚。但是就这样一个浴室,却有着让人无法解开的迷,这个迷,到底是什么呢?

(广告被屏蔽)

画面开始:几个精壮的汉子,小心翼翼地调试着两个金属阀门。奇怪的是,他们都采取的是同一种姿势,这是一种极其古怪的姿势,让人看不出他们是在洗澡,反而会联想到是在点燃一个引线极短的炸药包。每一条胳膊像被什么东西抓住似的,伸展到一个不可思议的长度,身体却向着相反的方向,仿佛在竭力逃避着什么。

过了好久,他们还是保持着这个姿势,不由得让人想起二战里最勇敢最敬业的工兵。水哗哗地从那个斑驳裸露的钢管中流出来,他们偶尔会用手快速地伸进水柱里,然后再以迅雷不及掩耳的速度抽出。谁也不知道,就在这一瞬间,这些勇士们的经历已经是冰火九重天。有的人,被冰凉的水激得直打冷战,有的人,已经有好几处被滚烫的水烫得火红。

可是,为了洗澡,这些勇敢的人们还在坚持着,坚持着…

我们的节目,就此展开….

首先我们分析一下这个浴室的供水系统:从画面上我们可以看到,这个浴室的供水系统相当的原始,是最普通的二合一式。一根管道通的是凉水,一根管道通的是热水,两根管道上各有一个阀门,通过这两个阀门,两股水流合为一股,再从管口流出。

按常理来说,这样的温控系统虽然原始,却也简单。按一个公式来说,出口处温度T=热水管温度乘以体积系数+冷水管温度乘以体积系数。通过调节两个阀门来控制冷热水的体积系数,来达到控制水温的目的。

可是,事实,真的有这么简单吗?

让我们来采访几个当事人吧

我:请问,你觉得这个温度调节系统的控制简单吗?
龙套甲:我从来没有见过这么诡异的调温系统,从那个管子里喷出来的水不是冰冰凉就是可以烫死猪。
我:OK,谢谢你,同学,我们再来采访一下其他人

我:请问,你的感受和刚才那位同学一样么?
龙套乙:是的,它是我见过最不合常理的龙头。我是学自动控制的,可是我总是无法解释这个龙头的工作原理。按我学的知识,阀门的调节是一个模拟量,可是管口喷出来的水却绝对是一个数字量,它只有“烫”和“凉”两个状态,精确如二进制里的0和1。

龙套丙插话:对的,我曾经把我们实验室的示波器拿到这里,接上温度感应器来测试水温的波形。结果,我得到的不是三角波,也不是正弦波,而是…方波!!!

我:有这么离奇吗?那么,有没有人成功地将水温调到过一个正常的状态?
龙套丁:有,第一个成功的人,那是我们系的传奇人物。(旁边有人插话:他是光电系的)他毕业的时候,简历上只有这么一句话:我曾经成功地将紫金港蓝田澡堂的水温调节到正常范围。就凭这句话,瑞士好几家钟表企业请他去做技师,德州电子仪器也高薪发来了OFFER,结果他一个都没有看上。

我:那么他现在在干什么呢?
龙套丁:他就凭这只手上的功夫,开别人的保险柜就像开公共厕所的门一样方便。如今已经是神龙见首不见尾,唯见长江天际流…

我:那么,他以后,还有人成功过吗?
龙套丁:有,这位师兄毕业前,把他的独家秘笈传授给了我们。据他说,在这冰与火之间,是存在一个临界点的。当我们把双手练到比市面上最精密的扭距仪还要精确的时候,我们就能发现它了。

这个临界点,师兄给它命名为G点。多少年来,紫金港都流传着这样一个传说:当你触及这个神秘的G点的时候,当那传说中的上帝之水蓬勃而出的时候,你会感觉到无上的快乐,那是一种能让你忘记一切的感觉,为了那一刻的快乐,值得我们倾其所有。是的,倾其所有。所有经历过的人都是这样说的。

画外音起:一个普通的工科院校,一个新建的浴室,却藏着惊天大秘密。一个最简陋的温度调节系统,却可以得出精确的数字量,难道大自然里有蕴涵着天然的AD调节器吗?这么神秘的浴室,却有那么多人排队进入,他们是为了什么?那个传说中的G点,真的存在吗?这一切的一切,都让我们感觉如此的神秘。

谜底该怎样解开?这一切的一切,都是因为什么?请收看下集走进浙大

9 Responses to “暂停党什么的最讨厌了”
  1. think says:

    请问朋友试过imgseek-server没,我尝试在centos5上安装,总是通不过,希望能得到你的帮助,谢谢!

  2. clover says:

    附件犀利了.. 在家颓废许久来shi哥这里揉揉我的蛋

  3. hzqtc says:

    邮件提醒直接被gmail归类到垃圾邮件里了,shi哥犀利!

  4. LCLL says:

    shi哥扎实-。-附件搞笑

  5. hzqtc says:

    好象很好玩啊,可是无图无真相

  6. fancy says:

    旹哥你又疼了……

  7.  
Leave a Reply