#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <sstream>
using namespace std;
using namespace cv;
/************************************************************************
*
/************************************************************************/
Mat& sanImgEffective(Mat &I, const uchar* const table)
{
CV_Assert(I.depth() != sizeof(uchar));
int channels = I.channels();
int nRows = I.rows;
int nCols = I.cols * channels;
if (I.isContinuous()) {
nCols = nRows * nCols;
nRows = 1;
}
uchar* p;
for (int i = 0; i < nRows; ++i) {
p = I.ptr<uchar>(i);
for (int j = 0; j < nCols; ++j) {
p[j] = table[p[j]];
}
}
return I;
}
/************************************************************************
*
/************************************************************************/
Mat& sanImgIterator(Mat &I, const uchar* const table)
{
CV_Assert(I.depth() != sizeof(uchar));
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, ++end) {
*it = table[*it];
}
break;
}
case 3: {
MatIterator_<Vec3b> it, end;
for (it = I.begin<Vec3b>(), end = I.end<Vec3b>(); it != end; ++it, ++end) {
(*it)[0] = table[(*it)[0]];
(*it)[1] = table[(*it)[1]];
(*it)[2] = table[(*it)[2]];
}
break;
}
}
return I;
}
/************************************************************************
*
/************************************************************************/
Mat& sanImgOnTheFly(Mat &I, const uchar* const table)
{
CV_Assert(I.depth() != sizeof(uchar));
int channels = I.channels();
int nRows = I.rows;
int nCols = I.cols;
switch(channels) {
case 1: {
for (int i = 0; i <nRows; ++i) {
for (int j = 0; j < nCols; ++j) {
I.at<uchar>(i, j) = table[I.at<uchar>(i, j)];
}
}
break;
}
break;
case 3: {
Mat_<Vec3b> _I = I;
for (int i = 0; i <nRows; ++i) {
for (int j = 0; j < nCols; ++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;
}
int main(){
uchar table[256];
int divideWith = 16;
for (int i = 0; i < 256; ++i) {
table[i] = divideWith * (i / divideWith);
}
Mat image = imread("tiger.jpg");
Mat result = image.clone();
cout << "Time of reducing color :" << endl;
//C operator [] method 1-------------------------------------------------------
{
double t;
t = (double)getTickCount();
cv::Mat clone_i = image.clone();
result = sanImgEffective(image, table);
t = 1000*((double)getTickCount() - t)/getTickFrequency();
cout << " C operator [] runs: \n " << t << " milliseconds."<< endl;
}
//iterator method 2------------------------------------------------------------
{
double t;
t = (double)getTickCount();
cv::Mat clone_i = image.clone();
result = sanImgIterator(image, table);
t = 1000*((double)getTickCount() - t)/getTickFrequency();
cout << " iterator runs: \n " << t << " milliseconds."<< endl;
}
// on-the-fly method 3--------------------------------------------------------
{
double t;
t = (double)getTickCount();
cv::Mat clone_i = image.clone();
result = sanImgOnTheFly(image, table);
t = 1000*((double)getTickCount() - t)/getTickFrequency();
cout << "on-the-fly address runs: \n " << t << " milliseconds."<< endl;
}
// lookUpTable method 4--------------------------------------------------------
Mat lookUpTable(1, 256, CV_8U);
uchar* p = lookUpTable.data;
for( int i = 0; i < 256; ++i)
p[i] = table[i];
{
double t;
t = (double)getTickCount();
LUT(image, lookUpTable, result);
t = 1000*((double)getTickCount() - t)/getTickFrequency();
cout << "the LUT f runs: \n " << t << " milliseconds."<< endl;
}
}