下面的代码是matlab中RMSE的一个实现。当我尝试在命令窗口中运行它时,我收到以下错误:
未定义的功能或方法' symsum'对于输入参数类型' uint8'。
我做错了什么?
I = imread ('images.jpg');
figure(1), imshow (I,[]);
R= imread ('Gray Image.jpg');
figure(2), imshow (R,[]);
impixelinfo
modi_size = (R);
[r,c]= size(I);
for i = 1 : r ;
for j = 1: c ;
rmse1 = sqrt(1/r * c);
rmse2 = (I(i,j)- R(i,j))^2 ;
RMSE = rmse1 * sqrt((symsum (rmse2,0,r))* (symsum(rmse2,0,c))) ;
end
end
答案 0 :(得分:0)
首先,您对RMSE的定义是错误的。对于均方误差,定义为:
来源:Wikipedia
如果您想要 root 均方误差,只需取这个结果的平方根。您的for
循环没有正确累积平方偏差的总和。此外,rmse1
不正确。这相当于说rmse1 = sqrt(c/r)
。你的真正含义是rmse1 = sqrt(1/(r*c))
。但是,您应该缩放总和的外部。您需要将所有平方误差之和相加,除以图像的总大小,然后然后取平方根。 symsum
也适用于符号数学。你是用数字计算的。您还需要将RMSE
变量设为累加器,并将错误添加到此变量中。
我需要提到的最后一件事是,您需要将图像转换为double
或超出uint8
的精度(这是图像的数据类型)。这是因为当您计算平方误差时,您很可能会超出255的最大值。如果不这样做,您的值将被限制为255,这不是您想要的。
因此,您需要将代码更改为:
%// Removed half of your code. This is the important part
[r,c]= size(I);
I = double(I);
R = double(R); %// Cast to ensure precision
RMSE = 0;
%// Accumulate sum of squared errors
for i = 1 : r
for j = 1 : c
RMSE = RMSE + (I(i,j)- R(i,j))^2;
end
end
%// Find mean, then square root
RMSE = sqrt(RMSE / (r*c));
但是,由于使用for
循环,上述代码效率很低。你可以做的是矢量化代码。您可以在一行中执行此操作(不使用强制转换):
I = double(I);
R = double(R);
RMSE = sqrt( mean( (I(:) - R(:)).^2 ) );
I
和R
展开为单个向量,每个向量都会逐个减去它们的正方形,计算此结果的平均值,然后取平方根。
希望这会有所帮助。祝你好运!