Ошибка усреднения большого вектора в MATLAB - PullRequest
0 голосов
/ 29 июня 2018

Как вы точно берете среднее значение больших наборов целых чисел в MATLAB? У меня есть два больших вектора (2672x4008 в размерах), с которыми я имею дело, каждый из которых является результатом пикселей на изображении. Следовательно, результирующий вектор заполняется значениями от 0 до 256, все целые числа. Моя проблема в том, что я хочу получить точное значение средней интенсивности этих серых изображений. Для этого я использовал строку

meanvalue = mean(I(:))

Это привело к значению среднего значения = 155,9335 в строке вывода MATLAB.

Затем я добавил 20 к каждому значению вектора, как показано ниже (это должно повысить интенсивность всего изображения, если я правильно понимаю).

Ipt = I + 20;

Затем я взял среднее значение этого нового вектора, Ipt

meanvaluept = mean(Ipt(:))

и Matlab выплюнул значение meanvaluept = 175,8916. Я не математик, но знаю достаточно, чтобы знать, что 175,8916 - 20 155,9335.

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

Ответы [ 3 ]

0 голосов
/ 30 июня 2018

В вашем вопросе есть очень важное примечание:

Предположим, I = [2 3;4 9]

meanvalue = mean(I(:)) = 4.5

Когда вы добавите 20 с I, у вас будет:

Ipt = I + 20;

Ipt = [22 23; 24 29]

так что вы добавите 20 ко всем элементам в I, поэтому ваше среднее значение увеличит значение на 20.

0 голосов
/ 30 июня 2018

Вы проверили тип данных изображения?

Это правда, что если ваше среднее изображение I

meanvalue = mean(I(:)) = 155.9335

и вы добавили 20 к каждому пикселю

Ipt = I + 20

у вас должно быть

meanept = mean(Ipt(:)) = meanvalue + 20 = 175.9335

Но не забывайте, что тип данных изображения - это uint8, что ограничивает значение пикселей 0-255 . Это означает, что если вы добавили 20 к пикселю, а его значение больше 255, его значение будет равно 255, и то же самое, если вы вычесть какое-то значение и оно будет меньше 0.

Возможно, некоторые из ваших пикселей ограничены 255, когда обычно у вас будет больше 255.


Например:

У меня вектор X в двойном

X = [1 1 1; ...
     1 1 1; ...
     1 1 240];

Среднее значение X равно

mean(X(:)) = 27.5556

с

( 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 240)/9 = 27.5556

Если бы я добавил 20 к каждому пикселю

X20 = X + 20
    = [(1 + 20) (1 + 20) (1 + 20); ...
       (1 + 20) (1 + 20) (1 + 20); ...
       (1 + 20) (1 + 20) (240 + 20)];
    = [21 21 21; ...
       21 21 21; ...
       21 21 255];

Обратите внимание, что X20 (3,3) составляет 255, а не 260. Это вызывает

meanX20 = mean(X20(:)) = 47

но если я изменю тип данных X на удвоенный

X_double = double(X)

и добавил 20 к каждому пикселю

X20_double = X_double + 20
           = [(1 + 20) (1 + 20) (1 + 20); ...
              (1 + 20) (1 + 20) (1 + 20); ...
              (1 + 20) (1 + 20) (240 + 20)];
           = [21 21 21; ...
              21 21 21; ...
              21 21 260];

, а среднее значение X20_double -

X20_double_mean = mean(X20_double(:)) = 47.5556

Видите разницу? Среднее двойное значение X20 составляет 47,5556, а среднее значение x20 для uint8 - 47. Я надеюсь, что это поможет:)

0 голосов
/ 29 июня 2018

Поскольку вы имеете в виду «изображения в оттенках серого», и у вас есть целые числа в диапазоне 0–255 (упомянутые вами 256 должны быть опечаткой), я предполагаю, что ваш I имеет тип uint8 .

В этом случае MATLAB использует насыщенное сложение, в результате чего результаты, превышающие 255, ограничиваются 255. Эффект, который вы описываете, вызван этим насыщенным сложением.

Вот пример:

>> I = uint8(randi(255,1000,1000));
>> mean( I(:)+20 )
ans =
  147.1954
>> mean(I(:)) + 20
ans =
  148.0151

Решение состоит в том, чтобы сначала преобразовать в double:

>> mean( double(I(:)) + 20 )
ans =
  148.0151
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...