OpenCV: преобразование изображения CV_8UC3 в изображение CV_32S1 в переполнении стека

Мне нужно преобразовать изображение CV_8U с 3 каналами в изображение, которое должно быть одним каналом CV_32S. Но когда я пытаюсь это сделать, изображение, которое я получаю, полностью черное. Я не понимаю, почему мой код не работает.

Я имею в виду изображение в градациях серого, поэтому я делю трехканальное изображение на вектор одноканального изображения, а затем обрабатываю только первый канал.

//markers->Image() returns a valid image, so this is not the problem

cv::Mat dst(markers->Image().size(), CV_32SC1);
dst = cv::Scalar::all(0);
std::vector<cv::Mat> vectmp;
cv::split(markers->Image(), vectmp);
vectmp.at(0).convertTo(dst, CV_32S);

//vectmp.at(0) is ok, but dst is black...?

Заранее спасибо.

2

Решение

Вы пытались получить значения результирующего изображения? Как это:

for (int i=0; i<result.rows; i++)
{
for (int j=0; j<result.cols; j++)
{
cout << result.at<int>(i,j) << endl;
}
}

Я преобразовал (также использовал convertTo) случайное серое одноканальное изображение для CV_32S (это 32-битное целое значение со знаком для каждого пикселя) мой вывод был таким:

80
111
132

И когда я попытался показать это, я также получил черное изображение. От документация:

Если изображение является 16-разрядным без знака или 32-разрядным целым числом, пиксели
делится на 256. То есть диапазон значений [0,255 * 256] отображается на
[0255].

Таким образом, если вы разделите эти маленькие числа на 255, то вы получите 0 (int тип). Вот почему imshow отображает черное изображение.

3

Другие решения

Если вы хотите отобразить 32-битное изображение и увидеть значимый результат, вам нужно умножить все его элементы на 256 до вызова imshow, Иначе, imshow уменьшит ваши значения до нуля, и вы получите черное изображение (как указал Астор).

Поскольку исходные значения являются 8-битными без знака, они должны быть меньше 255. Поэтому умножение их на 256 безопасно и не будет переполнять 32-битное целое число.

РЕДАКТИРОВАТЬ Я только что понял, что ваш тип вывода подписанный 32-разрядное целое число, но оригинальный тип неподписанный 8-битное целое число. В этом случае вам необходимо соответствующим образом масштабировать ваши значения (посмотрите на scaleAdd).

Наконец, вы можете убедиться, что ваше изображение в формате YCbCr, прежде чем вы начнете выбрасывать каналы изображения.

0

У меня была та же проблема, я решил ее косвенным путем, пытаясь преобразовать 8UC1 в 32S вместо 8UC3.

RgbToGray принимает создание серого изображения, используя тип элемента 8UC3 или 8UC1.
8UC1 — это мой маркер.

Я сделал это в Opencvsharp:

Mat buf3 = new Mat(iplImageMarker);
buf3.ConvertTo(buf3, MatType.CV_32SC1);
iplImageMarker= (IplImage)buf3;

iplImageMarker=iplImageMarker* 256;
0

Я считаю, что это то, что вы ищете. Преобразуйте ваше изображение в этот 8-битный одноканальный канал. CV_8UC1. Вы начинаете с 8-битного изображения и меняете его на 32-битный одноканальный? Зачем? Держите это 8 бит.

0
По вопросам рекламы [email protected]