繁体   English   中英

同一张图像的2个灰度图像有何不同?

[英]How are the 2 gray scale images of the same image different?

将图像读取为灰度图像并将3通道图像转换为灰度图像之间有什么区别?

为了清楚起见,如果我阅读如下图像:

gray_1 = cv2.imread("model.jpg", 0)

colored = cv2.imread("model.jpg")

gray_2 = cv2.cvtColor(colored, cv2.COLOR_RGB2GRAY)

print(gray_1.shape) #(1152,1536)
print(gray2.shape)  #(1152, 1536)

现在,如果我检查两个numpy数组gray_1gray_2相等性,则它们不相等。

np.array_equal(gray_1, gray_2)

上面的语句返回False 这是为什么? gray_1gray_2什么gray_2

请注意,该答案没有陈述,也从未说过,灰度加载与彩色加载以及随后转换为灰度之间没有区别。 它仅指出:

1)OP需要使用cv2.COLOR_BGR2GRAY而不是cv2.COLOR_RGB2GRAY进行正确的比较,并且

2)对于准备使用有损JPEG来存储其图像的任何人,差异可能微不足道。


OpenCV本机以BGR顺序存储,因此真正的比较实际上是:

gray_2 = cv2.cvtColor(colored, cv2.COLOR_BGR2GRAY)

与使用cv2.COLOR_RGB2GRAY


量化由于直接以灰度加载而不是彩色加载然后进行转换的结果,这两个图像的“差异”可能会有所帮助,因此我计算了以下统计信息:

  • 绝对误差 -只是像素数不同

  • 峰值绝对误差 -任何两个对应像素之间的最大绝对差

  • 平均绝对误差 -相应像素之间的平均绝对差

  • 均方误差 -相应像素之间的均方差

  • 均方根误差 -上面的平方根

如果您使用标准的512x512 Lena图像,并将直接加载为灰度的图像与加载为彩色并随后转换的图像进行比较,则会得到以下结果:

AE: 139
PAE: 4
MAE: 0.00072479248046875
MSE: 0.001220703125
RMSE: 0.034938562148434216

因此,在262,144个像素中, 只有 139个像素存在差异,并且任何两个像素之间的最大差异在0..255范围内仅为4,即小于1.6%

相比之下,如果将保存为JPEG质量90和质量89的Lena图像进行比较,则会得到以下差异:

AE: 158575
PAE: 13
MAE: 0.9766883850097656
MSE: 2.2438392639160156
RMSE: 1.4979450136490378

因此,我是说JPEG质量的1%差异会导致100倍的像素相差3倍之多。 因此,您选择将数据存储为JPEG的事实比两种灰度转换方法的差异具有更大的影响,并且,如果您真正关心准确性,则应该使用PNG / TIFF / PPM或其他无损格式。


#!/usr/bin/env python3

import math
import numpy as np
from PIL import Image
import cv2

def compare(im1, im2, metric):
   """
   Compare two images in terms of given metric.
   'AE'   Absolute Error. Simply the number of pixels that are different.
   'PAE'  Peak Absolute Error. The largest absolute difference between two corresponding pixels.
   'MAE'  Mean Absolute Error. The average difference between correspondng pixels.
   'MSE'  Mean Squared Error.
   'RMSE' Root Mean Squared Error.
   """

   assert(im1.shape==im2.shape)

   im1 = np.ravel(im1).astype(np.int64)
   im2 = np.ravel(im2).astype(np.int64)

   if metric == 'AE':
      # Return count of pixels that differ
      res = (im1 != im2).sum()
      return res

   if metric == 'PAE':
      # Return largest absolute difference
      res = np.abs((im1-im2)).max()
      return res

   if metric == 'MAE':
      # Return average absolute difference between corresponding pixels
      res = np.abs((im1-im2)).mean()
      return res

   # Calculate mean squared difference between corresponding pixels
   res = ((im1-im2)*(im1-im2)).mean()

   if metric == 'MSE':
      return res

   if metric == 'RMSE':
      return math.sqrt(res)


# Uncomment any one of the three following blocks

# Create greyscale image 640x480 filled with mid-grey
#w,h = 640,480
#im1 = np.zeros([h,w,1], dtype=np.uint8) + 128
#im2 = im1.copy()
#im2[1,1]=7

# Load first image as greyscale, second as colour but then convert to greyscale afterwards
#gray_1   = cv2.imread('lena.jpg',cv2.IMREAD_GRAYSCALE)
#coloured = cv2.imread('lena.jpg',cv2.IMREAD_COLOR)
#gray_2   = cv2.cvtColor(coloured, cv2.COLOR_BGR2GRAY)

# Load Lena in 89 and 90 JPEG quality
gray_1   = cv2.imread('lena89.jpg',cv2.IMREAD_GRAYSCALE)
gray_2   = cv2.imread('lena90.jpg',cv2.IMREAD_GRAYSCALE)

res = compare(gray_1, gray_2, 'AE')
print('AE: {}'.format(res))
res = compare(gray_1, gray_2, 'PAE')
print('PAE: {}'.format(res))
res = compare(gray_1, gray_2, 'MAE')
print('MAE: {}'.format(res))
res = compare(gray_1, gray_2, 'MSE')
print('MSE: {}'.format(res))
res = compare(gray_1, gray_2, 'RMSE')
print('RMSE: {}'.format(res))

OpenCV在imload功能中使用内部编解码器。 但是对于cvtColor,它使用以下公式:

RGB[A] to Gray:Y←0.299⋅R + 0.587⋅G + 0.114⋅B

这是一种已知的行为(但看起来像个错误:))。 您可以在这里这里跟踪其历史。

另一个答案中提出的COLOR_BGR2GRAY将不起作用:

In [6]: gray1 = cv2.imread('1.png', 0)

In [7]: col = cv2.imread('1.png')

In [8]: gray2 = cv2.cvtColor(col, cv2.COLOR_RGB2GRAY)

In [10]: np.array_equal(gray1, gray2)
Out[10]: False

In [16]: gray3 = cv2.cvtColor(col, cv2.COLOR_BGR2GRAY)

In [17]: np.array_equal(gray1, gray3)
Out[17]: False

TLDR:他们不同,没关系。 只是忍受它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM