スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

【同じタグを付けた記事の一覧】

ADF スキャナの自動用紙サイズ検出機能向け「切り過ぎ発見スクリプト」

2010年05月17日(月)06時26分

【追記:2010/09/18】fi-6130 の「自動用紙サイズ検出」機能に関して勘違いをしていました(→「fi-6130 の自動用紙サイズ検出は傾きも補正する」)。

【追記:2010/06/06】OverCutChecker2 にバージョンアップしました

自動用紙サイズ検出

相変わらずPK-513L(裁断機)が届かないため fi-6130 をいじっています。
で、これの TWAIN ドライバに「自動用紙サイズ検出」という機能があります。
本をデジタル・データ化する際には背表紙の部分をカットしますので、ぴったり A4 や B6 等の規定サイズになるわけでなく、また毎回先頭ページを定規で測って丁度いい取り込みサイズを設定したところで、ページごとの微妙な差異や、引き込み時のズレ等によって、余分な領域の残留や、必要なデータの欠落が生じる可能性があります。
そこでこの機能をオンにしておくと、事前に用紙サイズを決めなくとも、自動的に用紙ごとの適したサイズで取り込むことができ、余計な手間を省けるようになります。

原理

原理は基本的に「黒背景」で取り込んで、外周の黒部分を除去していると思われます。
また、マニュアルの「自動用紙サイズ検出」項目の説明には、「以下のいずれかの原稿の場合、自動用紙サイズ検出ができません。」という注意書きがあり、その一つに「厚さが 52g/? 以下の薄い原稿」というものがありますので、おそらく重送検出用の超音波センサー(紙厚を計る)も使用しているんだと思います(紙厚が0ならそこは原稿ではないと判定できます)。
それと多分ですが、両面取り込みで裏面のサイズも参考にしているのではないかと思いました。
つまり、同じ紙で表面が幅 21cm あるのに裏面が 15cm しかないというのはありえないだろう、ということでそれを反映させているのではないかということです。
というのも、下半分が真っ黒とか右のふちが塗りつぶされているような原稿でもわりにちゃんと黒部分が残されており、失敗した(切り込みすぎた)のは裏も表も同様の黒枠があるページでしたので。
この「自動用紙サイズ検出」機能は検出精度を 0~3 までの4段階で設定できますので、それぞれで何処までの処理をするかは異なるようですが、少なくとも3(精度重視)の場合は、ただ単純に黒枠を消しているだけではなさそうです。

鬼門

とはいえ、こういうスキャナの自動補正機能は、特にスキャン後に原稿を捨ててしまう場合には大変危険が伴う鬼門でもあります。
他にも傾き補正や向き決定、ノイズ除去等がありますが、こういうものが自動で行われていて、オリジナルを破棄した後にそれが失敗していると気付いても、もう取り返しがつかないわけです。
もちろんビジネスでの使用などで原書も保管しておく必要があるとか、文書の形式がほぼ固定されている場合には便利な機能ですが、そうではない場合、この手の自動補正機能は全て切り、失敗の余地がないよう無加工状態で取り込んでおき、必要な加工があれば後から別にソフトウェアで行うのがセオリーです。
こうすれば後付けの加工が失敗していても、元ファイルをバックアップしておけばまたやり直せますから。

しかしながら

とはいえ「自動用紙サイズ検出」に関しては、いちいちサイズを設定する手間が省け、データの欠落を気にしなくてすむため、自分にとってはとても魅力的な機能です。
そして、場合によっては、例えば今回の自分の目的である本のデジタル・データ化に限定して考えるとすれば、割に簡単にサイズ検出ミスを洗い出すことができるのではないか?と考えたわけです。

切り過ぎ発見スクリプト

というわけで、前置きが長くなったのですが、とりあえずやっつけ作業で確認用のスクリプトを書いてみました。
原理としては、同じ一冊の本をスキャンするわけですから、各ページでそんなにサイズに差があるはずがない、つまりは直前のページ画像と横幅・高さをそれぞれに比較して、これが極端に違うようならサイズ検出に失敗して切り込みすぎたのだろうということです。
ということで、このスクリプトは、指定されたフォルダ中の画像ファイルを、(ファイル名順で)直前の画像ファイルと横幅・高さについて比較して、それぞれに差が大きいもの順に並べたリストを表示します。

