白くなるところが真っ白になってなかったり、黒になるところが真っ黒になってないところを 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

関連記事

使ったフィルタなどの説明

使わなかったフィルタで関係するフィルタの説明

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)