OpenCV - Как преобразовать оттенки серого в цвет (CV_8UC3)? - PullRequest
0 голосов
/ 07 января 2020

Я пытаюсь добавить два объекта Mat вместе, но я сталкиваюсь с ошибкой.

Это рабочий код:

    Mat src1, src2, dst;

    /// Read image ( same size, same type )
    src1 = imread("lion.png");
    src2 = imread("bluebell.png");

    dst = src1 + 0.5 * src2;

    imshow("Blend", dst);

    waitKey(0);
    return 0;

Оба src1 и src2 имеют тот же тип, который CV_8UC3. Но когда я пытаюсь это сделать:

    Mat src1, src2, src3, dst;

    /// Read image
    src1 = imread("lion.png");
    src2 = imread("bluebell.png", IMREAD_GRAYSCALE);
    src2.convertTo(src3, COLOR_GRAY2RGB);

    cout << "src1.type " << src1.type() << endl;
    cout << "src2.type " << src2.type() << endl;
    cout << "src3.type " << src3.type() << endl;

    dst = src1 + 0.5 * src3;

    imshow("Blend", dst);

    waitKey(0);
    return 0;

Это не работает. Потому что src2 и src3 оба имеют тип 0, который равен CV_8U. Но я хочу, чтобы src3 имел тип 16, который равен CV_8UC3 (согласно здесь ). Этот код возвращает эту ошибку:

Ошибка OpenCV: Размеры входных аргументов не совпадают (Операция не является ни массивом «массив операций» (где массивы имеют одинаковый размер и одинаковое количество каналов), ни 'array op scalar', ни 'scalar op array') в cv :: arithm_op

Как преобразовать изображение в градациях серого в цветное изображение с точным типом CV_8UC3?

1 Ответ

1 голос
/ 07 января 2020

Вы не можете изменить количество каналов, позвонив по номеру convertTo. В соответствии с эталоном :

желаемого типа выходной матрицы или, скорее, глубиной, поскольку количество каналов такое же, как у входа ; если rtype отрицателен, выходная матрица будет иметь тот же тип, что и входной.

Если у вас матрица с одним каналом в оттенках серого, вы можете использовать cv::merge для создания 3-канального изображения, поместив это один компонент для каналов BGR в новой матрице:

src1 = imread("lion.png");
src2 = imread("bluebell.png", IMREAD_GRAYSCALE);    // one channel

cv::merge(std::vector<cv::Mat>{src2, src2, src2}, src2);
                            // blue, green,red    as output 3-channels mat
dst = src1 + 0.5 * src2;

Вызвав convertTo, вы можете преобразовать тип данных для хранения значений, например, из целого числа в число с плавающей точкой.

...