我有一个矩阵img
(480 * 640像素,浮点64位),我在其上应用复杂的掩码。在此之后,我需要将我的矩阵乘以一个值,但为了赢得时间,我想仅对非零元素进行乘法,因为现在乘法太长,因为我必须在2000年迭代2000次操作不同的矩阵但具有相同的掩模。所以我找到了非零像素的索引(在x / y轴上),它保存在Point的矢量中。但是我没有成功使用这个向量来仅对在同一向量中索引的像素进行乘法。
这是一个例子(用简单的掩码)来理解我的问题:
Mat img_temp(480, 640, CV_64FC1);
Mat img = img_temp.clone();
Mat mask = Mat::ones(img.size(), CV_8UC1);
double value = 3.56;
// Apply mask
img_temp.copyTo(img, mask);
// Finding non zero elements
vector<Point> nonZero;
findNonZero(img, nonZero);
// Previous multiplication (long because on all pixels)
Mat result = img.clone()*value;
// What I wish to do : multiplication only on non-zero pixels (not functional)
Mat result = Mat::zeros(img.size(), CV_64FC1);
result.at<int>(nonZero) = img.at(nonZero).clone() * value
棘手的是我的像素不在一个范围内(例如一行上的像素3,4和50,51)。
提前谢谢。
答案 0 :(得分:1)
构造点矢量也会增加计算时间。我认为你应该考虑迭代所有像素并且如果像素不等于零则相乘。
如果将矩阵作为原始数据,迭代速度会更快。
答案 1 :(得分:1)
我建议使用Mat.convertTo。
基本上,对于参数alpha
,这是缩放因子,使用掩码的值(在您的情况下为3.56)。确保Mat的类型为CV_32
或CV_64
。
这比查找所有非零像素要快,在Vector中保存它们的坐标并进行迭代(在Java中对我来说速度更快)。
希望它有所帮助!
答案 2 :(得分:1)
如果你这样做
Mat result = img*value;
而不是
Mat result = img.clone()*value;
速度几乎快10倍
我还用矢量测试了你的建议,但这比你的第一个解决方案还慢。 在我用来测试你的冷杉建议的代码下面
cv::Mat multMask(cv::Mat &img, std::vector<cv::Point> mask, double fact)
{
if (img.type() != CV_64FC1) throw "invalid format";
cv::Mat res = cv::Mat::zeros(img.size(), img.type());
int iLen = (int)mask.size();
for (int i = 0; i < iLen; i++)
{
cv::Point &p = mask[i];
((double*)(res.data + res.step.p[0] * p.y))[p.x] = ((double*)(img.data + img.step.p[0] * p.y))[p.x] * fact;
}
return res;
}