(OPENCV RC1)什么导致MAT乘法比每像素乘法慢20倍
(opencv rc1) What causes Mat multiplication to be 20x slower than per-pixel multiplication?
// 700 ms
cv::Mat in(height,width,CV_8UC1);
in /= 4;
用
替换//40 ms
cv::Mat in(height,width,CV_8UC1);
for (int y=0; y < in.rows; ++y)
{
unsigned char* ptr = in.data + y*in.step1();
for (int x=0; x < in.cols; ++x)
{
ptr[x] /= 4;
}
}
什么会导致这种行为?这是由于OpenCV"促进"垫子具有标量乘法到具有MAT乘法的垫子的原因,还是对ARM的特定失败优化?(启用了霓虹灯)。
这是一个非常古老的问题(我在几年前报告),许多基本操作都需要额外的时间。不仅是分裂,而且加法,abs等...我不知道这种行为的真正原因。更奇怪的是,应该花费更多时间(例如加工)的操作实际上非常有效。尝试这个:
addWeighted(in, 1.0/4, in, 0, 0, in);
它执行每个像素的多次操作,但运行速度比添加功能和循环实现快几次。
这是我在错误跟踪器上的报告。
通过测量CPU时间尝试了相同的尝试。
int main()
{
clock_t startTime;
clock_t endTime;
int height =1024;
int width =1024;
// 700 ms
cv::Mat in(height,width,CV_8UC1, cv::Scalar(255));
std::cout << "value: " << (int)in.at<unsigned char>(0,0) << std::endl;
cv::Mat out(height,width,CV_8UC1);
startTime = clock();
out = in/4;
endTime = clock();
std::cout << "1: " << (float)(endTime-startTime)/(float)CLOCKS_PER_SEC << std::endl;
std::cout << "value: " << (int)out.at<unsigned char>(0,0) << std::endl;
startTime = clock();
in /= 4;
endTime = clock();
std::cout << "2: " << (float)(endTime-startTime)/(float)CLOCKS_PER_SEC << std::endl;
std::cout << "value: " << (int)in.at<unsigned char>(0,0) << std::endl;
//40 ms
cv::Mat in2(height,width,CV_8UC1, cv::Scalar(255));
startTime = clock();
for (int y=0; y < in2.rows; ++y)
{
//unsigned char* ptr = in2.data + y*in2.step1();
unsigned char* ptr = in2.ptr(y);
for (int x=0; x < in2.cols; ++x)
{
ptr[x] /= 4;
}
}
std::cout << "value: " << (int)in2.at<unsigned char>(0,0) << std::endl;
endTime = clock();
std::cout << "3: " << (float)(endTime-startTime)/(float)CLOCKS_PER_SEC << std::endl;
cv::namedWindow("...");
cv::waitKey(0);
}
结果:
value: 255
1: 0.016
value: 64
2: 0.016
value: 64
3: 0.003
value: 63
您看到结果有所不同,可能是因为mat.divide()
确实执行了浮点划分,并舍入到了下一个。当您在更快的版本中使用整数部门时,它的速度更快,但会产生不同的结果。
此外,OPENCV计算中还有一个饱和度cast,但我猜更大的计算负载差将是双重精度划分。
相关文章:
- 如何在不产生任何垃圾的情况下获得C中的像素
- 在C++中使用GDAL可以将图像的像素坐标转换为lat,long吗
- 如何在24位SDL_Surface上设置像素的颜色
- 如何从SDL_Surface获取特定像素的颜色
- 如何将CMSampleBufferRef/CIImage/UIImage转换为像素,例如uint8_t[]
- 在C++中查找像素 RGB 数据的最快方法是什么?
- 是否可以从 OpenGL 缓冲区获取原始大小的像素?
- 选择基于另一个垫子的非零像素的cv::Mat的一部分?
- 如何使用 sdl2 快速绘制像素网格?
- 如何在C++中进行像素操作? - Linux
- 他们如何将红外锁定像素转换为镜头前方 1m 的正常平面上的位置
- 访问随机图像像素的快速方法,最多一次
- OpenCV 像素访问点与 at() - 不同的值
- 如何使用 freetype2 访问单色位图中的像素状态
- 尝试渲染像素坐标时,简单线条渲染失败
- 计算另一个图像像素满足条件的像素值的平均值
- 如何返回定义良好的内存部分?例如来自图像数据的像素的颜色值
- 在Qt-cpp中通过像素获取QString的子字符串
- 打印像素值,但图像重叠.图像是其应有大小的三倍
- (OPENCV RC1)什么导致MAT乘法比每像素乘法慢20倍