MATLAB довольно уникален тем, как он обрабатывает операции между различными типами данных.Если x
равно uint8
(как, вероятно, в этом случае), а m
равно double
(как, вероятно, и в этом случае), то эта операция:
Z1=(x(i-1,j-1))*(m(1,1));
возвращаетзначение uint8
, а не double
.Арифметика в MATLAB всегда принимает тип не двойного аргумента.(И вы не можете делать арифметику между двумя разными типами, если только один из них не равен double
.)
MATLAB выполняет целочисленную арифметику с насыщением.Это означает, что uint8(5) * -1
дает 0, а не -5, потому что uint8
не может представлять отрицательное значение.
Так что все ваши Z1
.. Z9
являются значениями uint8
, отрицательные результаты былиустановите на 0. Теперь вы добавляете все это, опять же с насыщением, приводя к значению не более 255. Это значение присваивается выходу (двойному).Таким образом, похоже, что вы делаете свои вычисления правильно и выводите двойной массив, но вы все еще ограничиваете свой результат странным образом.
Корректная реализация будет приводить каждое из значений от x
до double
перед умножением на потенциально отрицательное число.Например:
for i = 2:H-1
for j = 2:W-1
s = 0;
s = s + double(x(i-1,j-1))*m(1,1);
s = s + double(x(i-1,j))*m(1,2);
s = s + double(x(i-1,j+1))*m(1,3);
s = s + double(x(i,j-1))*m(2,1);
s = s + double(x(i,j))*m(2,2);
s = s + double(x(i,j+1))*m(2,3);
s = s + double(x(i+1,j-1))*m(3,1);
s = s + double(x(i+1,j))*m(3,2);
s = s + double(x(i+1,j+1))*m(3,3);
y(i,j) = s;
end
end
(обратите внимание, что я исключил использование вами 9 различных переменных, я думаю, что это чище, и я также удалил много ненужных скобок!)
Прощереализация будет:
for i = 2:H-1
for j = 2:W-1
s = double(x(i-1:i+1,j-1:j+1)) .* m;
y(i,j) = sum(s(:));
end
end