两副图片的差异比较的C#实现

本文介绍了一种简单实用的图片差异检测方法,通过将图片分割成小块并比较每个小块内的像素差异来确定图片间的变化区域。该方法适用于快速识别两幅图像之间的不同之处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简单实现方法就是:将两副图片同时按一定大小的小块“切分开”,再分别比较这些小块,如果某个块里出现有一个不同的象素点,那就认为此块所在的位置是有差异的否则认为是相同的,当比较完所有小块后,两副图之间的不同之处的位置也就出来了。因为要进行所有小块比较,所以最坏的情况下是要扫描比较图片的所有象素点(两副图完全一样的情况时),最理想的情况就是只扫描比较所有小块的第一点(两副图完全不一样的情况时)。

这种方法的判断精确性是根据“块”大小来决定的,也就是如果你将“块”设得过大,判断的“精确性”就越低(因为只要块里有一点不相同,就认为此块位置是有差异的),如将“块”设置得过小,则判断的“精确性”就越高,但需要时间也有可能会越多!

 

如有下面的两副图:(以下图借用了stg609 的《Dot Net下实现屏幕图像差异获取v1.0》文章里的截图,呵)

                             

            (第一幅图片)                                                               (第二幅图片)

 

将上面两幅图按20*20(px)大小“切分”:

                      

            (第一幅图片)                                                               (第二幅图片)

 两副图都分别“切分”成多个20*20的小块,程序再分别对这些小块进行判断,如果“扫描”到小块里的某个象素点是不相同的则记录此块的坐标位置并退出当前块的扫描,继续扫描下一个小块,直到所有小块“扫描”完成。

在程序处理时为提高速度,利用了Bitmap的LockBits方法,直接对图片的内存数据操作,并且“切分”图片的小块时,并不真正的“切图”,而是利用“内存指针”进行数据定位操作。如下面代码:

 代码

                     while  (h  <  bd1.Height  &&  h  <  bd2.Height)
                    {
                        
byte *  p1  =  ( byte * )bd1.Scan0  +  h  *  bd1.Stride;
                        
byte *  p2  =  ( byte * )bd2.Scan0  +  h  *  bd2.Stride;

                        w 
=   0 ;
                        
while  (w  <  bd1.Width  &&  w  <  bd2.Width)
                        {
                            
// 按块大小进行扫描
                             for  ( int  i  =   0 ; i  <  block.Width; i ++ )
                            {
                                
int  wi  =  w  +  i;
                                
if  (wi  >=  bd1.Width  ||  wi  >=  bd2.Width)  break ;

                                
for  ( int  j  =   0 ; j  <  block.Height; j ++ )
                                {
                                    
int  hj  =  h  +  j;
                                    
if  (hj  >=  bd1.Height  ||  hj  >=  bd2.Height)  break ;

                                    ICColor
*  pc1  =  (ICColor * )(p1  +  wi  *   3   +  bd1.Stride  *  j);
                                    ICColor
*  pc2  =  (ICColor * )(p2  +  wi  *   3   +  bd2.Stride  *  j);

                                    
if  (pc1 -> !=  pc2 -> ||  pc1 -> !=  pc2 -> ||  pc1 -> !=  pc2 -> B)
                                    {
                                        
// 当前块有某个象素点颜色值不相同.也就是有差异.

                                        
int  bw  =  Math.Min(block.Width, bd1.Width  -  w);
                                        
int  bh  =  Math.Min(block.Height, bd1.Height  -  h);
                                        rects.Add(
new  Rectangle(w, h, bw, bh));

                                        
goto  E;
                                    }
                                }
                            }
                        E:
                            w 
+=  block.Width;
                        }

                        h 
+=  block.Height;
                    }

 示例项目代码下载:/Files/kingthy/ImageComparer.zip

上面两幅图的差异比较后的截图:(两图中蓝色与红色框框内的小块就是表明有差异的小块)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值