Python 检查两幅图像的RGB值之间的差异

Python 检查两幅图像的RGB值之间的差异,python,python-3.x,image,opencv,math,Python,Python 3.x,Image,Opencv,Math,现在我有了一个代码来提取RGB值并计算两幅给定图像之间的差异,但我注意到一幅图像中存在一个问题,这让我停下来思考我是否做对了 这是我的代码: import cv2 import math dif_R = 0 dif_G = 0 dif_B = 0 img = cv2.imread("image1.jpg", cv2.IMREAD_COLOR) imgcom = cv2.imread("image2.jpg", cv2.IMREAD_COLOR) pixel = 100 / (img.sh

现在我有了一个代码来提取RGB值并计算两幅给定图像之间的差异,但我注意到一幅图像中存在一个问题,这让我停下来思考我是否做对了

这是我的代码:

import cv2
import math

dif_R = 0
dif_G = 0
dif_B = 0

img = cv2.imread("image1.jpg", cv2.IMREAD_COLOR)
imgcom = cv2.imread("image2.jpg", cv2.IMREAD_COLOR)


pixel = 100 / (img.shape[0] * img.shape[1])
for ih in range(img.shape[0]):
    for iw in range(img.shape[1]):
        pixelB, pixelG, pixelR = img[ih][iw]

        pixelR = int(pixelR)
        pixelG = int(pixelG)
        pixelB = int(pixelB)

        pixelcomB, pixelcomG, pixelcomR = imgcom[ih][iw]

        pixelcomR = int(pixelcomR)
        pixelcomG = int(pixelcomG)
        pixelcomB = int(pixelcomB)

        if pixelR != pixelcomR:
            dif = math.fabs(pixelR - pixelcomR)
            dif_R += (dif / 255) * pixel

        if pixelG != pixelcomG:
            dif = math.fabs(pixelG - pixelcomG)
            dif_G += (dif / 255) * pixel

        if pixelB != pixelcomB:
            dif = math.fabs(pixelB - pixelcomB)
            dif_B += (dif / 255) * pixel

print(dif_R, dif_G, dif_B)
我的图像如下:

正如您看到的,如果执行代码,则R的差异为11.78,G的差异为14.02,B的差异为16.66。但是您可以清楚地看到第一个图像是紫色的,而另一个是橙色的

我看到一个可选的方法,就是使用lab colorspace。这种方法的差异越来越大,但我需要rgb值。。。不知道我该怎么办


如何解决此问题或做其他事情以获得最佳准确的差异?我的代码有什么地方做错了吗?

我想首先指出,您尝试实现这一目标的方式效率很低-在处理图像时,绝对不需要逐个循环像素值。Numpy具有很强的矢量运算能力,为您节省了宝贵的时间,尤其是在处理大量图像时。我提供给你一个不同的实现,从我对问题的理解来看,应该可以解决你的问题

from PIL import Image
import numpy as np

def jpg_image_to_array(image_path):
    """
    Loads JPEG image into 3D Numpy array of shape (width, height, channels)
    in double precision 
    """
    with Image.open(image_path) as image:
        im_arr = np.fromstring(image.tobytes(), dtype=np.uint8)
        im_arr = im_arr.reshape((image.size[1], image.size[0], 3)) /255
    return im_arr

img1 = jpg_image_to_array("1.jpg")
img2 = jpg_image_to_array("2.jpg")
diff = np.absolute(img1 - img2) 
print(np.sum(diff,axis=(0,1)))
请注意,此代码计算R、G、B通道之间的绝对差值,然后将此差值相加。您的图像的结果是:

[289702.61960608 344853.21176722 409960.28628742]
其中,前三个数字分别是R、G、B通道中的差值之和。这对我来说很有意义,因为你的图像中有1281 x 1920像素

如果要查找平均差异,可以将此列表除以像素数,即:

n_pixels = img1.shape[0]*img1.shape[1]
其结果是:

[0.11778828 0.14021159 0.16668305]

尽量避免将
用于带有Numpy的
循环,它是完全矢量化的:

import cv2
import numpy as np

# Load images
im1 = cv2.imread("image1.jpg", cv2.IMREAD_COLOR)
im2 = cv2.imread("image2.jpg", cv2.IMREAD_COLOR)

# Calculate absolute differences
absdiff = np.abs(im1.astype(np.float) - im2.astype(np.float)) 

# Calculate mean error for each channel
Berr = np.mean(absdiff[...,0])
Gerr = np.mean(absdiff[...,1])
Rerr = np.mean(absdiff[...,2])
您可以将最后3行写成:

Berr, Gerr, Rerr = [np.mean(absdiff[...,chan]) for chan in {0,1,2}]

现在我使用这个代码,但是在这张图像中效果很好,但是在对比度高的图像中,阴影的百分比太高了不?您可以将
absdiff
图像显示为灰度图像,并可以看到最亮的区域,即图像之间的差异更大的区域,以及较暗的区域,即它们更相似的区域。您还可以使用其他度量,RMS误差、峰值绝对误差等。您还可以在不同的颜色空间中查看误差。这取决于你的数据和对你来说什么是重要的。好吧,这对我来说很有用,但是。。。如果我想对灰度进行同样的处理?您想将RGB图像转换为灰度,然后计算像素值的平均差值吗?是的,我想这样做。因为我对灰度图像有问题