rydotの呟''

プログラミングとかCGとかDTMとか適当にいろいろのことを適度にやる気なく綴るはず。

適応的しきい値

借りた本をスキャンしたんだけれど 真ん中のへこんだ部分がどうしても暗くなる。

本の印刷のコントラストが適度に低くて しかも本が適度に分厚いと 真ん中のへこんだ部分がより大きく暗くなるので 全体の文字がつぶれないようにがんばると どうしてもこうなる。

threshold0.png threshold0.png

そこで適応的にしきい値かけるソフトを探したんだけれど openCVに標準で関数があったので テキトーに書いてみた。 ていうか「適応的しきい値」とか「適応的二値化」ってマイナーなのかしら あんまりソフトがひっかからんかったような気がする。

適応的しきい値をかけるとこういう感じになってくれてとてもうれしい。

threshold0.png threshold1.png

参考 http://opencv.jp/sample/filter_and_color_conversion.html#threshold

#include <cv.h>
#include <highgui.h>

int main (int argc, char **argv)
{
  IplImage *src_img = 0, *dst_img;
  IplImage *src_img_gray = 0;

  //args
  // inputfile outputfile blocksize thresholdparameter
  char *outfile="out.jpg";
  int block=5;
  double param=5;

  if (argc >= 2)
  {
    src_img = cvLoadImage(argv[1], CV_LOAD_IMAGE_COLOR);
  }
  if (src_img == 0)
  {
    return -1;
  }
  if (argc >= 3)
  {
    outfile=argv[2];
  }
  if(argc>=4)
  {
    int b=atoi(argv[3]);
    if(b<3)b=3;
    b/=2;
    b*=2;
    b++;
    block=b;
  }
  if(argc>=5)
  {
    double p=atof(argv[4]);
    param=p;
  }

  dst_img = cvCreateImage(cvGetSize (src_img), IPL_DEPTH_8U, 1);
  src_img_gray = cvCreateImage(cvGetSize (src_img), IPL_DEPTH_8U, 1);

  cvCvtColor(src_img, src_img_gray, CV_BGR2GRAY);

  cvAdaptiveThreshold(src_img_gray, dst_img, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, block, param);

  cvSaveImage(outfile,dst_img);

  cvReleaseImage(&src_img);
  cvReleaseImage(&src_img_gray);
  cvReleaseImage(&dst_img);

  return 0;
}