OpenCVでリアルタイムハーフトーニング

Last-modified: 2011-07-23 (土) 20:19:51

参考にさせてもらいました
http://d.hatena.ne.jp/Kojo_Sugita/20100912/1284271144


目次


today: ?
yesterday: ?
total: ?

更新履歴

2011/07/23

  • プログラム公開

推奨環境

  • OS: Linux(Ubuntu 11.04で確認)
  • OpenCV: 2.3

ダウンロード用ファイル

main関数の流れ

/* $Id: halfToning.cpp 2011/07/23 19:57:46 kato Exp $
 * 参考: http://d.hatena.ne.jp/Kojo_Sugita/20100912/1284271144
 * ハーフトーニングでおしゃれに二値化
*/

#include
#include
#include
#include
#include

using namespace std;
using namespace cv;

void help(void);
Mat floydSteinberg(Mat_<unsigned char> a);
bool capture(Mat img, string fmt);

int main(int argc, char **argv){
    if(argc == 1)
	help();
    const string filename = argc == 2 ? argv[1] : "lena.jpg";
    Mat_<unsigned char> img = imread(filename, CV_LOAD_IMAGE_GRAYSCALE);
    try{
	CV_Assert(img.data);
    }catch(Exception e){
	return -1;
    }
    floydSteinberg(img);
    return 0;
}

inline void help(void){
    cout << "./halfToning [image path]" << endl;
}

Mat floydSteinberg(Mat_<unsigned char> a){
    namedWindow("FloydSteinberg", CV_WINDOW_AUTOSIZE);
    Mat_<unsigned char> result = a.clone();
    for(int y = 0; y < a.rows; y++){
	for(int x = 0; x < a.cols; x++){
	    int f = a(y, x);
	    int e;
	    if(f > 128){
		e = f-255;
		f = 255;
	    }else{
		e = f;
		f = 0;
	    }
	    result(y, x) = f;
	    if(x != a.cols-1)
		a(y, x+1) += (int)(7*e/16);
	    if((x != 0) && (y != a.rows-1))
		a(y+1, x-1) += (int)(3*e/16);
	    if(y != a.rows-1)
		a(y+1, x) += (int)(5*e/16);
	    if((x != a.cols-1) && (y != a.rows-1))
		a(y+1, x+1) += (int)(3*e/16);
	}
	imshow("FloydSteinberg", result);
	waitKey(2);
	if(!(y%(a.rows/3)))
	    capture(result, ".jpg");
    }
    waitKey(0);
    return result;
}

bool capture(Mat img, string fmt){
    static int i = 0;
    stringstream now;
    now << i;
    string fullname;
    if(i < 10)
	fullname = "capture-0" + now.str() + fmt;
    else
	fullname = "capture-" + now.str() + fmt;
    bool chk = imwrite(fullname, img);
    i++;
    return chk;
}

参考画像

capture-03.jpg