如何找到两幅图像之间的差异? [英] How to find the difference between two images?

查看:375
本文介绍了如何找到两幅图像之间的差异?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个屏幕共享应用程序。在这个项目中,我需要在互联网上传输图像。很显然,我不能发送新照片在互联网上每隔几秒钟,这将是非常慢。
我想在服务器的屏幕的一个图像发送到客户端,事后,而不是发送一个新的画面只发送像素自上次图像(一个客户端已经拥有)已被更改。

I'm developing a screen-sharing application. In this project I need to transport images over the internet. Obviously, I can't send a new picture over the internet every few seconds, it would be extremely slow. I want to send one image of the server's screen to the client, and afterwards, instead of sending a new picture sending only the pixels that have been changed since the last image (the one the client already has).

我写了这个code:

private List<Color> CompareBitmaps(Image old, Image _new)
{
    List<Color> returnList = new List<Color>();

    for(int i = 0; i < old.Width; i++)
        for (int j = 0; j < old.Height; j++)
        {
            if (((Bitmap)old).GetPixel(i, j) != ((Bitmap)_new).GetPixel(i, j))
            {
                returnList.Add(((Bitmap)_new).GetPixel(i, j));
            }
        }

return returnList;
}

然而,它的工作方式过于缓慢。

However, it works way too slow.

我正在寻找更快的算法,一个具有较好的复杂性。

I'm looking for a faster algorithm, one with a better complexity.

请注意:我不想建库,做到这一点。我需要一个算法。

Note: I don't want a built library that does that. I need an algorithm.

推荐答案

该程序发现两个位图之间的差异,并通过一切设置几乎是黑色的和pretty透明得多一号位图返回他们。它也可以通过将结果返回到previous图像恢复原始第二文件..

This routine finds the differences between two Bitmaps and returns them in the 1st Bitmap by setting everything else to almost black and pretty much transparent. It can also restore the original 2nd file by adding the result back into the previous image..

我缩水800MB 1O 12K的截图 - 但实际上只不过是在钟手中一个非常小的变化;-)如果你的图像的像素数量不同,COM pression不会像spectacular..but我相信这将b不够好tranmitting我怀疑由像素的基础上任何事情都会比较的PNG或JPG文件格式的COM pression程序。(你不传输BMP的,我希望!)

I shrunk a screenshot of 800MB 1o 12k - but there was really just a very small change at the Clocks hands ;-) If your images differ in many pixels, the compression will not be as spectacular..but I believe it will b good enough for tranmitting and I doubt anything on a pixel by pixel basis will compare to the compression routines of png or jpg file formats.. (you don't transmit bmps, I hope!)

该例程使用LockBits是pretty快。

The routine uses LockBits and is pretty fast.

在布尔参数决定是否创建差异位图或恢复更改的位图。

The bool parameter decides whether to create the difference bitmap or to restore the changed bitmap.

public static Bitmap Difference(Bitmap bmp0, Bitmap bmp1, bool restore)
{
    int Bpp = 4;  // assuming an effective pixelformat of 32bpp
    var bmpData0 = bmp0.LockBits(
                    new Rectangle(0, 0, bmp0.Width, bmp0.Height),
                    ImageLockMode.ReadWrite, bmp0.PixelFormat);
    var bmpData1 = bmp1.LockBits(
                    new Rectangle(0, 0, bmp1.Width, bmp1.Height),
                    ImageLockMode.ReadOnly, bmp1.PixelFormat);

    int len = bmpData0.Height * bmpData0.Stride;
    byte[] data0 = new byte[len];
    byte[] data1 = new byte[len];
    Marshal.Copy(bmpData0.Scan0, data0, 0, len);
    Marshal.Copy(bmpData1.Scan0, data1, 0, len);

    for (int i = 0; i < len; i += Bpp)
    {
        if (restore)
        {
            bool toberestored = (data1[i  ] != 2 && data1[i+1] != 3 && 
                                 data1[i+2] != 7 && data1[i+2] != 42);
            if (toberestored)
            {
                data0[i  ] = data1[i];    // Blue
                data0[i+1] = data1[i+1];  // Green 
                data0[i+2] = data1[i+2];  // Red
                data0[i+3] = data1[i+3];  // Alpha
            }
        }
        else
        {
            bool changed = ((data0[i  ] != data1[i  ]) ||  
                            (data0[i+1] != data1[i+1]) || (data0[i+2] != data1[i+2]) );
            data0[i  ] = changed ? data1[i  ] : (byte)2;   // special markers
            data0[i+1] = changed ? data1[i+1] : (byte)3;   // special markers
            data0[i+2] = changed ? data1[i+2] : (byte)7;   // special markers
            data0[i+3] = changed ? (byte)255  : (byte)42;  // special markers
        }
    }

    Marshal.Copy(data0, 0, bmpData0.Scan0, len);
    bmp0.UnlockBits(bmpData0);
    bmp1.UnlockBits(bmpData1);
    return bmp0;
}

注意:
- 我已经选择了一个特殊的颜色来标记那些需要在收件人要恢复像素。在这里,我选择了阿尔法= 42 R = 7; G = 3; B = 2; ..没有100%安全的,但差不多;不是很多的像素将被错过;也许你没有tranparency呢..?

Notes: - I have chosen a special color to mark those pixels that need to be restored at the recipient. Here I chose alpha=42 and R=7; G=3; B=2;.. Not 100% safe but almost; not a lot of pixels will be missed; and maybe you don't have tranparency anyway..?

我附上两个较小的图像,无论是png格式,400KB左右:

I append two smaller images, both PNGs, around 400kB:


这是差分图像(3KB):

This is the difference image (3kB):

恢复的图像是相同的第二图像

The restored image is the same as the 2nd image.

这篇关于如何找到两幅图像之间的差异?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