ImageChops.difference 的定义

Pri*_*nce 4 python image-processing

我使用 ImageChops 库是为了使用差异函数来比较两个图像:

im1 = Image.open("image1.jpg")
im2 = Image.open("image2.jpg")
diff= ImageChops.difference(im1, im2)
Run Code Online (Sandbox Code Playgroud)

差分函数究竟是如何工作的?它实际上在做什么?

小智 8

ImageChops.difference 计算“两个图像之间逐像素差异的绝对值”,这会导致返回差异图像。它的代码位于https://github.com/python-pillow/Pillow/blob/master/src/PIL/ImageChops.py#L88。更准确地说,对于 2 张图像,image1 和 image2,它返回以下内容作为新图像:

image1.im.chop_difference(image2.im)
Run Code Online (Sandbox Code Playgroud)

在哪里:

  1. https://github.com/python-pillow/Pillow/blob/43c5f2cd649bdc8422dd2892b1e3349ea003fb46/_imaging.c#L3085 中, chop_difference 被定义为 (PyCFunction)_chop_difference

  2. _chop_difference 在https://github.com/python-pillow/Pillow/blob/43c5f2cd649bdc8422dd2892b1e3349ea003fb46/_imaging.c#L2016映射到 ImagingChopDifference

  3. ImagingChopDifference 是在https://github.com/python-pillow/Pillow/blob/4aba749c3c0ff0bc24b525886c0c89c3dca1d43f/libImaging/Imaging.h#L322 中引用的外部函数,并在http: //botpublic.chops.c 中定义。/tags/pil-1.1.4/libImaging/Chops.c为:

    ImagingChopDifference(Imaging imIn1, Imaging imIn2)
    {
        CHOP(abs((int) in1[x] - (int) in2[x]), NULL);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. CHOP 是以下类似函数的 C 宏,它也在 Chops.c 中定义。它将算术运算的结果剪辑到范围 (256) 内。请注意,在此代码中,“#”不是注释开头,而是“#define”是用于定义常量或创建宏的 C 指令。

    #define CHOP(operation, mode)\
        int x, y;\
        Imaging imOut;\
        imOut = create(imIn1, imIn2, mode);\
        if (!imOut)\
            return NULL;\
        for (y = 0; y < imOut->ysize; y++) {\
            UINT8* out = (UINT8*) imOut->image[y];\
            UINT8* in1 = (UINT8*) imIn1->image[y];\
            UINT8* in2 = (UINT8*) imIn2->image[y];\
            for (x = 0; x < imOut->linesize; x++) {\
                int temp = operation;\
                if (temp <= 0)\
                    out[x] = 0;\
                else if (temp >= 255)\
                    out[x] = 255;\
                else\
                    out[x] = temp;\
            }\
        }\
        return imOut;
    
    Run Code Online (Sandbox Code Playgroud)
  5. 使用 GNU C 预处理器 cpp 预处理(4)和(3)中的代码后,结果是可编译的 ImagingChopDifference 函数如下:

    static Imaging
    ImagingChopDifference(Imaging imIn1, Imaging imIn2)
    {
        int x, y;
        Imaging imOut; 
        imOut = create(imIn1, imIn2, NULL);
        if (!imOut) 
            return NULL; 
        for (y = 0; y < imOut->ysize; y++) {
            UINT8* out = (UINT8*) imOut->image[y]; 
            UINT8* in1 = (UINT8*) imIn1->image[y]; 
            UINT8* in2 = (UINT8*) imIn2->image[y]; 
            for (x = 0; x < imOut->linesize; x++) {
                int temp = abs((int) in1[x] - (int) in2[x]); 
                if (temp <= 0) 
                    out[x] = 0; 
                else if (temp >= 255) 
                    out[x] = 255; 
                else out[x] = temp; 
            }
        } 
        return imOut;
    }
    
    Run Code Online (Sandbox Code Playgroud)

GNU C 预处理器 cpp 广泛用于 Linux 和 Unix 系统。CentOS 7.0 手册页位于http://www.unix.com/man-page/centos/1/cpp/。其完整手册位于https://gcc.gnu.org/onlinedocs/cpp/index.html,其中包括有关宏的一章。

CHOP 是 CHannel OPeration 的首字母缩写,其中 channel 是指数字图像通道(参见https://en.wikipedia.org/wiki/Channel_%28digital_image),并且在http://effbot 中记录了对通道操作结果的剪辑。 org/imagingbook/imagechops.htm)。