因为我的的图像很多(10多万张),我用的几个算法,匹配速度要2秒(720*576),准确度还高,但经理说太慢了,要用MS来计算,请各位兄台帮忙,有没有好的匹配算法。
要求:{ 速度, 准确度(只能差1-2个像素) }请大家多多发言谢了。

解决方案 »

  1.   

    old=GetTickCount();............
    匹配图片
    ............now=GetTickCount();usetime=now-old;   //单位是ms
      

  2.   

    720*576的应该不到0.02秒才对
    你每次要读入大量的图片到内存,比如1024张,然后用memcmp函数对比内存,不能自己比另外,如果你这种做法有问题,应该给10万服图片建立出一个hash索引,比如每个图都提取几个固定点的颜色,然后计算出一个整数,存储起来。你新来的图片,也按照这样计算出一个整数,然后只要找哪些图片的索引和他一样,然后再再做详细的对比,这样能节省上千倍的时间
      

  3.   

    duqiang2050(杜杜)  720*576的应该不到0.02秒才对?  不会吧这个快啊。能不能说说你的方法? 急,看到你的话我非常兴奋, 真的求你了。我把我的图说一下:
    有10万张图都是有CCD拍的,邻近的图有120左右个像素的重叠,有色差,有时可能在拍第二张时突然有一个尘埃这样可能使与第一张重叠的部分多出了一个(30*30多像素)杂质。非常想看看你的思路。
      

  4.   

    他所说的使用memcmp的方法是假设图片是完全一样的,即每一个像素都是一样的,这样才能使用内存比较,当然你的实际情况并非这样,而且有色差,所以就不能用这种方法。
    对于你的图,我想可能转换成灰度图,然后再比较某一区域(8x8或者16x16像素)的亮度差绝对值,这样会快些准确些。如果可能的话,还要做下图像修正。
      

  5.   

    shines(Othelloing) 
    你好,我是将对应像素差的绝对值比较但是不准确我认为是种方法跟我以前的那种方法在准确度上差不多。如果这个能准确的得到的话,优化性非常的高,若我用2次误差的话可能可以达到0.0X秒。关健最主要的还没有搞定,我读到了每个像素都正确可不知为什么不行。 我真郁闷,
      

  6.   

    还是把代码写出来吧。
    /*///////////////////////////////
    *
    *  功能:  
    *         从左图中找到与右图中给定块的最大相似区的坐标
    *  参数:  
    *  LeftDIB_RightTopPos  最大相似块在左图中的起点坐标
    *         RightDIB_LeftTopPos  最大相似块在右图中的起点坐标            
    *         iAdd                 为重载而加的,在程序中无用途
    *  返回: 
    *         合并成功返回true, 否则返回false 
    *  程序员:
    *         陈小凌
    *  日期:  
    *         2003-8-20
    *  
    *////////////////////////////////
    bool CMergeDIB::FindSimilarBlockPos(CPoint& LeftDIB_RightTopPos, CPoint& RightDIB_LeftTopPos, int iAdd)
    {
      // 左图平分的块数
      const UINT BlockNum = 6;  // 左图中搜索区域
      const int SubDIB_Width =  bmp1.bmp_Width - bmp1.bmp_Width * 4/5;  
      const int SubDIB_Height = bmp1.bmp_Height * 3/BlockNum;            

      // 模板区域值
      const int Template_W = BLOCKWIDTH;
      const int Template_H = BLOCKHEIGHT;

      // 左右图像素
      BYTE LeftPix;
      BYTE RightPix;

      // 指向左子图起点,右图模板起点
      BYTE* LeftSubDIB = bmp1.lpDIB + (bmp1.bmp_Width * 4/5) * (bmp1.bmp_BitCount/8);
      BYTE* RightTmpDIB = bmp2.lpDIB + (bmp2.bmp_line_w * bmp2.bmp_Height *   1/BlockNum);  // 循环变量
      int rw = 0, rh = 0, lw = 0, lh = 0;

      // 相同点的位置
      UINT SimilarX = 0;
      UINT SimilarY = 0;  // 允许累加最大值
      long MinD = 999999999;   

      // 累加中间值
      long TempD = 0;
      
      // 两像素之差
      int Disparity = 0;  // 误差阀值
      UINT Ethreshold = 0;
      Ethreshold = ArEthreshold * (Template_W+1)/2 * (Template_H+1)/2;
      
      // 粗匹配
      UINT Left_StartX = bmp1.bmp_Width * 4/5;            
      UINT Left_StartY = 0;
      UINT Right_StartX = 0;
      UINT Right_StartY = bmp2.bmp_Height * 1/BlockNum;   
      for (lh = 0; lh < SubDIB_Height - Template_H + 1; lh += 1)
        for (lw = 0; lw <SubDIB_Width - Template_W + 1; lw += 1)
        {
          TempD = 0;
          for (rh = 0; rh < Template_H && TempD < MinD; rh += 1)
         {
    for (rw = 0; rw < Template_W && TempD < MinD; rw += 1)
    {
                LeftPix = (BYTE)*(LeftSubDIB + (lw + rw) * (bmp1.bmp_BitCount/8) + (lh + rh) * bmp1.bmp_line_w); 
       RightPix = (BYTE)*(RightTmpDIB + rw * (bmp2.bmp_BitCount/8) + rh * bmp2.bmp_line_w);
      Disparity = (int)(LeftPix - RightPix);
      TempD += abs(Disparity);
    // 取绝对值
    if (Disparity < 0) 
      TempD -= Disparity;
    else
      TempD += Disparity;
    // 超过最大阀值停址后该块的的执行
    //if ( TempD <(int)Ethreshold )
    //  break;  
         }
      }
      if (TempD < MinD )
      {
        MinD = TempD;
        SimilarX = lw;
        SimilarY = lh;
      }
    }
     LeftDIB_RightTopPos.x = SimilarX + Left_StartX;
     LeftDIB_RightTopPos.y = SimilarY;
     RightDIB_LeftTopPos.x = 0;
     RightDIB_LeftTopPos.y = bmp2.bmp_Height/BlockNum;
     return true;
    }
    上面的代码没有优化,但是没有优化的代码为什么不准确呢,这样的算法没有什么问题啊,大家帮我看一下那里出错啊。 我精匹配没有写。
    那位大哥帮你纠正一下,若用原码更家谢谢。 要分只要你说我一定给。
      

  7.   

    我把我以前的算法优化了,可以达到250ms我但这个算法可以在100ms左右。帮忙看一下。
      

  8.   

    使用MMX汇编代码可以一次比较8Byte数据。
      

  9.   

    schwarzenegger(找不到服务器) 
    你的思路有点概念,能不能清楚一点。 谢谢你的发言。进来的朋友帮我看一下上面的那段代码,哪里有问题,或者说那个人有这种方法实现过,并到正确的
    认准图。