我需要在HSV颜色空间中通过3通道矩阵进行迭代,而且速度非常慢。大约需要2.5秒。
cv::Mat img = cv::imread( "image.jpg" );
cv::Mat img32FC3;
img.convertTo( img32FC3, CV_32FC3 );
cv::cvtColor( img32FC3, img32FC3, CV_BGR2HSV );
int height = img32FC3.rows;
int width = img32FC3.cols;
cv::Size size = img32FC3.size();
if( img32FC3.isContinuous() ) {
size.width *= size.height;
size.height = 1;
}
size.width *= 3;
for( int i = 0; i < size.height; i ++ ) {
float* ptr = img32FC3.ptr<float>(i);
for( int j = 0; j < size.width; j += 3 ) {
h = (ptr[ j ]);
s = (ptr[j +1 ]);
v = (ptr[j +2 ]);
}
}
cv::cvtColor( img32FC3, img32FC3, CV_HSV2BGR );
img32FC3.convertTo( img, CV_8UC3 );
imwrite("test.jpg", img );
上面的代码改编自documentation of openCV,其中表明它是高效的。所以我想知道如何加快速度,因为2.5秒真的非常慢:(。
BTW:图像为3744x5616像素
答案 0 :(得分:3)
您不应该直接访问mat的数据,因为有时它不会像您期望的那样存储。检查my answer here。
另一种方法是使用Mat迭代器。根据[opencv_tutorials.pdf,ver 2.4.2 pp.89-92] 它比我链接中的嵌套循环稍慢。 (对于大图像,你慢5%,但请注意它们只使用MatIterator,而不是 const ,可以通过一个不错的编译器进一步优化。)
MatConstIterator_<Vec3b> it = M.begin<Vec3b>(), it_end = M.end<Vec3b>();
for(; it != it_end; ++it)
{
//do sth read-only otherwise use MatIterator_<Vec3b>
b = (*it)[0];
g = (*it)[1];
r = (*it)[2];
}
<double>
如果是灰度,则来自ocv2.4.2 refman p19。
答案 1 :(得分:1)
加速的最佳机会是并行化循环。 OpenCV使用TBB作为多线程环境,您可能需要检查它。顺便说一句,你不需要对大小等进行所有计算。你已经检查过你的矩阵是连续的(),所以你可以把指针作为float ptr = reinterpret_cast<float>(img32FC3.data)
然后你的循环:
for (size_t i = ; i < img32FC3.rows*img32FC3.cols; ++i, ptr +=3) {
// do something
}