文字の書かれている画像から文字を読み出し、その画像のメタ情報にその文字列を埋め込んで、その画像を画像内の文字で検索できるようにするツール


## 画像内文字検索ツールの背景
リモート会議も増えて、会議中の画像のスナップショットを撮る事が多くなった人も多いと思います。
しかしここで問題があります、それらの画像が検索できないことです。そこで、このままでは検索できない画像内の文字を、その画像のexif情報に事前に埋め込んでおくことで、画像を検索可能にする環境を構築してみます。
ビデオ会議などのスナップショット画像で溜め込む人には、お勧めのツールだと思います。

## 完成品動作のイメージ
エクスプローラーの通常の検索機能で画像が検索できます。
会議の画像とかが大量に溜まっている中からテキストで検索し、それにヒットした画像のみが表示されています。
また画像ファイル名と同名のテキストファイルができていて、そこに読み取れた文字列が書かれているので、このテキストを使うと議事録作成が加速できます。
![SnapP50_NoName_2022-1-3_20-28-42_No-00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3968/4e161ee8-fb81-9e42-e354-5d13896f1e21.jpeg)

## 環境構築

## 各ツールのインストール

- **ugrep** : UTF8環境で漢字が検出できるgrepとして使っています。
  https://github.com/Genivia/ugrep
  から/bin/win64/ugrep.exe をダウンロードし、自分のpowershellから ugrep.exe が起動できるように、PATHが通っている場所に配置します。
  powershellからの操作で
  PS > ugrep --version
  ugrep 3.3.12 WIN64 +avx2 +pcre2_jit +zlib +bzip2 +lzma +lz4 +zstd
  License BSD-3-Clause: <https://opensource.org/licenses/BSD-3-Clause>
  Written by Robert van Engelen and others: <https://github.com/Genivia/ugrep>
  とか出ればOKです。

- **ugrepのman** のpage (参考用)
https://manpages.debian.org/unstable/ugrep/ugrep.1.en.html

- **tesseract**  :OCRリーダーソフトです、私は64bit版を使いました。
	https://github.com/UB-Mannheim/tesseract/wiki
	tesseract-ocr-w64-setup-v5.0.0-alpha.20210811.exe を起動します。
	導入時にはjapanese dataを追加します
	Additional script dataで Japaneseを追記します。
	導入後にコントロールパネル > システム > 関連設定の　システムの詳細設定 > 環境変数(N)... > Path環境変数 > 編集(E)... >   
	C:\Program Files\Tesseract-OCR のpathを追加
	powershell上で tesseract.exe と打って、動作確認できることを確認します。
	動作確認コマンド例: `tesseract.exe a.jpg a \l jpn` と打つと a.txt という OCR読み取り結果のファイルが作られます。
	
- **exiftool** :jpgファイルにテキスト情報を埋め込むのに使用します。
https://exiftool.org/ からダウンロードしてください、ここでは exiftool(-k).exe を exiftool.exe にリネームして使用しています。exiftoolにはいつくか異なった実装があり、挙動がちょっとづつ違うようなので、このexiftool以外での動作は未確認です。
- powershellのコード本体

```powershell:embedTextFromImage.ps1
# embed Text from Image file

Get-ChildItem . -Filter *.jpg -Recurse |
Foreach-Object {
	$textinfo= exiftool.exe -ImageDescription $_.FullName
	if ($textinfo.Length -lt 2) {	    # 既に処理したjpgはスキップ
		$updateTime = (Get-ItemProperty $_.FullName ).CreationTime
		Write-Host "updatetime" $updateTime 
		tesseract.exe $_.FullName $_.Fullname.Replace(".jpg","")  -l jpn
		$newTextFileName =  $_.FullName -creplace ".jpg", ".txt"
		$xpcomment = ""
		$xpcomment += ugrep.exe -ohiE [あ-んア-ンA-Za-z0-9]* $newTextFileName
		$xpcomment = " -IFD0:ImageDescription="+$xpcomment
		$xpcomment = $xpcomment.Replace(" ","").Replace("・","")
		$commands = $xpcomment+"  "+$_
		Write-host "xpcomment " $commands 
		exiftool.exe  $xpcomment $_.FullName  -overwrite_original_in_place
		(Get-Itemproperty $_.FullName ).set_LastWriteTime($updateTime) # jpgのタイムスタンプを作成時の時間に戻す.
		(Get-Itemproperty $newTextFileName).set_LastWriteTime($updateTime) # txtのタイムスタンプをjpgに合わせます.
	} else {
		Write-Host "Skipped " $_.FullName
	}
} 
```

## このツールの動き
- 画面ショットを撮ったディレクトリで起動すると、再帰的にそこにある画像と同じ名前のテキストファイルを作成しそこに読み取った文字情報を保存します。
- また画像のタイトルのメタデータにその抽出したテキストを埋め込みます。
- そのメタデータは、改行なしの、1行に圧縮されたテキストです。
- 一度テキストが埋め込まれた画像は二度目の処理はスキップします。
- テキストファイルのタイムスタンプは、画像の持つタイムスタンプと同じです。
- テキスト埋め込まれたかどうかは画層の右クリック > プロパティ(R) > 詳細タブ > タイトルと件名を見ると分かります。 

## 使い方例
ビデオ会議中に、URLのような長い文字列や、表のような文字の塊が出てきた時に、画面ショットを撮ったら、このツールを起動して、画像の文字化をして、そのテキストをその場で利用します。
会議終了後に、議事録を作る時に、画面ショットから作ったテキストファイルを下地として利用して議事録を作ります。
議事録ができたらテキストファイルを削除します。
Windowsのインデックス機能に依存しているので、画像の置き場はドキュメント・フォルダー以下にしておいてください。
## まとめ
- 画像検索がとても高速化できました、過去のビデオ会議の画像の検索が簡単にできます、ついでに議事録起こしも速くなりました。
- EXIFにはコメントというメタタグもあって、そちらの方がコメント情報の埋め込みに良さそうでしたが、漢字があると受け付けられなかったのでタイトル欄に埋め込むことにしました。
- PowerShellで作りましたが、Windows依存性は低いので、macやlinux版も作れると思います。
- exifで日本語データの埋め込みには、いろいろ試行錯誤が必要でした。exiftoolの引数の`=`の前後にはスペースを入れてはいけないようです。

### 参考リンク
- Tesseract OCR をWindowsにインストールする方法
https://gammasoft.jp/blog/tesseract-ocr-install-on-windows/
- ExifTool.exe の簡単な使い方 － 表示編
https://kokufu.blogspot.com/2010/12/exiftool.html



**以上**