卒業研究で画像からの人検出をやろうとしてる学生に INRIA Person dataset をすすめたら,「OpenCV の imread で画像が読み込めない.調べてみたら,libpng のバージョンを下げたら解決するという話があった( http://stackoverflow.com/questions/25543930/libpng-error-idat-invalid-distance-too-far-back-in-mac-osx-10-9 ).けど,どうしたらよいかわからない」という相談を受けました.
で,いい解決法はないかと探ってみたところ,最近の libpng ( libpng Home Page )で配布されてる pngfix というコマンドを使えば一発っちゅうことがわかりました.ググってもすぐ出てくる情報でもないみたいなので,メモっときます.
2015-09-30 追記: pngfix 使えば無事解決と思ったら,それではだめでした.結局,別のコマンドを使うことになりました.下の方の optipng の話を参照してください.
MacPorts で libpng 1.6.18 を入れてるたかたかの環境では,/opt/local/bin に pngfix ってコマンドがインストールされてます.引数にファイル名を指定して
$ pngfix hoge.png
とするだけでOK.hoge.png をチェックして,問題のあるものだった場合は自動で修正してくれます(引数なしで実行するとマニュアルが出てきます).上述の INRIA Person データセットの場合は,PNG画像を含むディレクトリで
$ pngfix *.png
したら直ったようです.
どうしてうまく読み込めない画像があるのか,その理由についてちゃんとは理解してませんが,古いPNG画像の中に,zlib がらみで何か問題があって,最近の libpng を使って読み込もうとするとエラーになってしまうものがある,ということのようです.OpenCV や ImageMagick は libpng に頼ってるので,OpenCV の imread も ImageMagick の display も,そういうPNGのファイルを読ませるとエラーを吐く,と.ちなみに,Mac OS X Yosemite の「プレビュー」は,そういうファイルでも普通に表示するようです.
というわけで,PNG画像の読み込み時にエラーが出たら pngfix を試してみましょう.
と思ってたら,pngfix 使っても直ってないファイルがあることが判明.再度いろいろ調べてみたら,OptiPNG ( OptiPNG Home Page ) というツールが使えそうだとわかりました.本来は PNG 画像ファイルを情報損失なしでより小さいファイルサイズになるように再圧縮するためのものですが,壊れたPNGファイルをfixするオプションもあります.
たかたかは MacPorts で OptiPNG 0.7.5 をインストールしました.
$ sudo port install optipng
単一ファイルの fix なら
$ optipng -fix hoge.png
でOK.複数ファイルを修正する場合は
$ optipng -quiet -force -fix *.png
でよいでしょう.オプションの意味は man optipng に書いてあります.
というわけで,PNG画像の読み込み時にエラーが出たら optipng を試してみましょう.