使い方

下記スクリプトをクリップボードにコピー(ソースコード右上に表示されるアイコンの左から二番目をクリック)して「メモ帳」にでも貼り付けて「OverCutChecker.bat」とでも名付けて保存します。
または「OverCutChecker.txt」を右クリックで「対象をファイルに保存」して保存し、拡張子「.txt」を「.bat」に変更してください。
このとき、保存した「OverCutChecker.txt」を右クリックし「プロパティ」を見て、「セキュリティ:このファイルは他のコンピュータから取得したものです。このコンピュータを保護するため、このファイルへのアクセスはブロックされる可能性があります。」と書かれている場合は「ブロックの解除」をしてください(しなくても使えますが)。
もし必要があれば27行目の「var RankingCount=」で上位何位までを表示するかを変更できます。
後はその「OverCutChecker.bat」を画像の存在するフォルダで実行するか、画像ファイルやフォルダをドラッグ&ドロップするか、あるいは「SendTo」に置いて「送る」コマンドで使用しても便利かと思います。
WinXP 以降でないと使えません(動作確認は WinXP と Win7 でしました)。

@START MSHTA.EXE "%~f0" %*
@GOTO :EOF

<!--
ADFスキャナから自動で用紙サイズを検出する機能を使って書籍を一括で取り込んだ場合に、
原稿画像領域の切り出しに失敗した可能性のある画像を洗い出すためのスクリプト(BATファイル)です。
検査対象フォルダ内に存在する画像ファイルをファイル名順に並べ、
直前の画像ファイルとの横幅・高さそれぞれの長さの差を算出し、差が大きいもの順に表示します。
同じ本であるのに前のページとサイズが大きく異なるものは切り出しに失敗している可能性があります。
WinXP以降のWindowsで使用できます。

このBATファイルに検査対象フォルダかファイルをドラッグ&ドロップするか、
検査対象画像の存在するフォルダ内で実行してください。
レジストリは使用せず、ファイルも生成しません。
不要になった場合にはこのファイルを削除してください。
-->

<script language="JScript">document.body.innerText=""</script>

<html>

<head>
	<title>Speech BaguHitta</title>
	<hta:application id="OverCutChecker" version="100515" />

	<style type="text/css">
		/*フォントを変更。*/
		textarea{font-family:monospace;font-size:18px;}
	</style>

	<script language="JScript">

