我的RMSE实施有什么问题?

时间:2014-12-26 14:07:17

标签: matlab image-processing

下面的代码是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

1 个答案:

答案 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 ) );

IR展开为单个向量,每个向量都会逐个减去它们的正方形,计算此结果的平均值,然后取平方根。


希望这会有所帮助。祝你好运!