Переполнение Numpy с помощью np.divide(). RuntimeWarning: в ushort_scalars обнаружено переполнение

Я запускаю следующий код на 2 изображениях:

ndvi = np.divide(img8 - img4, img8+img4)

invalid = (ndvi > 1).any()
if invalid:
    print("Stopping Execution")
    print(ndvi)

img8 и img4 — это 2 изображения, и все они имеют положительные значения. ndvi это (img8-img4)/(img8+img4)

Следовательно, по определению все элементы ndvi должны быть между -1 и 1. Но я получаю некоторые значения›1

Типы всех переменных в этом контексте — «uint16».

Когда я проверяю индекс недопустимых значений и запускаю отдельный код:

temp = (img8[88][118]-img4[88][118])/(img8[88][118]+img4[88][118])

Я получил следующее предупреждение:

<stdin>:1: RuntimeWarning: overflow encountered in ushort_scalars

Значения: img8[88][118] = 1462 img4[88][118] = 1652

Сами значения невелики, чтобы привести к переполнению, но когда размеры массива становятся большими, происходит переполнение.


person Raghav Arora    schedule 14.07.2021    source источник
comment
Возможно, значения в img8 и/или img4 не такие, как вы думаете. Распечатать их   -  person DeepSpace    schedule 14.07.2021
comment
Кроме того, просто чтобы вы знали, если значение в img4 больше, чем соответствующее значение в img8, вы получите отрицательные значения.   -  person DeepSpace    schedule 14.07.2021
comment
@DeepSpace Да, я понимаю. Я имел в виду, что это будет между -1 и 1.   -  person Raghav Arora    schedule 14.07.2021
comment
Итак, по индексу (88 118) встречалось 1 конкретное недопустимое значение. Я напечатал соответствующие значения img: img4[88][118]=1652 img8[88][118]=1462 Итак, ndvi[88][118] должно быть -0,06101 Но он сообщает, что это 20,9845   -  person Raghav Arora    schedule 14.07.2021
comment
Пожалуйста, напечатайте dtypes всего (img8, img4, img4+img8, img8-img4)   -  person Gulzar    schedule 14.07.2021
comment
Возможно это связано с тем, как np.divide работает с вложенными/многомерными массивами. Опубликуйте минимально воспроизводимый пример   -  person DeepSpace    schedule 14.07.2021
comment
Я думаю, что нашел ошибку, когда я это делаю: (img8[88][118]-img4[88][118])/(img8[88][118]+img4[88][118]) Я получаю предупреждение: RuntimeWarning: переполнение в ushort_scalars Но я не понимаю, почему это переполнение   -  person Raghav Arora    schedule 14.07.2021
comment
@Gulzar Все типы dtype имеют значение «uint16».   -  person Raghav Arora    schedule 14.07.2021


Ответы (1)


При вычитании большого числа из маленького, оба из которых равны unitXX, вы получаете переполнение (действительно, underflow), а результатом является модуль XX отрицательного числа, т.е. большое число.
Это связано с тем, что uint не может представлять отрицательное число, а вместо этого содержит большое положительное число.

Этот модуль фактически добавляет maxint (==65535) на отрицательный

В этом случае для указанного вами индекса

img8[88][118]-img4[88][118] == 1462 - 1652 == -190 == 65535 - 190 = 65345

Разделите это на 1462 + 1652 == 3114 и получите 20.984264611432241490044958253051


Решение:

Преобразуйте dtypes в float перед делением и обычно работайте с плавает для изображений, а не uint.

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

Также будет работать использование int, а не uint, но придерживайтесь поплавков ради вашего собственного блага.

person Gulzar    schedule 14.07.2021