Отрицательные числа типа unsigned char

Я реализую двумерный корреляционный код с нуля, и у меня есть простая матрица изображений 3×3 типа unsigned char:

 unsigned char Image = [184   0   35
48   107  193
29   166  32]

Мое корреляционное ядро

             Kernel = [-1 0 1]

Теперь, когда я выполняю корреляцию, результат из первой строки математически равен -149, но результат печати равен 107 (дополнение 2).

unsigned char res = -1.F *(Kernel[i-1]) + (Kernel[i+1]);

Разве это не ошибка? Как я могу сохранить результат как -149, но тип все еще остается как беззнаковый символ?
Я знаю, что мой вопрос может быть неуместным, поскольку диапазон беззнаковых символов составляет от 0 до 255, но я хотел убедиться, что я что-то упустил. Мне также известно о том, что отрицательные числа конвертируются в дополнение к 2.
Кстати, это не домашняя работа, я просто работаю над C / C ++ с точки зрения обработки изображений.

3

Решение

Как я могу сохранить результат как -149, но тип все еще остается как беззнаковый символ?

Не делай этого. Используйте целочисленный тип со знаком.

использование int Если увеличение использования памяти не является проблемой.
В противном случае используйте short,

3

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

При вычислении градиента [-X 0 X] на изображении с диапазоном [0 max] ваши результаты попадают в диапазон [-XМакс, ХМаксимум]. Есть разные способы справиться с этим в соответствии с вашими потребностями и ограничениями:

  1. Если у вас нет проблем с памятью, вы увеличиваете кодировку (byte -> short, short -> int).
  2. Если вас интересует только интенсивность градиента, а не его знак, сначала вы применяете абсолютное значение, чтобы получить новый результирующий диапазон [0, X * max], и вы применяете третье решение.
  3. Вы растягиваете свой результат, чтобы соответствовать желаемому диапазону, то есть применяете растяжение гистограммы (линейная функция): [-XМакс, Хmax] -> [0 max]. К сожалению, это решение теряет много точности. Например, это решение теряет половину точности (от [-255, 255)] до [0, 255]), за исключением случаев, когда вы применяете точку 2 ранее.
1

Теперь, когда я выполняю корреляцию, результат из первой строки математически равен -149, но результат печати равен 107 (дополнение 2). Разве это не ошибка?

unsigned char res = -1.F *(Kernel[i-1]) + (Kernel[i+1]);

Сохранение отрицательного значения в переменной без знака, например res, не меняет тип res, Это навсегда unsigned char, Отрицательное значение преобразуется путем многократного добавления / (или вычитания) UCHAR_MAX + 1 (256) и до тех пор, пока он не окажется в unsigned char или в этом случае: 107,

Чтобы сохранить отрицательное значение и сохранить отрицательное значение в resиспользуйте подписанный тип, соответствующий требованиям диапазона:

Type          Range of Type
signed char   at least [-127 to 127]      Varies by platform
signed short  at least [-32767 to 32767]  Varies by platform
int8_t        exactly  [-128 to 127]
int16_t       exactly  [-32768 to 32767]
0