//起動時に実行される関数。
document.body.onload=function()
{
	//■結果として出力されるテキストに上位何位までを表示するかをここで変更できます。
	var RankingCount=5;

	//コマンドラインを""で囲まれていない半角スペースで分割。
	var argv=OverCutChecker.commandLine.match(/".*?"|[^ ]+/g);
	//各文字列の先頭・末尾に"があれば削除。
	for(var argc=0;argc<argv.length;argc++)if(argv[argc].match(/^".*"$/))argv[argc]=argv[argc].replace(/^"(.*)"$/,"$1");

	//引数リストから検査対象フォルダを確定。
	var SorcPath="";
	var fso=new ActiveXObject("Scripting.FileSystemObject");

	//コマンドライン引数が存在すれば検査対象フォルダとして設定。
	if(argv.length>0)
	{
		for(var argc=1;argc<argv.length;argc++)
		{
			if(fso.FileExists(argv[argc]))
				SorcPath=fso.GetParentFolderName(argv[argc]);
			else if(fso.FolderExists(argv[argc]))
				SorcPath=argv[argc];
			else
				SorcPath="";

			if(SorcPath)break;
		}
	}

	//コマンドライン引数で検査対象フォルダが確定できなければBATファイル自身のフォルダを設定。
	if(!SorcPath||!fso.FolderExists(SorcPath))SorcPath=fso.GetParentFolderName(argv[0]);

	//検査対象フォルダ最終確認。これでダメならここで終了。
	if(!SorcPath||!fso.FolderExists(SorcPath))
	{
		IdTaText.value="検査対象フォルダ「"+SorcPath+"」が確認できません。";
		return;
	}

	fso=null;

	//XPかVista以降かで画像プロパティの取得方法が異なるため、
	//事前にOSを確認しておく。バージョン6.0未満ならWinXP。
	var IsWinXP=false;
	var WinMgmts=GetObject("winmgmts:\\\\.\\root\\cimv2");
	var WinMgmtsExecQuery=new Enumerator(WinMgmts.ExecQuery("Select * from Win32_OperatingSystem"));
	for(;!WinMgmtsExecQuery.atEnd();WinMgmtsExecQuery.moveNext())
		if(Number(WinMgmtsExecQuery.item().Version.substr(0,3))<6)
			IsWinXP=true;
	WinMgmtsExecQuery=null;
	WinMgmts=null;

	//指定フォルダ内に存在するファイルの横幅・高さを取得。
	var ShellApp=new ActiveXObject("Shell.Application");
	var Folder=ShellApp.Namespace(SorcPath);
	var Files=new Enumerator(Folder.Items());
	var Pictures=new Array();
	for(;!Files.atEnd();Files.moveNext())
	{
		var Wide=0;
		var Height=0;

		if(IsWinXP)
		{
			Horizontal=parseInt(Folder.GetDetailsOf(Files.item(),27),10);
			Vertical=parseInt(Folder.GetDetailsOf(Files.item(),28),10);
		}
		else
		{
			//Vista以降の画像プロパティには先頭・末尾に不可視の非文字が付いているため取り除く必要がある。
			Horizontal=parseInt(Folder.GetDetailsOf(Files.item(),162).replace(/^[^\d]*([\d]*).*/,"$1"),10);
			Vertical=parseInt(Folder.GetDetailsOf(Files.item(),164).replace(/^[^\d]*([\d]*).*/,"$1"),10);
		}

		//横幅・高さが取得できたもの(OSが画像と認識しているもの)のみ登録。
		if(isNaN(Horizontal))Horizontal=0;
		if(isNaN(Vertical))Vertical=0;
		if(Horizontal>0||Vertical>0)
		{
			var Picture=new Object();
			Picture.Name=Files.item();
			Picture.Wide=Horizontal;
			Picture.Height=Vertical;

			Pictures[Pictures.length]=Picture;
			Picture=null;
		}
	}
	Files=null;
	Folder=null;
	ShellApp=null;

	if(Pictures.length<=0)
	{
		IdTaText.value="「"+SorcPath+"」には画像ファイルが存在しないか、画像情報が取得できません。";
		return;
	}

	//ページ(ファイル名)順に並べ替える。
	Pictures.sort(SortName);
	//最初のページには「直前のページ」か存在しないため差は0。
	Pictures[0].WideDiff=0;
	Pictures[0].HeightDiff=0;
	//2ページ目以降に直前のページとの差を設定する。
	for(var PicCnt=1;PicCnt<Pictures.length;PicCnt++)
	{
		Pictures[PicCnt].WideDiff=Pictures[PicCnt-1].Wide-Pictures[PicCnt].Wide;
		Pictures[PicCnt].HeightDiff=Pictures[PicCnt-1].Height-Pictures[PicCnt].Height;
	}

	//結果を表示。
	IdTaText.value="検査対象フォルダ:"+SorcPath+"\n\n";

	//横幅順に並べ替える。
	IdTaText.value+="■横幅"+"\n";
	Pictures.sort(SortWideDiff);
	//上から追加
	IdTaText.value+="・上位"+RankingCount+"位「ファイル名(横幅x高さ)\t[直前のページとの差]」\n";
	for(var PicCnt=0;PicCnt<RankingCount;PicCnt++)
	{
		if(PicCnt>=Pictures.length)break;
		IdTaText.value+=Pictures[PicCnt].Name+"("+Pictures[PicCnt].Wide+"x"+Pictures[PicCnt].Height+")";
		IdTaText.value+="\t["+Pictures[PicCnt].WideDiff+"]\n";
	}
	//下から追加
	IdTaText.value+="・下位"+RankingCount+"位「ファイル名(横幅x高さ)\t[直前のページとの差]」\n";
	for(var PicCnt=1;PicCnt<RankingCount+1;PicCnt++)
	{
		var RevCnt=Pictures.length-PicCnt;
		if(RevCnt<0)break;
		IdTaText.value+=Pictures[RevCnt].Name+"("+Pictures[RevCnt].Wide+"x"+Pictures[RevCnt].Height+")";
		IdTaText.value+="\t["+Pictures[RevCnt].WideDiff+"]\n";
	}

	IdTaText.value+="\n";

	//高さ順に並べ替える。
	IdTaText.value+="■高さ"+"\n";
	Pictures.sort(SortHeightDiff);
	//上から追加
	IdTaText.value+="・上位"+RankingCount+"位「ファイル名(横幅x高さ)\t[直前のページとの差]」\n";
	for(var PicCnt=0;PicCnt<RankingCount;PicCnt++)
	{
		if(PicCnt>=Pictures.length)break;
		IdTaText.value+=Pictures[PicCnt].Name+"("+Pictures[PicCnt].Wide+"x"+Pictures[PicCnt].Height+")";
		IdTaText.value+="\t["+Pictures[PicCnt].HeightDiff+"]\n";
	}
	//下から追加
	IdTaText.value+="・下位"+RankingCount+"位「ファイル名(横幅x高さ)\t[直前のページとの差]」\n";
	for(var PicCnt=1;PicCnt<RankingCount+1;PicCnt++)
	{
		var RevCnt=Pictures.length-PicCnt;
		if(RevCnt<0)break;
		IdTaText.value+=Pictures[RevCnt].Name+"("+Pictures[RevCnt].Wide+"x"+Pictures[RevCnt].Height+")";
		IdTaText.value+="\t["+Pictures[RevCnt].HeightDiff+"]\n";
	}

	Pictures=null;
}

