How to set given channel of a cv::Mat to a given value efficiently without changing other channels?

后端 未结 4 803
走了就别回头了
走了就别回头了 2020-12-11 01:12

How to set given channel of a cv::Mat to a given value efficiently without changing other channels? For example, I want to set its fourth channel (alpha channel

4条回答
  •  醉梦人生
    2020-12-11 01:48

    If your image is continuous in memory you can use following trick:

    mat.reshape(1,mat.rows*mat.cols).col(3).setTo(Scalar(120));
    

    If it is not continuous:

    for(int i=0; i

    Edit (thanks to Antonio for the comment):

    Note that this code may be the shortest and it is not allocating new memory but it is not efficient at all. It may be even slower than split/merge approach. OpenCV is really inefficient when it should perform operations on non-continuous matrices with 1 pixel in a row. If time performance is important you should use the solution proposed by @Antonio.

    Just a minor improvement to his solution:

    const int cols = img.cols;
    const int step = img.channels();
    const int rows = img.rows;
    for (int y = 0; y < rows; y++) {
        unsigned char* p_row = img.ptr(y) + SELECTED_CHANNEL_NUMBER; //gets pointer to the first byte to be changed in this row, SELECTED_CHANNEL_NUMBER is 3 for alpha
        unsigned char* row_end = p_row + cols*step;
        for(; p_row != row_end; p_row += step)
             *p_row = value;
        }
    }
    

    This saves increment operation for x and one less value in register. On system with limited resources it may give ~5% speedup. Otherwise time performance will be the same.

提交回复
热议问题