如何计算两个图片的差异部分? ( 积分: 100 )

  • 主题发起人 主题发起人 warmfish
  • 开始时间 开始时间
W

warmfish

Unregistered / Unconfirmed
GUEST, unregistred user!
先后截屏的两张图片,想要计算两者有差异的最小部分
我用一个像素一个像素进行比对,可以出结果,但是CPU占用太高

请问各位前辈,有什么好的算法吗?
 
xusong168 能不能说的详细点啊?
 
像素比较是很慢的,还是一行一行比较吧,Bitmap.ScanLine
 
把两张图片的2进制异或一下
相同为0,不同为1,
这样就可以找出不同得了
 
我正在做的一个东西:
把newbmp里的图象和basebmp里的做对比,结果放到tmpbmp里,2张图象必须一样大
var
bmph,bmpw,i,j:integer;
p1,p2,p3: PByteArray;
begin
bmph:=basebmp.height;
bmpw:=basebmp.width;
for J:=0 to bmph-1 do
begin
P1 := basebmp.ScanLine[J];
P2 := newbmp.ScanLine[J];
P3 := tmpbmp.ScanLine[J];
for I:=0 to bmpw-1 do
P3 := P1 Xor P2;
end;
end;
 
上面的方法好像都无法避免 例 像素800*600的图片 循环480000次的情况
这样的CPU占用是相当高的
有没有更好的方法?
 
关注这个问题

以前也遇过,没好的解决方法!
 
不用管循环多少次......关键看实际速度......你比较下就知道了
刚改了下有个错误 应该是bmpw*3
我比较2个1024*768的图片几乎没感觉到有迟钝,CPU也看不到有多高
你要是用basebmp.Canvas.Pixels[x,y]自然效率会降低很多

procedure tform1.aa;
var
bmph,bmpw,i,j:integer;
p1,p2,p3: PByteArray;
begin
bmph:=basebmp.height;
bmpw:=basebmp.width;
tmpbmp.Height:=bmph;
tmpbmp.Width:=bmpw;
basebmp.PixelFormat:=pf24bit;
newbmp.PixelFormat:=pf24bit;
tmpbmp.PixelFormat:=pf24bit;
for J:=0 to bmph-1 do
begin
P1 := basebmp.ScanLine[J];
P2 := newbmp.ScanLine[J];
P3 := tmpbmp.ScanLine[J];
for I:=0 to bmpw*3-1 do
P3 := P1 Xor P2;
end;
end;
 
hs-kill没错,以前我做旋转图片的函数,一个点一个点操作比一行一行操作慢N倍
 
scanline 当然是更快了,不过好像还是不够快,特别是如果要在1秒之内处理多个图像的时候,你就会发现cpu的占用率多高了。

要是能处理差异部分,我想会好多了。。
 
现在就是要找差异啊.....
毕竟你不知道哪有不一样的,只能一个像素一个像素的对比
真正耗资源的不在480000次循环,而是你选用的操作所消耗的资源ScanLine是指针地址偏移来定位数据,Pixels用的是数组....
对于一个2进制数据流来说,指针偏移的效率自然要高很多

而多个图片的CPU占用......我觉得那是在于数值比较方面的资源消耗...这点,似乎无法避免吧,反正我是没想出方法来
刚才试了下,用memorystream直接对内存数据做偏移逐个字节比较的方法,和ScanLine的效率也差不多,而且还慢点....哈哈 改用汇编写应该效率差不多了
 
Bitmap.ScanLine 比 像素比较速度是快很多。
但必须要对PixelFormat进行赋值或者设定属性HandleType为bmDIB(缺省为bmDDB)。

如果:新创建了一个TBitmap对象实例,然后对其Height和Width赋值,然后用ScanLine访问其象素,速度就奇慢。
 
谢谢各位前辈
 
多人接受答案了。
 
后退
顶部