//ファイル名順で並び替え。
function SortName(a,b)
{
	if(a.Name==b.Name)return 0;
	return(a.Name>b.Name?1:-1);
}

//横幅差順で並び替え。
function SortWideDiff(a,b)
{
	//差がある場合には、差の大きい方が上位に来るように。
	if(a.WideDiff!=b.WideDiff)return(a.WideDiff<b.WideDiff?1:-1);
	//差がない場合には、ファイル名順で。
	if(a.Name==b.Name)return 0;
	return(a.Name>b.Name?1:-1);
}

//高さ差順で並び替え。
function SortHeightDiff(a,b)
{
	//差がある場合には、差の大きい方が上位に来るように。
	if(a.HeightDiff!=b.HeightDiff)return(a.HeightDiff<b.HeightDiff?1:-1);
	//差がない場合には、ファイル名順で。
	if(a.Name==b.Name)return 0;
	return(a.Name>b.Name?1:-1);
}

	</script>

</head>

<body>
	<div style="text-align:center;width:100%;height:100%;">
		<textarea id="IdTaText" style="width:99%;height:99%;"></textarea>
	</div>
</body>

</html>

アンインストール

レジストリの変更はおろかファイルすら作りませんので、BAT ファイルを削除するだけです。

結果

以下のような文章が表示されますので、リストアップされたファイルの怪しそうなものを手動で確認していくことになります。

検査対象フォルダ:C:\Pictures\Temp

■横幅
・上位5位「ファイル名(横幅x高さ)	[直前のページとの差]」
p0063.jpg(3152x4287)	[60]
p0003.jpg(3192x4276)	[56]
p0009.jpg(3176x4280)	[40]
p0061.jpg(3160x4293)	[40]
p0007.jpg(3184x4280)	[32]
・下位5位「ファイル名(横幅x高さ)	[直前のページとの差]」
p0062.jpg(3212x4290)	[-52]
p0002.jpg(3248x4270)	[-44]
p0032.jpg(3208x4281)	[-36]
p0076.jpg(3168x4290)	[-32]
p0068.jpg(3176x4289)	[-32]

■高さ
・上位5位「ファイル名(横幅x高さ)	[直前のページとの差]」
p0066.jpg(3168x4228)	[59]
p0059.jpg(3172x4271)	[25]
p0125.jpg(3192x4268)	[19]
p0108.jpg(3180x4288)	[18]
p0134.jpg(3216x4290)	[18]
・下位5位「ファイル名(横幅x高さ)	[直前のページとの差]」
p0068.jpg(3176x4289)	[-36]
p0127.jpg(3212x4294)	[-27]
p0067.jpg(3144x4253)	[-25]
p0095.jpg(3172x4310)	[-24]
p0109.jpg(3188x4308)	[-20]

