У меня есть изображение, которое я пытаюсь сегментировать, закрашивая каждый пиксель либо красным, либо зеленым, либо синим. Я рассчитал показатель достоверности для каждого пикселя и хочу настроить альфа-прозрачность пикселя для отражения достоверности, то есть низкая достоверность означает почти прозрачность. Есть ли способ сделать это в OpenCV? Если нет, то может ли кто-нибудь предложить минимально инвазивную библиотеку (C ++)?
У меня есть попытки использовать 4-канальный 8-битный Mat
как предположил Авреллий, вот код:
cv::Mat m = cv::Mat(20,20, CV_8UC4);
for(int i = 0; i < m.rows; i++){
for(int j = 0; j < m.cols; j++){
Vec4b& v = m.at<Vec4b>(i,j);
v[0] = 255;
v[1] = 0;
v[2] = 0;
v[3] = 0.5;
}
}
imwrite("alpha.png", m);
namedWindow("m");
imshow("m", m);
waitKey(0);
Показанное изображение просто полностью голубое (без прозрачности), а изображение полностью прозрачное.
Есть много способов сделать это. Одним из возможных способов является доступ и изменение каждого отдельного пикселя. Если предположить, image
является четырехканальным, 8-битным cv::Mat
:
auto& pixel = image.at<cv::Vec4b>(i,j);
pixel[3] = confidence;
где i
а также j
являются индексами пикселя в изображении.
Есть и другие методы, которые, вероятно, более элегантны, но они будут зависеть от вашего текущего кода.
ОБНОВИТЬ:
Поведение, которое вы описываете, следует ожидать. По-видимому cv::imshow()
не поддерживает прозрачность. Это объясняет, почему изображение отображается синим цветом.
Что касается сохраненного изображения, важно помнить, что изображение имеет тип CV_8UC4
, Это означает, что каждый элемент канала хранится как uchar
, Назначение значения 0.5
будет обрезаться до нуля, следовательно, полностью прозрачное сохраненное изображение.
Если ваша уверенность является значением с плавающей точкой в диапазоне [0,1]
масштабируйте его до 255, чтобы поместить его в диапазон, поддерживаемый 8-битными изображениями. Таким образом,
v[3] = 0.5;
становится
v[3] = 0.5 * 255;
У меня тоже была такая же проблема, но когда я рисовал прозрачные фигуры и решал их, смешивая изображения.
Я нашел это в документации OpenCV
if you want to paint semi-transparent shapes, you can paint them in a separate buffer and then blend it with the main image.
Для этого я предлагаю вам взглянуть на этот документация статья. Надеюсь, это поможет.