2014-11-02 118 views
0

我正在尝试制作基于浏览器的远程桌面控制器。为此,我正在做的是获取远程桌面的屏幕截图并定期将其发送给客户端。但这种方法效率很低,因为屏幕变化不大。所以我想做的只是传输连续截图的区别。这样我就可以增加fps了。最初我使用Python的PIL库将屏幕截图转换为像素数组,然后比较这两个数组以找出不同的像素并仅发送那些像素。但是要花费很多时间才能找到屏幕截图的像素数组。 然后我遇到了也可以用来表示图像的字节数组。将图像转换为字节数组比将其转换为像素数组(rgba)快得多。但我如何解释字节数组。什么是存储在图像的字节数组中?图像的字节数组

bytes = readimage("./scimg1.png") 

i = 0 
bytearr = [] 
while i < len(bytes): 
    bytearr.append(bytes[i]) 
    i+=1 

如何使用该字节组比较两个图像,并把他们的区别:我使用这段代码转换的字节数组为8个整数的数组。我发现这个数组的长度对于两个尺寸相同(长度,宽度)的图像来说是不同的。

+0

你可以使用外部库如numpy吗? – Eric 2014-11-02 08:53:11

+0

基本上你试图重新实现某种视频流。现在已经有涉及视频编解码器的解决方案,这可能会产生更好的效果 – Eric 2014-11-02 08:55:09

+0

@Eric是的!我可以使用外部库。 – user3286661 2014-11-02 09:08:32

回答

1

通常逐字节比较在所有情况下都不会有效。您可以使用此代码from this article来检查图像之间的差异。你可以根据你的需要来检查它的差异。

from itertools import izip 
import Image 

i1 = Image.open("image1.jpg") 
i2 = Image.open("image2.jpg") 
assert i1.mode == i2.mode, "Different kinds of images." 
assert i1.size == i2.size, "Different sizes." 

pairs = izip(i1.getdata(), i2.getdata()) 
if len(i1.getbands()) == 1: 
    # for gray-scale jpegs 
    dif = sum(abs(p1-p2) for p1,p2 in pairs) 
else: 
    dif = sum(abs(c1-c2) for p1,p2 in pairs for c1,c2 in zip(p1,p2)) 

ncomponents = i1.size[0] * i1.size[1] * 3 
print "Difference (percentage):", (dif/255.0 * 100)/ncomponents 

检查也filecmp.cmp()filecmp package它可能会有所帮助。

UPDATE

我是想检查哪些是两幅图像之间进行比较的最快方法:Pixel by PixelPIL或使用statistical techniques,但我无法注意到性能的巨大差异。这个问题可能与图像的重量有关。

from PIL import Image, ImageChops 

pixelsDifference = ImageChops.difference(Image.open('image1.png'), Image.open('image2.png')).convert('L') 
pixelsDifference = pixelsDifference.point(([0] + ([255] * 255))) 
Img = pixelsDifference.convert('RGB') 
+0

找到两个截图之间的差异仍然需要很长时间。 (百分比):4.38976009701 real \t 0m1。241s user \t 0m1.225s sys \t 0m0.016s – user3286661 2014-11-02 09:13:10

+0

@ user3286661我试图比较每个图像的像素,当我偶然发现这个线程。尝试在你身边提到的Snippit,并让我知道如果不工作,所以我们可以尝试找到其他的选择。 http://stackoverflow.com/a/1927681/4179775 – 2014-11-02 12:44:34

0

我会建议使用的视频编码库如PyMediapyffmpeg。显然你在这里优化速度,在传输图像方面可能没有比这更快的速度。 PyMedia只支持mpeg1和2,这些都很古老。

您的其他选择是放弃自定义方法并绑定已经存在的内容,例如用于任何平台的Windows或VNC的RDP协议。 (VNC不是那么敏感)

0

您可以将图像与ImageChops模块区别开来。您可以使用ImageChops.difference(image1,image2)来获取这两个屏幕截图之间的区别。

在发送图像之前,您还应该使用gzip压缩图像。这样你就需要在每一帧都发送较少的数据。这里是gzip library的文档。