Как эффективно установить данный канал в cv::Mat
для данного значения без изменения других каналов? Например, я хочу установить значение четвертого канала (альфа-канала) равным 120
(т.е. полупрозрачный), что-то вроде:
cv::Mat mat; // with type CV_BGRA
...
mat.getChannel(3) = Scalar(120); // <- this is what I want to do
PS: Мое текущее решение - сначала разбить mat
на несколько каналов и установить альфа-канал, а затем объединить их обратно.
PS2: я знаю, что могу сделать это быстро, если я также хочу изменить другие каналы:
mat.setTo(Scalar(54, 154, 65, 120));
Обновление с обобщенным решением:
Оба метода будут работать для установки всех значений мата в данном канале на заданное значение. И они будут работать для всех матриц, независимо от того, являются ли они непрерывными или нет.
Способ-1 - более эффективный
→ основано на ответе @Antonio и улучшено @MichaelBurdinov
// set all mat values at given channel to given value
void setChannel(Mat &mat, unsigned int channel, unsigned char value)
{
// make sure have enough channels
if (mat.channels() < channel + 1)
return;
const int cols = mat.cols;
const int step = mat.channels();
const int rows = mat.rows;
for (int y = 0; y < rows; y++) {
// get pointer to the first byte to be changed in this row
unsigned char *p_row = mat.ptr(y) + channel;
unsigned char *row_end = p_row + cols*step;
for (; p_row != row_end; p_row += step)
*p_row = value;
}
}
Метод 2 - более элегантный
→ на основе ответа @MichaelBurdinov
// set all mat values at given channel to given value
void setChannel(Mat &mat, unsigned int channel, unsigned char value)
{
// make sure have enough channels
if (mat.channels() < channel+1)
return;
// check mat is continuous or not
if (mat.isContinuous())
mat.reshape(1, mat.rows*mat.cols).col(channel).setTo(Scalar(value));
else{
for (int i = 0; i < mat.rows; i++)
mat.row(i).reshape(1, mat.cols).col(channel).setTo(Scalar(value));
}
}
PS: Стоит отметить, что, согласно документации, матрицы, созданные с помощью Mat::create()
, всегда непрерывны. Но если вы извлекаете часть матрицы с помощью Mat::col()
, Mat::diag()
и т.д. Или создаете заголовок матрицы для внешних данных, такие матрицы могут больше не иметь этого свойства.