在 OpenCV 中分配矩阵元素
Posted
技术标签:
【中文标题】在 OpenCV 中分配矩阵元素【英文标题】:Assign matrix element in OpenCV 【发布时间】:2019-05-28 14:23:32 【问题描述】:在 OpenCV 中将元素从一个源矩阵分配到目标矩阵的最通用方法是什么?我总是发现自己在编写这样的代码,这并不优雅:
cv::Mat source; // CV_32FC3
cv::Mat dest; // CV_32FC3
// ...
switch( source.channels() )
case 1:
dest.at<float>( y, x ) = source.at<float>( j, i );
break;
case 2:
dest.at<cv::Vec2f>( y, x ) = source.at<cv::Vec2f>( j, i );
break;
case 3:
dest.at<cv::Vec3f>( y, x ) = source.at<cv::Vec3f>( j, i );
break;
case 4:
dest.at<cv::Vec4f>( y, x ) = source.at<cv::Vec4f>( j, i );
break;
我想知道推荐的方法是什么,必须有一些通用的单线,对吧?
适用于不同数据类型的解决方案的奖励积分(例如,将 n 通道浮点元素分配给 n 通道双精度或短元素)
【问题讨论】:
你可以使用opencv中提供的函数remap吗?它需要一个输入矩阵和输出矩阵,以及它们之间的映射。输入矩阵和输出矩阵必须是相同的类型,否则函数不关心它们的类型。 改用 1x1 大小的 ROI?dest(cv::Rect(x,y,1,1)) = source(cv::Rect(i,j,1,1))
如果它在一个循环中,可能会有很多开销,但是你也可以让投资回报率更大。如果您需要更改类型,请使用 convertTo
而不是分配。或者切换到使用显式类型的 Mats(如 Mat3f
),这样如果你按照答案中的建议创建一个模板化函数,它可以自动确定参数。
@TheBarrometer 感谢您指出remap
,在我目前的情况下,它确实是最好的解决方案。但我也在考虑其他情况。
@DanMašek 是的,我认为开销太大。但我真的不知道打字垫,谢谢!
【参考方案1】:
cv::Vec<T, n>
有一个模板版本,因此您可以制作一个模板函数,获取源和目标类型以及通道数,如下所示:
template<typename TSrc, typename TDst, int N>
void assign(const cv::Mat& src, cv::Mat& dst, int x, int y)
assert(src.channels() == N);
assert(dst.channels() == N);
assert(src.size() == dst.size());
const cv::Vec<TSrc, N>& srcVec = src.at<cv::Vec<TSrc, N>>(x, y);
cv::Vec<TDst, N>& dstVec = dst.at<cv::Vec<TDst, N>>(x, y);
for (int i = 0; i < N; ++i)
dstVec[i] = static_cast<TDst>(srcVec[i]);
int main(int argc, char* argv[])
//sample usage:
cv::Mat src(5, 5, CV_8UC3, cv::Scalar::all(255)), dst(5, 5, CV_32FC3, cv::Scalar::all(1));
assign<unsigned char, float, 3>(src, dst, 3, 3);
【讨论】:
我会考虑使用saturate_cast
而不是static_cast
,尤其是对于整数类型,这样可以避免溢出(并使其更接近convertTo
的行为方式)。以上是关于在 OpenCV 中分配矩阵元素的主要内容,如果未能解决你的问题,请参考以下文章