简体   繁体   中英

How Can I make it faster in c++11 with std::vector?

I have cv::Mat Mat_A and cv::Mat Mat_B both are (800000 X 512) floats

and below code is looks slow .

int rows = Mat_B.rows;
cv::Mat Mat_A = cv::repeat(img, rows, 1, Mat_A);
Mat_A = Mat_A - Mat_B
cv::pow(Mat_A,2,Mat_A)
cv::reduce(Mat_A, Mat_A, 1, CV_REDUCE_SUM);
cv::minMaxLoc(Mat_A, &dis, 0, &point, 0);

How Can I do this in std::vector ?

I think it should be faster.

In my 2.4 Ghz mabook pro it took 4 sec ? very slow.

I don't think you should use std::vector to do these operations. Image processing (CV aka Computer Vision) algorithms tend to be quite computationally heavy because there is so much data to deal with. OpenCV 2.0 C++ is highly optimized for this kind of operations, eg cv::Mat has a header and whenever a cv::Mat is copied with copy assignment or constructor, only the headers are copied with a pointer to the data. They use reference counting to keep track of instances. So memory management is done for you, and that's a good thing.

https://docs.opencv.org/2.4/doc/tutorials/core/mat_the_basic_image_container/mat_the_basic_image_container.html

You could try to compile without debug symbols, ie release vs debug. And you can also try to compile with optimization flags, eg for gcc -O3 which should reduce the size of your binary and speed up runtime operations. Maybe it might make a difference.

https://www.rapidtables.com/code/linux/gcc/gcc-o.html

Another thing you could try is to give your process a higher priority, ie the higher the priority, the less it the process yields the CPU. Again, that might not make a lot of difference, it all depends of other processes and their priorities, etc.

https://superuser.com/questions/42817/is-there-any-way-to-set-the-priority-of-a-process-in-mac-os-x

I hope that helps a bit.

Well your thinking is wrong.

  1. Why your program is slow:

Your CPU have to loop through a lot of number and do calculation. This will make computation complexity high. That's why it's slow. Your program's speed is in proportion to size of Mat A and B. You can check this point by reducing/increasing the size of Mat A and B.

  1. Can we accelerate it by std::vector

Sorry but it's no. Using std::vector will not reduce the calculation complexity. The math arthmetic of opencv is da "best", re-writing will only lead to slower code.

  1. How to accelerate the calculation: you need to enable the acceleration options for opencv

you can see it at : https://github.com/opencv/opencv/wiki/CPU-optimizations-build-options . Intel provide intel mkl library to accelerate the matrix calculation. You could try it first.

Personally, the easiest approach is to use the GPU. But your machine doesn't have GPU, so it's out of the scope here.

You keep iterating over the data over and over again to do independent operations on them.

Something like this iterates only once over the data.

//assumes Mat_B and img cv::Mat
using px_t = float;//you mentioned float so I'll assume both img and Mat_B use floats
int rows = Mat_B.rows;
cv::Mat output(1,rows, Mat_B.type());
auto output_ptr = output.ptr<px_t>(0);
auto img_ptr = img.ptr<px_t>(0);
int min_idx =0;
int max_idx =0;
px_t min_ele = std::numeric_limits<px_t>::max();
px_t max_ele = std::numeric_limits<px_t>::min();
for(int i = 0; i< rows; ++i)
{
    output[i]=0;
    auto mat_row = Mat_B.ptr<px_t>(i);
    for(int j = 0; j< Mat_B.cols; ++j)
    {
        output[i] +=(img_ptr[j]-mat_row[j])*(img_ptr[j]-mat_row[j]);
    }
    if(output[i]<min_ele)
    {
       min_idx = i;
       min_ele = output[i];
    }
    if(output[i]>max_ele)
    {
       max_idx = i;
       max_ele = output[i];
    }
}

While I am also not sure if it is faster you can do this, assuming Mat_B contains uchar

std::vector<uchar> array_B(Mat_B.rows* Mat_B.cols);
if(Mat_B.isContinuous())
    array_B = Mat_B.data;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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