简体   繁体   English

C ++ OpenCV使用向量 <Point> 作为矩阵的索引

[英]C++ OpenCV use vector<Point> as index of a matrix

I have a matrix img (480*640 pixel, float 64 bits) on which I apply a complex mask. 我有一个矩阵img (480 * 640像素,浮点64位),在上面应用了复杂的蒙版。 After this, I need to multiply my matrix by a value but in order to win time I want to do this multiplication only on the non-zero elements because for now the multiplication is too long because I have to iterate the operation 2000 times on 2000 different matrix but with the same mask. 此后,我需要将一个矩阵乘以一个值,但是为了赢得时间,我只想对非零元素执行此乘法,因为现在乘法太长了,因为我必须在2000上将操作迭代2000次不同的矩阵,但具有相同的蒙版。 So I found the index (on x/y axes) of the nonzero pixels which I keep in a vector of Point. 因此,我找到了我保存在Point向量中的非零像素的索引(在x / y轴上)。 But I don't succeed to use this vector to do the multplication only on the pixels indexed in this same vector. 但是我没有成功使用此向量仅对在同一向量中索引的像素进行乘法。

Here is an example (with a simple mask) to understand my problem : 这是一个示例(带有简单的蒙版),用于理解我的问题:

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

What is tricky is that my pixels are not on a range (for example pixels 3, 4 and 50, 51 on a line). 棘手的是我的像素不在范围内(例如,一行上的像素3、4和50、51)。

Thank you in advance. 先感谢您。

Constructing vector of points will also increase computation time. 构造点向量也会增加计算时间。 I think you should consider iterating over all pixels and multiply if the pixel is not equal to zero. 我认为您应该考虑对所有像素进行迭代,如果像素不等于零,则应该相乘。

Iterating will be faster if you have the matrix as raw data. 如果将矩阵作为原始数据,则迭代将更快。

I would suggest using Mat.convertTo . 我建议使用Mat.convertTo Basically, for the parameter alpha , which is the scaling factor, use the value of the mask (3.56 in your case). 基本上,对于参数alpha ,它是比例因子,请使用mask的值(在您的情况下为3.56)。 Make sure that the Mat is of type CV_32 or CV_64 . 确保Mat的类型为CV_32CV_64

This will be faster than finding all non-zero pixels, saving their coordinates in a Vector and iterating (it was faster for me in Java). 这比查找所有非零像素,将其坐标保存在Vector中并进行迭代要快(在Java中对我来说这更快)。

Hope it helps! 希望能帮助到你!

If you do 如果你这样做

Mat result = img*value;

Instead of 代替

Mat result = img.clone()*value;

The speed will be almost 10 times as fast 速度几乎快了十倍

I have also tested your suggestion with vector but this is even slower than your first solution. 我也用vector测试了您的建议,但这比您的第一个解决方案还要慢。 Below the code I used to test your firs suggestion 在我用来测试您的建议的代码下面

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM