當(dāng)處理圖片的像素值時(shí),如變化
i=(i/10)*10。沒有必要對每一個(gè)像素值進(jìn)行這個(gè)操作??梢詣?chuàng)建一個(gè)表,如果是灰度圖像,那么表達(dá)大小是256*常數(shù)2。之后對每一個(gè)像素進(jìn)行查表即可。
運(yùn)行時(shí)間的計(jì)算:
double t = (double)getTickCount();
// do something ...
t = ((double)getTickCount() - t)/getTickFrequency();
在內(nèi)存中,圖像每行的像素存儲(chǔ)一般是是連續(xù)的。
C的遍歷
Mat& ScanImageAndReduceC(Mat& I, const uchar* const table)
{
// accept only char type matrices
CV_Assert(I.depth() == CV_8U);
int channels = I.channels();
int nRows = I.rows;
int nCols = I.cols * channels;
if (I.isContinuous())
{
nCols *= nRows;
nRows = 1;
}
int i,j;
uchar* p;
for( i = 0; i < nRows; ++i)
{
p = I.ptr<uchar>(i);
for ( j = 0; j < nCols; ++j)
{
p[j] = table[p[j]];
}
}
return I;
}
迭代器方法
Mat& ScanImageAndReduceIterator(Mat& I, const uchar* const table)
{
// accept only char type matrices
CV_Assert(I.depth() == CV_8U);
const int channels = I.channels();
switch(channels)
{
case 1:
{
MatIterator_<uchar> it, end;
for( it = I.begin<uchar>(), end = I.end<uchar>(); it != end; ++it)
*it = table[*it];
break;
}
case 3:
{
MatIterator_<Vec3b> it, end;
for( it = I.begin<Vec3b>(), end = I.end<Vec3b>(); it != end; ++it)
{
(*it)[0] = table[(*it)[0]];
(*it)[1] = table[(*it)[1]];
(*it)[2] = table[(*it)[2]];
}
}
}
return I;
}
typedef Vec<uchar, 3> cv::Vec3b
typedef Vec<double, 3> cv::Vec3d
typedef Vec<float, 3> cv::Vec3f
typedef Vec<int, 3> cv::Vec3i
typedef Vec<short, 3> cv::Vec3s
typedef Vec<ushort, 3> cv::Vec3w
On-the-fly address calculation with reference returning
Mat& ScanImageAndReduceRandomAccess(Mat& I, const uchar* const table)
{
// accept only char type matrices
CV_Assert(I.depth() == CV_8U);
const int channels = I.channels();
switch(channels)
{
case 1:
{
for( int i = 0; i < I.rows; ++i)
for( int j = 0; j < I.cols; ++j )
I.at<uchar>(i,j) = table[I.at<uchar>(i,j)];
break;
}
case 3:
{
Mat_<Vec3b> _I = I;
for( int i = 0; i < I.rows; ++i)
for( int j = 0; j < I.cols; ++j )
{
_I(i,j)[0] = table[_I(i,j)[0]];
_I(i,j)[1] = table[_I(i,j)[1]];
_I(i,j)[2] = table[_I(i,j)[2]];
}
I = _I;
break;
}
}
return I;
}
很慢,不過要處理少數(shù)個(gè)數(shù)據(jù)時(shí)候,可以參考。Mat_data type神器呀!
最好的方法
Mat lookUpTable(1, 256, CV_8U);
uchar* p = lookUpTable.ptr();
for( int i = 0; i < 256; ++i)
p[i] = table[i];
LUT(I, lookUpTable, J);
速度最快,因?yàn)?code>This is because the OpenCV library is multi-thread enabled via Intel Threaded Building Blocks.
不過犧牲了一些安全性。