首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在matlab实现和python中,PSNR值不同。

在matlab实现和python中,PSNR值不同。
EN

Stack Overflow用户
提问于 2017-07-06 09:07:05
回答 1查看 4.8K关注 0票数 1

我已经实现了一个用于计算YCrCb信道中Y通道的PSNR值的python代码。我得到的PSNR值大约为35.7dB(对于一对图像)

代码语言:javascript
运行
复制
import cv2, main
import sys

i1 = cv2.imread(sys.argv[1])
i2 = cv2.imread(sys.argv[2])

i1= cv2.cvtColor(i1, cv2.COLOR_BGR2YCrCb)
i2= cv2.cvtColor(i2, cv2.COLOR_BGR2YCrCb)

print(main.psnr(i1[:,:,0], i2[:,:,0]))

在主psnr中,psnr定义为:

代码语言:javascript
运行
复制
def psnr(target, ref):
    import cv2
    target_data = numpy.array(target, dtype=numpy.float64)
    ref_data = numpy.array(ref,dtype=numpy.float64)

    diff = ref_data - target_data
    print(diff.shape)
    diff = diff.flatten('C')

    rmse = math.sqrt(numpy.mean(diff ** 2.))

    return 20 * math.log10(255 / rmse)

我得到了一个在线实现(从我所指的论文)在matlab中,我得到的PSNR值约为37.06dB (对于同一对图像)。

代码语言:javascript
运行
复制
function psnr=compute_psnr(im1,im2)
if size(im1, 3) == 3,
    im1 = rgb2ycbcr(im1);
    im1 = im1(:, :, 1);
end

if size(im2, 3) == 3,
    im2 = rgb2ycbcr(im2);
    im2 = im2(:, :, 1);
end

imdff = double(im1) - double(im2);
imdff = imdff(:);

rmse = sqrt(mean(imdff.^2));
psnr = 20*log10(255/rmse)

这个错误是由numpy引入的错误引起的,还是numpy似乎达到的精度造成的?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-06 11:33:05

您的两个转换函数似乎产生了截然不同的结果:

Python输出:

倍频程输出:

这就解释了这种差异。

Octave确实提到了几个YCbCr标准:

代码语言:javascript
运行
复制
 The formula used for the conversion is dependent on two constants,
 KB and KR which can be specified individually, or according to
 existing standards:

 "601" (default)
      According to the ITU-R BT.601 (formerly CCIR 601) standard.
      Its values of KB and KR are 0.114 and 0.299 respectively.
 "709" (default)
      According to the ITU-R BT.709 standard.  Its values of KB and
      KR are 0.0722 and 0.2116 respectively.

也许python版本使用的是不同的标准?(或者可能是BGR对RGB的问题?)在任何情况下,这都是不一致的地方,这似乎并不是numpy精度的问题(当用相同的输入单独测试这些函数时,它们产生相同的结果)。

编辑:

根据这些建议:

python (或者更确切地说,opencv库)似乎输出的是“模拟”(非缩放)版本,而matlab / octave则输出“数字”(缩放)版本。

这一点得到证实:

代码语言:javascript
运行
复制
# Python
RGB = numpy.concatenate(
  ( numpy.array([[[0], [255], [255], [0],   [0],   [0],   [255]]], dtype=numpy.uint8),
    numpy.array([[[0], [0],   [255], [255], [255], [0],   [255]]], dtype=numpy.uint8),
    numpy.array([[[0], [0],   [0],   [0],   [255], [255], [255]]], dtype=numpy.uint8)),
  axis=2)

RGB2Y = cv2.cvtColor(RGB, cv2.COLOR_BGR2YCrCb)
print(RGB2Y)

[[ 0 128 128 179 0 171 226 149 1 255 128 128]

代码语言:javascript
运行
复制
% Octave
pkg load image;
RGB = uint8 (cat (3, [0, 255, 255, 0,   0,   0,   255], ...
                     [0, 0,   255, 255, 255, 0,   255], ...
                     [0, 0,   0,   0,   255, 255, 255]));
RGB2Y = rgb2ycbcr(RGB)

RGB2Y = ans(:,:1)= 16 81 210 145 170 41 235 ans(:,:,2) = 128 90 16 16 54 166 240 128 ans( :,3) = 128 240 146 34 16 110 128

因此,如果这是实现一致性的问题,我将使用从模拟到数字的转换公式来缩放python结果,在上面的wikipedia页面中提到了这一点,即:

如果这是一个“哪个版本最适合计算PSNR”的问题,我不知道,但从我在上面的链接中看到的,我的钱将在matlab /八度实现上。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44944455

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档