【问题标题】:Find the differences between two images for screen sharing apps查找屏幕共享应用程序的两个图像之间的差异
【发布时间】:2026-02-15 09:20:03
【问题描述】:

您好,我正在编写一个客户端/服务器远程查看器(桌面共享)应用程序,其中桌面的屏幕截图通过套接字通过网络发送。我想通过获取两个图像之间的差异然后发送差异来减少传输的大小。 另一方面,差异将与另一端的先前图像合并。

所以请任何人指导我如何完成这项工作。现在我仍然每次通过网络以编程方式发送屏幕的完整图像,而另一端的程序只显示该图像。我觉得巨大的数据正在通过网络传递,另一端的屏幕更新速度很慢。所以请告诉我如何比较两个图像并仅将差异发送到另一端的好方法。还告诉我如何将差异与另一端的实际图像合并。

1) 许多免费代码和库可用于图像比较,但我只是不明白我应该使用哪一个以及哪一个会更快进行比较。所以请指导我。

2)最重要的部分是如何仅通过网络发送差异并将差异与另一端的实际图像合并

我尝试了很多关于我的第 2 点的信息,但没有得到类似的信息。没有文章我发现谁能指导我如何仅通过网络发送差异并将差异与另一端的实际图像合并

所以我正在寻找关于我的第 2 点的深入讨论。谢谢

【问题讨论】:

  • 因此,如果您的图像上半部分是马,下半部分是人腿。另一幅图像有上半部马,下半部斑马。你想要斑马腿吗?然后做什么?当它们在同一个地方时,您将如何合并差异?
  • "另一端的屏幕更新速度很慢" 您是否尝试通过网络发送视频?已经有编解码器可以仅促进帧更新数据,您使用的是什么编解码器?还是您只发送图片 - 如果是,它们是什么格式的?
  • png 格式。只是指导我如何在当前图像上应用两个图像之间的差异?这对我来说非常重要。

标签: c# image-comparison screensharing desktop-sharing


【解决方案1】:

您必须遵循三个步骤:

  1. 创建两个连续图像的差异 (DIFF)。比较每个像素的两个图像像素将非常耗时。您应该使用像 OpenCV 这样完善的库;查看 .NET 的 Emgu CV 库 (http://www.emgu.com/):AbsDiff() 应该是您正在寻找的方法。结果将类似于 DIFF = IMG2 - IMG1。
  2. 通过网络发送 DIFF。它仍然是一个完整的图像,但 JPEG 或 PNG 将利用其完整的压缩能力,假设它是一个主要是黑色的图像,即很少的变化。所以这实际上是三个子步骤:压缩 - 发送 - 解压缩
  3. 在当前图像上应用 DIFF。接收者可以计算下一个图像 IMG2 = DIFF + IMG1。这可以使用 EmguCV 的 Add 方法来执行。

【讨论】:

  • 感谢您的帮助,但这一点尚不清楚 3) 在当前图像上应用 DIFF。请详细告诉我如何在当前图像上应用 DIFF?你能开车去任何代码或文章吗?非常感谢。
  • 我以前从来没有这个库。你能不能给我这个库的示例代码,我可以用它来创建两个连续图像的差异(DIFF)并在当前图像上应用 DIFF,即 IMG2 = DIFF + IMG1。谢谢
  • Emgu 实际上有一个优秀的文档。您可以在 Wiki 上找到 introduction 和一些 basic examples。这应该足以启动它。
  • Absolute 差异将不起作用,因为像素差异会给出将饱和为 0 的负值。因此无法重建。
  • 负值?有 abs() 所以 |a-b|总是给出正值 |10-250|是 240。但是在添加它们时,应该检查总和是否大于 255 进行减法而不是总和。但是我不知道两边的jus XOR是不是更好我今天会检查一下并给出一些评论。
【解决方案2】:

我知道回复很晚,但我今天发现了这个问题

我对图像差异进行了一些分析,但代码是为 java 编写的。请查看以下可能会有所帮助的链接

How to find rectangle of difference between two images

代码发现差异并将矩形保存在链接列表中。您可以使用包含矩形的链表将差异修补到基础图像上。

干杯!

【讨论】:

    【解决方案3】:

    我的方法怎么样,我不确定它是否有用,我希望有人能给我一些提示,我正在朝着正确的方向前进。

    我考虑将桌面流式传输到手机。我会使用带有网络 TCP 套接字的服务器-客户端模型。我考虑这样的模式(协议)。

    服务器:

    0)

    屏幕图像 - 表示为unsigned char *rgba_array IMAGE_SIZE -> 宽度、高度

    1)

    将图像尺寸宽、高发送给客户端。

    2)

    init rgba_array 长度

    0000 0000 0000 0000 0000 0000 0000 0000(示例像素 - 32 位)

    3)

    如果我有屏幕的新图像(屏幕截图?或其他方式),我会将其转换为unsigned char *new_rgba_array,然后进行 XOR 操作:

    rgba_array XOR new_rgba_array => diff_rgba_array 
    

    4)

    我只是将这个diff_rgba_array 压缩发送给客户? JPEG?

    5) 回到服务器端的第 3) 点。

    客户:

    0)

    get width and height -> init rgba_array with length

    1)

    得到diff_rgba_array,表示与之前的图像相比的变化并解压它? JPEG?

    0011 1010 0110 0111 1110 0000 0100 0000(示例像素差异)

    0 - 位表示没有变化

    1 - 位表示改变到相反的值

    2)

    将从diff_rgba_array 中的服务器收到的更改应用到rgba_array 在客户端。我想我应该进行下一个XORing。像这样

      10011101   10010101
    
      00001111   11111111 (XOR) 
    
    = 10010010   01101010 
    

    3)

    回到客户端的第 1) 点

    【讨论】: