白くなるところが真っ白になってなかったり、黒になるところが真っ黒になってないところを ffmpeg で補正する。方法はコントラストを上げて白はより白く、黒はより黒くする。今回は白黒ページの色補正だけでリサイズ(解像度を変える)、クロップ(指定範囲で切り取る)、デノイズは行わない。
自炊したときに JPG(PNG、BMP、TIFFでも可能)で出力したときに使える方法であり、PDFは ffmpeg では扱えない。一般的に Photoshop や GIMP を使う方法がよく紹介されているが、これらは一度 RGB にデコードして再度JPG出力するときに YUV に変換するので処理が遅くなりがちであるが、以下の方法は RGB 変換を挟まないので処理が早い。
基本コマンド
最近のマンガのコマンド例。真っ白と真っ黒以外に色が多い場合。
ffplay -i input -vf eq=contrast=1.5,lutyuv='st(0,gt(val,64)+gt(val,230));eq(ld(0),0)*0+eq(ld(0),1)*val+eq(ld(0),2)*255':128:128
ffmpeg -i input -vf eq=contrast=1.5,lutyuv='st(0,gt(val,64)+gt(val,230));eq(ld(0),0)*0+eq(ld(0),1)*val+eq(ld(0),2)*255':128:128,format=yuvj420p output.jpg
昔のマンガのコマンド例。白と黒だけ。他の色がある場合は色飛びする。
ffplay -i input -vf eq=contrast=2,lutyuv=val:128:128
ffmpeg -i input -vf eq=contrast=2,lutyuv=val:128:128,format=yuvj420p output.jpg
RGB画像(.png, .bmp)の場合。先にcolorchannelmixer
フィルタでグレーに色を変換する。
ffplay -i input -vf colorchannelmixer=.3:.59:.11:0:.3:.59:.11:0:.3:.59:.11:0,format=yuvj420p,eq=contrast=1.5,lutyuv='st(0,gt(val,64)+gt(val,230));eq(ld(0),0)*0+eq(ld(0),1)*val+eq(ld(0),2)*255':128:128
ffmpeg -i input -vf colorchannelmixer=.3:.59:.11:0:.3:.59:.11:0:.3:.59:.11:0,format=yuvj420p,eq=contrast=1.5,lutyuv='st(0,gt(val,64)+gt(val,230));eq(ld(0),0)*0+eq(ld(0),1)*val+eq(ld(0),2)*255':128:128 output.jpg
画像をD&Dするバッチファイル(ffmpeg のパス指定を各自書き換える)
画質設定
何も指定しなければ最適な品質指定で変換される。個別に指定する場合には-q:v [num]で 2 から 31 までの数値を指定する。小さい値ほど高画質・低圧縮・大容量で何も指定しなければframe= 1 fps=0.0 q=17.2 Lsize=N/A time=00:00:00.04 bitrate=N/A speed=0.321x
のようにコンソールに表示され、q=17.2の部分が-q:vで指定した値になる。
ffmpeg -i input -vf eq=contrast=1.5,lutyuv='st(0,gt(val,64)+gt(val,230));eq(ld(0),0)*0+eq(ld(0),1)*val+eq(ld(0),2)*255':128:128,format=yuvj420p -q:v 15 output.jpg
より正確に品質指定するときは-q:v、-qmax、-qminで同じ値を指定する。1に近いほど低圧縮大容量になる。
ffmpeg -i input -vf eq=contrast=1.5,lutyuv='st(0,gt(val,64)+gt(val,230));eq(ld(0),0)*0+eq(ld(0),1)*val+eq(ld(0),2)*255':128:128,format=yuvj420p -q:v 15 -qmax 15 -qmin 15 output.jpg
フィルタの解説
eq
フィルタでコントラストを上げる、contrast=2だと白黒だけになるので適宜調整する。lutyuv
フィルタの‘st(0,gt(val,64)+gt(val,230));eq(ld(0),0)*0+eq(ld(0),1)*val+eq(ld(0),2)*255’:128:128は Y 輝度信号が 64 以下は 0 にして、65 以上 230 以下はそのままの値にし、231 以上は 255 に変換する。後ろ2つの128:128は UV 青色と赤色成分の差分信号を 128 に変換する。- .jpg 出力なので
format=yuvj420p
でフルレンジ .jpg に指定する。
最適な値を調べるには
色が少なければコントラスト上げるだけでよいが、色が多いとコントラストを上げすぎると色が飛ぶのでコントラストを上げすぎない。圧縮率を高くするには黒と白の部分の値がどの値になるかeq
フィルタの後にoscilloscope
フィルタで調べてからlutyuv
フィルタの下限と上限を指定して 0 と 255 に変換する。
oscilloscope フィルタで値を調べる
ffplay -i input -vf oscilloscope
ffplay -i input -vf eq=contrast=1.5,format=yuvj420p,oscilloscope
ffplay -i input -vf eq=contrast=1.5,lutyuv='st(0,gt(val,64)+gt(val,230));eq(ld(0),0)*0+eq(ld(0),1)*val+eq(ld(0),2)*255':128:128,format=yuvj420p,oscilloscope
関連記事
使ったフィルタなどの説明
- 2色だけ、3色だけに減色する映像効果
- 直線上の YUV, RGB の値を表示する oscilloscope
- 映像フィルタを当てる前後のデータを見える化する
- ffmpeg でグレースケールを扱う
- eq(明暗調整)
使わなかったフィルタで関係するフィルタの説明
- リサイズ:リサイズする scale
- クロップ:映像を指定座標に切り取る crop
- デノイズ:輪郭を保護しながらシャープにしたりぼかしたりする unsharp