我正在尝试学习如何以最优化的方式操作OpenCV矩阵值。我尝试以四种不同方式缩放存储在OpenCV矩阵中的大图像。
1)使用星形*
运算符
2)使用at
函数和for
循环
3)使用指针访问和for
循环
4)使用查找表
该实验的四舍五入结果如下
*
运算符------- 3 ms
at
功能------- 12 ms
指针访问---- 9 ms
查找表-------- 1 ms
现在很明显为什么查找表是最快的。但是我并不总是能够使用它们。对于无法使用查找表的情况,我需要了解OpenCV如何使用*
运算符实现缩放,以便可以在其他矩阵值操作中将该方法用作参考。
如果有人能告诉我*
操作背后的情况使它比指针访问方法更快,我将不胜感激?
请找到以下代码以供参考。
谢谢
#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
#include <chrono>
typedef std::chrono::system_clock Timer;
typedef std::chrono::duration<double> Duration;
using std::cout;
using std::endl;
using std::vector;
double profile(Timer::time_point start, Timer::time_point end) {
Duration span = end - start;
return span.count() * 1000;
}
int main() {
cv::Mat image = cv::imread("../data/large.jpg", 0);
float sc = 1;
while (true) {
//=================== first method ====================
Timer::time_point s1 = Timer::now();
cv::Mat mine = image * sc;
Timer::time_point s2 = Timer::now();
//=================== second method ====================
cv::Mat yours(image.size(), image.type());
Timer::time_point s3 = Timer::now();
for (int i = 0; i < image.rows; i++) {
for (int j = 0; j < image.cols; j++) {
yours.at<uchar>(i, j) = image.at<uchar>(i, j) * sc;
}
}
Timer::time_point s4 = Timer::now();
//=================== third method ====================
if (!image.isContinuous()) {
std::cerr << "ERROR: image matrix isn't stored as a 1D array" << endl;
exit(-1);
}
Timer::time_point s5 = Timer::now();
cv::Mat result(image.size(), image.type());
for (int i = 0; i < image.rows; i++) {
for (int j = 0; j < image.cols; j++) {
result.data[i * image.cols + j] = image.data[i * image.cols + j] * sc;
}
}
Timer::time_point s6 = Timer::now();
//=================== fourth method ====================
Timer::time_point s7 = Timer::now();
cv::Mat lookupTable(1, 256, image.type());
for (int i = 0; i < 256; i++)
lookupTable.data[i] = i * sc;
cv::Mat his;
cv::LUT(image, lookupTable, his);
Timer::time_point s8 = Timer::now();
cout << "first = " << profile(s1, s2) << endl;
cout << "second = " << profile(s3, s4) << endl;
cout << "third = " << profile(s5, s6) << endl;
cout << "fourth = " << profile(s7, s8) << endl;
cout << "=============== " << endl;
}
return 0;
}
答案 0 :(得分:0)
操作员*()使用parallel_for!因此它将比单线程函数更快。您可以在行循环之前编写#pragma omp parallel并比较结果。或者,您可以使用image.forEach-它也是并行且快速的。
cv :: LUT:https://github.com/opencv/opencv/blob/master/modules/core/src/lut.cpp#L359
此函数具有一组实现:opencl,openvx,ipp和带有parallel_for的简单实现。我认为在您的情况下,使用的是ipp_lut,这是Intel非常优化的处理器版本。而且速度很快!