たまりば

  パソコン・インターネット パソコン・インターネット  三鷹市 三鷹市

続・映像キャプチャ
2011年09月03日 19:32

前回のつづき。

Wiiでもやってみた。
NTSC信号_Wii
見ると結構いろいろなものが映っている。してみると前回のファミコン互換機は電源は入っていても接触不良か何かで何も映っていなかったと見える。
また、垂直同期信号(真ん中辺の黒い線)の左右にファミコン互換機には無かった細かい模様が見える。
これは等化パルスというもので、NTSC信号は1フィールドごとに垂直同期信号の始まる横位置が半画面分ずれるのでそれに追随するためのものである(しかし前回を見るに無くても動くのか…)。
なお等価パルスではない。英語でいうとequalizationだかqualizingだかそんな感じ。

さて次に前回やり方が思いつかないと言っていた画像化だが、プログラムを書いてみたら案外簡単にできた。
上の画像の上から2px目のラインを変換したのがこれだ。
NTSC_画像化
見え方はほぼ想像通りといったところか。
Wiiの「警告 健康と安全のために」の画面なのだが、おぼろげに分かるだろうか。
健康と安全のために
縦方向の解像度は高いので文章とふりがなの間の隙間まで映っている。横方向もどこに文字があるかくらいは分かる。
さらに、最初の画像と見比べると、垂直同期信号の左の白い線が上下方向に途切れているのが分かる。これは「続けるにはAボタンを押してください。」の部分に対応している。上下方向は時間軸なので点滅しているということだ。

今回は単純にピクセルを並べ替えただけだが、上下や時間軸方向で隣との関係を見て補完すればもっと精細な絵ができるかもしれない。
めんどいからたぶんやらないけど。


最後に今回使ったプログラムのソースを置いておく。
C#、VisualStudio2005。
エラー処理皆無。
namespace NTSCSignalParser {
public partial class Form1:Form {
public Form1() {
InitializeComponent();
numericUpDown1.Increment = 0.1M;
numericUpDown1.Maximum = int.MaxValue;
numericUpDown1.Minimum = 1;
numericUpDown1.Value = 3200;
numericUpDown2.Increment = 1;
numericUpDown2.Maximum = int.MaxValue;
numericUpDown2.Minimum = int.MinValue;
numericUpDown2.Value = 0;
textBox1.Text = @"h:\t\ntsc_wii.png";
}

private void button1_Click(object sender, EventArgs e) {
Bitmap bmp0 = new Bitmap(textBox1.Text);
Bitmap bmp = parseNTSC(bmp0, (double)numericUpDown1.Value, (int)numericUpDown2.Value);
pictureBox1.BackgroundImage = bmp;
}

private Bitmap parseNTSC(Bitmap bmp0, double pixelCount, int offset)
{
int imgWidth = 3200;
Bitmap ret = new Bitmap(320, 263);
double pos = 0;
for(int x=0;x<ret.Width;x++) {
for(int y=0;y<ret.Height;y++) {
pos = y*ret.Width+x;
pos/=(ret.Height*ret.Width);
pos*=pixelCount;
pos = Math.Floor(pos);
ret.SetPixel(x, y, bmp0.GetPixel
(((int)pos + offset)%imgWidth, 2+(((int)pos + offset)/imgWidth))
);
}
}
return ret;
}
}
}
今回感じたことだけど、Windows上でGUIのプログラムを作るなら.NETに限るね。ものすごく楽。
今回みたいな何の変哲もないGUIを作るだけなら書くことほとんどない。アルゴリズム部分を書くだけでソフトが作れちゃう。  
タグ :ソフト画像