事例
对图像每一个像素使用变换公式 I n e w = I o l d d i v i d e W i t h ∗ d i v i d e W i t h I_{new} = \frac{I_{old}}{divideWith} * divideWith Inew=divideWithIold∗divideWith, I o l d 和 d i v i d e W i t h I_{old}和divideWith Iold和divideWith为命令行输入
#include <iostream>
#include <opencv2/opencv.hpp>
cv::Mat &ScanImageAndReduceC(cv::Mat &I, const uchar *const table);
cv::Mat &ScanImageAndReduceIterator(cv::Mat &I, const uchar *const table);
cv::Mat &ScanImageAndReduceRandomAccess(cv::Mat &I, const uchar *const table);
int main(int argc, char **argv) {
cv::String imageName = argv[1]; // 获取图像地址
cv::Mat img = cv::imread(imageName, cv::IMREAD_UNCHANGED); // 读取图像
// 判断是否成功读取
if (argc != 3 || !img.data) {
std::cout << "Can't open file: " << imageName << std::endl;
return -1;
}
int divideWith = 0; // convert our input string to number - c++ style
std::stringstream s;
s << argv[2];
s >> divideWith;
if (!s || !divideWith) {
std::cout << "Invalid number entered for dividing" << std::endl;
return -1;
}
// Lookup Table
uchar table[256];
for (int i = 0; i < 256; ++i)
table[i] = (uchar)(divideWith * (i / divideWith));
/*
double t = (double)cv::getTickCount();
// do something...
t = ((double)cv::getTickCount() - t) / cv::getTickFrequency();
*/
double t;
// The efficient way
t = (double)cv::getTickCount();
ScanImageAndReduceC(img, table);
t = ((double)cv::getTickCount() - t) / cv::getTickFrequency();
std::cout << "Times passed in seconds (Efficient): " << t * 1000 << " ms" << std::endl;
// The iterator(safe) method
img = cv::imread(imageName, cv::IMREAD_UNCHANGED);
t = (double)cv::getTickCount();
ScanImageAndReduceIterator(img, table);
t = ((double)cv::getTickCount() - t) / cv::getTickFrequency();
std::cout << "Times passed in seconds (Iterator): " << t * 1000 << " ms" << std::endl;
// On-the-fly address calculation with reference returing
img = cv::imread(imageName, cv::IMREAD_UNCHANGED);
t = (double)cv::getTickCount();
ScanImageAndReduceRandomAccess(img, table);
t = ((double)cv::getTickCount() - t) / cv::getTickFrequency();
std::cout << "Times passed in seconds (On-The-Fly RA): " << t * 1000 << " ms" << std::endl;
// LUT function
img = cv::imread(imageName, cv::IMREAD_UNCHANGED);
cv::Mat J; // J is the output image.
cv::Mat LookUpTable(1, 256, CV_8U);
uchar *p = LookUpTable.ptr();
for(int i = 0; i < 256; ++i)
p[i] = table[i];
t = (double)cv::getTickCount();
cv::LUT(img, LookUpTable, J);
t = ((double)cv::getTickCount() - t) / cv::getTickFrequency();
std::cout << "Times passed in seconds (LUT function): " << t * 1000 << "ms" << std::endl;
return 0;
}
cv::Mat &ScanImageAndReduceC(cv::Mat &I, const uchar *const table) {
// accept only char type matrices.
CV_Assert(I.depth() == CV_8U);
int nRows = I.rows;
int nCols = I.cols * I.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;
}
cv::Mat &ScanImageAndReduceIterator(cv::Mat &I, const uchar *const table) {
// accept onlt char type matricex
CV_Assert(I.depth() == CV_8U);
const int channels = I.channels();
switch (channels) {
case 1: {
cv::MatIterator_<uchar> it, end;
for (it = I.begin<uchar>(), end = I.end<uchar>(); it != end; ++it)
*it = table[*it];
break;
}
case 3: {
cv::MatIterator_<cv::Vec3b> it, end;
for (it = I.begin<cv::Vec3b>(), end = I.end<cv::Vec3b>(); it != end; ++it) {
(*it)[0] = table[(*it)[0]];
(*it)[1] = table[(*it)[1]];
(*it)[2] = table[(*it)[2]];
}
}
}
return I;
}
cv::Mat &ScanImageAndReduceRandomAccess(cv::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: {
cv::Mat_<cv::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;
}
cv::LUT( )速度最快
Times passed in seconds (Efficient): 25.7123 ms
Times passed in seconds (Iterator): 60.7759 ms
Times passed in seconds (On-The-Fly RA): 67.339 ms
Times passed in seconds (LUT function): 19.2237ms