请注意,此答案没有说明,也从未说明,加载灰度与加载彩色并随后转换为灰度之间没有区别。它只是声明:
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))