現在地 >> メニュー >> サンプルコード::OpenCV >> OpenCV+TBB::2値化
現在地 >> メニュー >> TBB >> OpenCV+TBB::2値化

CV+TBB::2値化(多重ループ)


問題


以下の画像をグレイスケールで読み込んで
インテル スレッディング・ビルディングブロック」を用いて、2値化せよ。

画像

答え


#include <iostream>
#include <tbb/task_scheduler_init.h>
#include <tbb/blocked_range.h>
#include <tbb/parallel_for.h>
#include <cv.h>
#include <highgui.h>

using namespace std;
using namespace tbb;


/**********[tbb用データ構造]******************/
class DATA_FOR_TBB
{
private:
char *data;

public:

/*******[コンストラクタ]************/
DATA_FOR_TBB(char *ipl_data):data(ipl_data){}


/*************[オペレータの設定]************/
void operator()(const blocked_range<int>& range)const;

};


/*******[オペレータの操作]********/
void DATA_FOR_TBB::operator()(const tbb::blocked_range<int> &range)const
{
for (int n = range.begin(); n != range.end();++n)
{
if( unsigned( data[n]) > unsigned char(127) )
{
data[n] = char(255);
}else
{
data[n] = char(0);
}

}

}


/************[ここからメイン関数]********************/
int main(int argc, char *argv)
{
IplImage *imgA =cvLoadImage( "test2.jpg", CV_LOAD_IMAGE_GRAYSCALE);//
if(imgA ==NULL)
{
cout << "file not found\n";
return (-1);
}


/*********ここからTBB********/
task_scheduler_init TBB_INIT;

DATA_FOR_TBB *Tbb_Class = new DATA_FOR_TBB(imgA->imageData);
parallel_for(blocked_range<int>(0,imgA->imageSize,100),*Tbb_Class);

TBB_INIT.terminate();
/********TBBおわり********/
delete Tbb_Class;


cvNamedWindow("window",CV_WINDOW_AUTOSIZE);
cvShowImage("window",imgA);

cvWaitKey(0); // 0秒待つ => ずっと入力待ち


cvReleaseImage( & imgA);
cvDestroyAllWindows();

return 0;
}

メモ


もし、IplImageを丸ごとクラスに渡したら、以下のような感じになる

#include <iostream>
#include <string>
#include <tbb/task_scheduler_init.h>
#include <tbb/blocked_range.h>
#include <tbb/parallel_for.h>
#include <cv.h>
#include <highgui.h>


const std::string filename = "test2.jpg";

/********[データ構造]***********/
class TbbIplImage
{
private:
	IplImage *imgT;

public:
	//コンストラクタ
	TbbIplImage(IplImage *img):imgT(img){}

	//オペレータ
	void operator()(const tbb::blocked_range<int>& range) const
	{

		for (int n = range.begin(); n != range.end();++n)
		{
			if( unsigned( imgT->imageData[n]) > unsigned char(127) )
			{
				imgT->imageData[n] = char(255);
			}else
			{
				imgT->imageData[n] = char(0);
			}
		}
	}

};

/******** [プロトタイプ宣言] ***********/
void Tbb_Img_Process(IplImage *imgA);


/*******[ここからメイン関数]*********/
int main()
{
	IplImage *imgA = cvLoadImage(filename.c_str(),CV_LOAD_IMAGE_GRAYSCALE);
	if(imgA == NULL)
	{
		std::cerr << "file not found \n";
		return -1;
	}

	Tbb_Img_Process(imgA);

	cvNamedWindow("window",CV_WINDOW_AUTOSIZE);
	cvShowImage("window",imgA);

	cvWaitKey(0); // 0秒待つ => ずっと入力待ち

	cvReleaseImage( & imgA);
	cvDestroyAllWindows();

	return EXIT_SUCCESS;
}


void Tbb_Img_Process(IplImage *imgA)
{
	tbb::task_scheduler_init TbbInit;
	tbb::parallel_for(tbb::blocked_range<int>(0,imgA->imageSize,imgA->widthStep),TbbIplImage(imgA));
	
	TbbInit.terminate();
}

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






▲よろしければ広告のクリックもお願いします


▲ランキングに参加しました

管理人/副管理人のみ編集できます