Determining template type when accessing OpenCV Mat elements

后端 未结 3 900
粉色の甜心
粉色の甜心 2021-02-06 08:02

I\'m using the following code to add some noise to an image (straight out of the OpenCV reference, page 449 -- explanation of cv::Mat::begin):

void
         


        
相关标签:
3条回答
  • 2021-02-06 08:34

    The problem is that you need determine to determine type and number of channels at runtime, but templates need the information at compile time. You can avoid hardcoding the number of channels by either using cv::split and cv::merge, or by changing the iteration to

    for(int row = 0; row < in.rows; ++row) {
        unsigned char* inp  = in.ptr<unsigned char>(row);
        unsigned char* outp = out.ptr<unsigned char>(row);
        for (int col = 0; col < in.cols; ++col) {
            for (int c = 0; c < in.channels(); ++c) {
                *outp++ = *inp++ + noise();
            }
        }
    }
    

    If you want to get rid of the dependance of the type, I'd suggest putting the above in a templated function and calling that from your function, depending on the type of the matrix.

    0 讨论(0)
  • 2021-02-06 08:50

    I know this comes late. However, the real solution to your problem is to use OpenCV functionality to do what you want to do.

    1. create noise vector as you do already (or use the functions that OpenCV provides hint!)
    2. shuffle noise vector so you don't need individual noise_index for each pixel; or create vector of randomised noise beforehand
    3. build a matrix header around your shuffled/random vector: cv::Mat_<double>(noise);
    4. use matrix operations for computation: out = in + noise; or cv::add(in, noise, out);
    5. PROFIT!

    Another advantage of this method is that OpenCV might employ multithreading, SSE or whatever to speed-up this massive-element operation, which you do not. Your code is simpler, cleaner, and OpenCV does all the nasty type handling for you.

    0 讨论(0)
  • 2021-02-06 08:53

    They are hardcoded because performance is better that way.

    In OpenCV1.x there is cvGet2D() , which can be used here since Mat can be casted as an IplImage. But it's slow since each time you access a pixel the function will find out the type, size, etc. Specially inefficient in loops.

    0 讨论(0)
提交回复
热议问题