如何解决将3通道图像转换为T型单个矢量的最快方法
我想将3通道RGB图像展平为T类型的单个矢量。在我的情况下,我专注于 float 数据类型。我写了一个工作正常的函数。但是我要在不到1MilliSecond中执行此操作。在这里,时间成本对我来说确实是一个问题。这是我的代码。
template<typename T>
inline std::vector<T> flatten_temp(cv::Mat frame_image)
{
assert(!frame_image.empty());
const int image_depth = frame_image.channels();
frame_image.convertTo(frame_image,CV_32FC3);
cv::Mat *planes = new cv::Mat[image_depth];
// /** Split into BGR */
cv::split(frame_image,planes);
std::vector<T> flattened_image;
flattened_image.assign(planes[0].begin<T>(),planes[0].end<T>());
for (int i = 1; i < image_depth; ++i) {
flattened_image.insert(flattened_image.end(),planes[i].begin<T>(),planes[i].end<T>());
}
frame_image.release();
delete [] planes;
return flattened_image;
}
任何帮助将不胜感激。
解决方法
insert
上的flattened_image
调整大小多次。此外,插入可能不如普通的std::copy
快(可以在此处完成)。实际上,如果planes[i].begin<T>()
和planes[i].end<T>()
是平凡的连续随机迭代器,那么std::copy
甚至可以memmove
或memcpy
很快的存储块。
因此,您可以首先尝试使用flattened_image.reserve(image_width * image_height * image_depth)
。然后,尝试直接将向量分配到合适的大小(自动将其填充为0),然后执行std::copy(planes[i].begin<T>(),planes[i].end<T>(),flattened_image.begin())
。第二个版本应该更快一些。如果通道在内存中交错,则此代码不是最有效的,因为将在内存中多次读取输入图像。在这种情况下,最好在插入通道时逐行遍历图像。
请注意,如果数据不连续,则还可以利用 parallelism 和 SIMD指令使此代码更快(OpenMP可能是一个很好的开始)。优化后,这种计算应受内存层次结构速度的约束,因此在几乎所有相对最新的计算机上,对于1920x1080x4而言,其计算时间少于1毫秒。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。