注意

注意しなければならないのは、リストアップされたファイルだけでなく、その前後のいくつかのファイルも確認する必要がある、ということです。
例えばA~Fの6枚の画像ファイルがあったとして、そのうちの「C・D・E」が「切り過ぎ」であったとしても、リストアップされるのはCとFの2枚になります。
なぜなら「直前のページとの差分」ですので、直前のページも同様に「切り過ぎ」であった場合、差として出てこないからです。
ですので上記の場合リストアップされたCだけでなく、それに続くDとEも取り直す必要があり、逆にFはリストアップこそされていますがサイズは正常ということになります。

余談

BTScan という、ADF スキャナから連続取り込みして連番をつけて保存してくれる非常に便利なフリーソフトウェアがあるのですが、それを使って fi-6130 から取り込む際に、この「自動用紙サイズ検出」を有効にすると、「ご使用のアプリケーションは、後端検出、もしくは自動サイズ検出に対応していない可能性があります。アプリケーションの開発元にお問い合わせになるか、アプリケーションのオプションの自動用紙長検出をオンにしてください。」というような警告メッセージが出てきます。
別にちゃんと検出済みの画像が保存されるのですが。

【追記:2010/06/06】OverCutChecker2 にバージョンアップしました

関連記事

【同じタグを付けた記事の一覧】
自作ソフト ポータブル 画像管理 電子ブック OverCutChecker

スポンサーサイト

コメントの投稿

非公開コメント

最新記事
最新コメント
Amazonおまかせリンク
カテゴリ
タグクラウド
Amazonお買い得ウィジェット
カレンダー
09 | 2017/10 | 11
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 - - - -
月別アーカイブ
プロフィール

電脳太助

Author:電脳太助
Website:電脳スピーチ web

RSSリンクの表示
メールフォーム

名前:
メール:
件名:
本文:

サイト内検索
Ads by Google
FC2アクセスランキング
Ads by Google
FC2拍手ランキング
ユーザータグ

音楽管理(66)
ポータブル(57)
ソフト紹介(44)
プログラミング(42)
音声技術(41)
自作ソフト(35)
サイト運営(32)
FC2(31)
ブログ(30)
iTunes(27)
Windows(25)
LISMO(24)
音声合成(23)
音声認識(22)
x-アプリ(22)
電子ブック(22)
eラーニング(20)
バックアップ(19)
語学学習(19)
foobar2000(18)
ソースコード(18)
WindowsLiveWriter(15)
画像管理(15)
C++(14)
アフィリエイト(10)
DnspTools(10)
fi-6130(9)
FLAC(9)
JavaScript(9)
ウォークマン(9)
英語音読学習計画(8)
Gracenote(8)
Prolog(8)
ベクター(8)
雑記(8)
CodeBlocks(7)
SyntaxHighlighter(7)
TraConv(7)
spcbght(7)
wxWidgets(7)
VirtualBox(6)
W63CA(6)
DCP-J552N(6)
WinRT(6)
WindowsLiveMesh(6)
iGoinLM(6)
英語発音矯正実験(6)
ExactAudioCopy(6)
MP3Gain(6)
LAME(5)
音楽技術(5)
Mery(5)
楽器演奏(5)
GalateaTalk(4)
nLite(4)
WindowsLiveSkyDrive(4)
ホームページ(4)
GalateaProject(4)
MIDI(4)
LLVM(4)
PC-98(3)
カウンター(3)
AACGain(3)
iTCDini(3)
OverCutChecker(3)
拍手(3)
PK-513L(3)
UniversalExtractor(3)
アクセスランキング(3)
ImageCompositeEditor(2)
アクセス解析(2)
OCR(2)
qtaacenc(2)
資格試験(1)
AquesTalk(1)
AquesCmdDl(1)

FC2アクセスランキング
最新トラックバック
アクセスランキング
[ジャンルランキング]
コンピュータ
161位
アクセスランキングを見る>>

[サブジャンルランキング]
ソフトウェア
19位
アクセスランキングを見る>>
FC2カウンター
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。