2009年10月3日土曜日

番外 MXのL字を消してみよう パート2

※この記事の処理は推奨しません。こちらを参照して下さい


追記
そらのおとしもの1話のL字で、縞解消を行なうと不都合があったので、deletterlcrop_szのみ修正しています。

前回L字消し記事を書いておきながら、他局やBDなどで補完、あるいはそもそもL字があったアニメに興味がないなどで、自分で実用的に使うことが1度もなかったけれど、MXのみ高画質でBDなしという例も多々あるので、いきなりL字(しかも事件でも災害でもない)炸裂だった超電磁砲を機会に見直してみよう。

といっても、やることは同じなので精度の向上と使いやすさを優先。改良の余地はまだあるだろうし試行錯誤途中のコードも残っているけれど、α版程度の気分で。

おかしいと思う点は適当に修正して下さい。それなりにavisynthを日常的に使っている人であれば、処理の内容を理解しなくても手順通りにやることでそれなりの結果になるようにしたつもり。

利用するfunction群

function showfieldnumber(clip c) {
return c.separatefields().ScriptClip(
\ "SubTitle(String(current_frame), size=90)")
}
function showframenumber(clip c) {
return c.ScriptClip(
\ "SubTitle(String(current_frame), size=90)")
}
function deletterl_f(clip c, int s, int e, int f) {
r = (f <> e) ? 0 :
\ ((f >= s && f <= s+30) ? 1 + f - s :
\ ((f >= e-30 && f <= e) ? 1 + e - f : 31))
w=5.809
h=2.178
return c.Lanczos4Resize(
\ 1440, 540, w*r, 0, 1440-w*r, 540-h*r)
}
function deletterl_sz(clip c, int s, int e) {
ft = "deletterl_f(" + String(s) + "," +
\ String(e) + ",current_frame)"
return c.ConvertToRGB24().ScriptClip(
\ "deletterl_f(" + String(s) + "," +
\ String(e) + ",current_frame)"
\ ).ConvertToYUY2()
}
function deletterl(clip c, int s, int e) {
return c.ConvertToYUY2(interlaced=true).
\ separatefields().
\ ApplyRange(s, e, "deletterl_sz", s, e).
\ weave()
}

function deletterlcrop_sz(clip c, float l) {
w = c.width()
h = c.height()
return c.Lanczos4Resize(w, h,
\ l, 0, w - l, h - (l*float(h)/float(w)))
}
function deletterlcrop(clip c, int s, int e, float "l") {
l = default(l, 30)
return c.ApplyRange(s, e, "deletterlcrop_sz", l)
}

ステップ 1

はじめに、リサイズやインタレ解除等なしでL字の開始位置と終了位置を確認。

showfieldnumber()

だけを追加し、avsを読み込んで表示できるツールでL字の開始と終了フィールドの数値を記録する。フィールドに分けているので1440x540に潰れた状態になります。

開始位置とは青いL字が出現する最初のフィールド。終了は青いL字が見える最後のフィールド = L字が完全に消えるフィールドの一つ前です。

以下説明のため、開始フィールドが14107, 終了フィールドが18710の場合として記述します。

ステップ 2

ロゴ削除処理用に、L字で削られたエリアを取り除く。

deletterl(14107, 18710)

showfieldnumber()はもう不要です。ステップ1で確認した数字を指定するだけです。この状態でL字が映像に少し食い込んでいる部分は残りますが、絵の位置やサイズがL字がない時の状態に戻ります(といっても当然ながら劣化は残る)。

やっかいなところはこれで終わりなので、あとは好きなように処理すればよいだけですが、ステップ3以降は食い込んだL字部分も取り除く一つの方法を紹介

ステップ 3

適当にロゴ削除とかインタレ解除を行なった上で、食い込みL字を消す範囲を確認。ここ以降、赤字部分は自分の環境に合わせて置き換えてください。

deletterl(14107, 18710)
delogo_mx()
#アプコン縞解消をする場合はこのタイミング
fps24p()
showframenumber()

フレーム毎に数字が表示されるので、L字の残骸が見え始めるフレームが存在するカットの最初のフレームと、消えるカットの最後のフレームの数字を確認します。カット単位で処理するのは、絵を少し拡大する加工を行なうわけで、カットの途中で切り替えるとその変化が見えてしまうのを回避するためです。結果的にL字の影響がないフレームまで一部が切り取られてしまうけれど、人が視聴する映像なので、気になる問題を残さないことを優先。

以降開始フレームが5564、終了が 7533だった場合として説明します。

ステップ 4

ステップ3で確認した範囲のフレームの左と下を削ります。

deletterl(14107, 18710)
delogo_mx()
#アプコン縞解消をする場合はこのタイミング
fps24p()
deletterlcrop(5564, 7533)

最終的に通常の処理に2行を追加するだけで、そこに記述する数字の確認方法を冗長に説明した形。

削る量は調整が可能で

deletterlcrop(5564, 7533, 30)

のように最後に削る量を指定できます。初期値は30。小さくすると削る量が減ります。縦横比維持優先で指定は一つだけ。L字によって左側より下の方が比率として広く絵が削られるため、横は必要以上削る形になります。

流石に通常の場所ほど綺麗にロゴ消しできるわけでもないけれど、気にならない感じにはなり、それでも気になるならその範囲を少しぼかすのもあり。

L字状態中のロゴデータを作ることで、L字のせり出し以外の部分はもっと綺麗に消すこともできそうだけど複雑で面倒な上、BD買った方が確実に綺麗で時間も無駄にならないということで、このあたりが妥協点かな。


注意点

1440x1080決め打ちなのでHD放送専用。マルチ編成時は頑張ってなんとかして下さい。

キャプチャ環境などで微妙に横位置がずれる場合、若干悪い結果になる可能性がありそう。

昨日の超電磁砲しかL字のデータでチェックしていないので、他のL字でもこのままでよいか不明。運良く(むしろ「運悪く」か)今後のL字放送で改善できるような点が見つかれば更新するかも。

個別の処理の説明は秋新番が出揃った後、時間に余裕があれば加筆予定。(こういう表現の時はやらない可能性が高い)