Обратите внимание, что в этом ответе не говорится и никогда не указывалось, что нет разницы между загрузкой в оттенках серого и загрузкой в цвете и последующим преобразованием в оттенки серого. Это просто утверждает, что:
1) OP должен будет использовать cv2.COLOR_BGR2GRAY
вместо cv2.COLOR_RGB2GRAY
для правильного сравнения и
2) разница, вероятно, незначительна для тех, кто готов использовать JPEG с потерями для хранения своих изображений.
OpenCV изначально хранится в порядке BGR, поэтому истинное сравнение будет на самом деле:
gray_2 = cv2.cvtColor(colored, cv2.COLOR_BGR2GRAY)
вместо использования cv2.COLOR_RGB2GRAY
.
Может быть полезно количественно определить «насколько различны» два изображения в результате загрузки непосредственно в оттенках серого по сравнению с загрузкой в цвете и последующим преобразованием, поэтому я вычислил следующую статистику:
Абсолютная ошибка - просто количество пикселей, которые отличаются
Пиковая абсолютная ошибка - наибольшая абсолютная разница между любыми двумя соответствующими пикселями
Средняя абсолютная ошибка - средняя абсолютная разница между соответствующими пикселями
Средняя квадратичная ошибка - средняя квадратическая разница между соответствующими пикселями
Ошибка среднего квадратного корня - квадратный корень из вышеперечисленного
Если вы используете стандартное изображение Lena 512x512 и сравниваете изображение, загруженное непосредственно в оттенках серого, с изображением, загруженным в цвет и затем преобразованным, вы получите следующие результаты:
AE: 139
PAE: 4
MAE: 0.00072479248046875
MSE: 0.001220703125
RMSE: 0.034938562148434216
Таким образом, из 262 144 пикселей только отличаются 139 пикселей, а разница максимум между любыми двумя пикселями составляет всего 4 в диапазоне 0..255, т.е. меньше 1.6 %
Для сравнения, если сравнить изображение Lena, сохраненное с качеством JPEG 90 и качеством 89, вы получите следующую разницу:
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))