我有一个垂直翻转的RGBA图像存储在uchar[] raw_data
中,但我需要灰度cv::Mat
。这可以使用以下代码轻松实现:
cv::Mat src(width, height, CV_8UC4, raw_data), tmp, dst;
cvtColor(src, tmp, CV_RGBA2GRAY);
flip(tmp, dst, 0);
然而,我发现以下代码的速度提高了两倍:
int linesize = width * 4; // 4 bytes per RGBA pixel
uchar *data_ptr = raw_data + linesize * (height-1); // ptr to last line
cv::Mat tmp(width, height, CV_8UC4, data_ptr, -linesize), dst;
cvtColor(tmp, dst, CV_RGBA2GRAY);
技巧非常明显:tmp
是使用指向最后一行和负行大小的指针创建的,因此当迭代行时它会在内存中移回。这会导致cvtColor
垂直图像翻转。图像数据仅迭代一次而不是两次,这提供了上述提升。我测试了它,它的工作原理,故事结束。
问题是:第一种方式有没有理由这样做?我知道,使用的cv::Mat
ctor中的第四个参数有size_t
类型,所以实际上这是基于指针溢出。该代码适用于不同的设备,包括智能手机和平板电脑,因此性能非常重要。另一方面,它将被编译为不同的体系结构(x86,ARM),因此必须保留可移植性。
提前致谢!