对比两个图片。

flyforlove 2003-10-15 02:45:56
现在想做一个程序,实现两个图片对比,把相异点提出,另存为一个文件。
其实也就是,我先拍了一张背景图片,相机不动,再拍一张人的图片,
和那张背景图片比较,把人的像取出来。
我的实现是两张图片的pixels对比,取出R,G,B三值相比较,只要在一定的差值范围
内,我就认为是相同的(考虑到背景的光线变换等原因,只能这样做)。
现在的问题是1,处理速度慢,2,处理效果不理想。
谁有比较好的办法,请不吝赐教,谢谢。
...全文
388 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
zplinze 2003-10-19
  • 打赏
  • 举报
回复
我写一下大概的思路:
首先定义如下的数组,用于存储图像的灰度值 :
type
imgbuf=array[0..255,0..255]of byte;

for i:=0 to Imgwidth-1 do
for j:=0 to Imglenth-1 do
begin
imgbuf1[i][j]:=GetBValue(bitmap1.Canvas.pixels[i,j]);
imgbuf2[i][j]:=GetBValue(bitmap2.Canvas.pixels[i,j]);
end;
这个不用解释了吧,bitmap就是你的两张图片,imgwidth,imglenth是图像的长宽;bitmap1,bitmap2是两幅要处理

的图像。

然后计算两幅图像的差
for i:=0 to Imgwidth-1 do
for j:=0 to Imglenth-1 do
imgbuf3[i][j]:=abs(imgbuf2[i][j] - imgbuf1[i][j]);

for i:=0 to Imgwidth-1 do
for j:=0 to Imglenth-1 do
bitmap.Canvas.pixels[i,j]:=RGB(imgbuf3[i][j],imgbuf3[i][j],imgbuf3[i,j]);
image1.Picture.Graphic:=Bitmap;

此时的到的图像image1就是差图像了。背景是黑色的,人部分是一些很奇怪的颜色,但是边界很明显。别担心,下面进行阈值分割定义阈值 const limen = 50;根据你的图像特征进行选取,也和图像的亮度有关,你可以多试几次,选择一个合适的阈值。

for i:=0 to Imgwidth-1 do
for j:=0 to Imglenth-1 do
begin
if imgbuf3[i][j] < 50 then imgbuf4[i][j] := 0 else imgbuf4[i][j] := 255;
end;
这个时候的图像大体成型了,背景黑色,但是有些白色噪声(因为两次拍照的背景不可能完全一样),人像的区域为白色,但是有很多黑色噪声。接下来要做的就是腐蚀膨胀运算,用于去除噪声。
太晚了,写不下去了,你可以参考
http://www.yesky.com/SoftChannel/72342371928702976/20030731/1718121.shtml
是C++的,你改写成Delphi的就可以了。
腐蚀可以消除图像中小的噪声区域,膨胀可以填补物体中的空洞。对一个图像先进行腐蚀运算然后再膨胀的操作过程称为开运算,它可以消除细小的物体、在纤细点处分离物体、平滑较大物体的边界时不明显的改变其面积。如果对一个图像先膨胀然后再收缩,我们称之为闭运算,它具有填充物体内细小的空洞、连接邻近物体、在不明显改变物体面积的情况下平滑其边界的作用。通常情况下,当有噪声的图像用阈值二值化后,所得到的边界是很不平滑的,物体区域具有一些错判的孔洞,背景区域散布着一些小的噪声物体,连续的开和闭运算可以显著的改善这种情况,这时候需要在连接几次腐蚀迭代之后,再加上相同次数的膨胀,才可以产生所期望的效果。
zplinze 2003-10-16
  • 打赏
  • 举报
回复
呵呵,在RGB模式下处理速度当然慢了。你的目的是取出人所在的区域,所以可以先转换成灰度图,然后将两图的灰度直相减,产生一幅新的图像,该图像背景变成全黑,由于两幅图像相减,人的区域变成了向底片一样的图像,但是边界非常明显。对该图像做阈值分割,也就是说某个象素的灰度值大于某个阈值(这个阈值可以根据你的图像特征进行选取),则将其用黑色填充,否则填充为白色。此时人的部分变为黑色,边界十分明显,可是区域内有些噪声。对其做膨胀运算,就可以得到背景全黑,人的部分为白色的图像。根据这个图像,你就可以很容易的取出人像了。看看下图:
http://media.cs.tsinghua.edu.cn/~ahz/digitalimageprocess/chapter08/dilation.gif
huojiehai 2003-10-16
  • 打赏
  • 举报
回复
用多线程比较试试
zswangII 2003-10-16
  • 打赏
  • 举报
回复
从简单的角度思考~~
其实就是比较两张图片哪里发生了变化~~
也就是对各点进行异或的运算~~
参考如下代码~~

//Image1为背景图,Image2为人物图,Image3为目标图~~
procedure TForm1.Button1Click(Sender: TObject);
begin
Image3.Picture.Bitmap := Image1.Picture.Bitmap;

Image3.Canvas.CopyMode := cmSrcInvert;
Image3.Canvas.CopyRect(Image3.Canvas.ClipRect, Image2.Canvas, Image2.Canvas.ClipRect);

Image3.Canvas.CopyMode := cmSrcAnd;
Image3.Canvas.CopyRect(Image3.Canvas.ClipRect, Image2.Canvas, Image1.Canvas.ClipRect);
end;


//当然这是理想状态~~
//自然界里要两张图象的光度相同是不可能的~~
//所以你自己还需要加一些模糊处理~~
flyforlove 2003-10-16
  • 打赏
  • 举报
回复
zplinze(linze)
谢谢你给了这么详细的说明,但是对各个步骤的处理,我还是不能明确,
请问有这方面的数学公式的资料吗。
fengyvn 2003-10-15
  • 打赏
  • 举报
回复
专业问题,建议去问学美工的......
flyforlove 2003-10-15
  • 打赏
  • 举报
回复
为什么没人理我?:(,100分不够还可以再加的。

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi GAME,图形处理/多媒体
社区管理员
  • GAME,图形处理/多媒体社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