请那位做过全景图像拼接的大虾指点,    我在做全景图像的拼接,是通行将重合部分分割成小块,再进行灰度的比较,以此来找到一条缝合曲线,但是无法做到无缝拼接,    各位,有这方面的经验的请谈谈如何来实现.

解决方案 »

  1.   

    有一个做的非常好的软件:pixmaker,
      

  2.   

    什么论坛,我发出去了,他说我没有登陆,白写了那么多。
    http://expert.csdn.net/Expert/topic/1988/1988156.xml?temp=.2311975
    参考一下。
      

  3.   

    to : yellowwolf(你们把名给全起了所以我注册色狼) 看了你在另一贴子中的论述,对你的匹配算法不是太明白,能发一份你的code给我吗[email protected]
      

  4.   

    BOOL CDIB::SetComparDIB(BMP* bmp1, BMP* bmp2)
    {
      unsigned int TempArea = 0;
      MAXarea = 0;  int rightbmp_h= bmp2->bmp_Width / 3;
          // 从右图的第一像素开始与左图的每一象素比较
        for ( register int leftbmp_w =bmp1->bmp_Width; leftbmp_w >=0 ; leftbmp_w--)
        {  
          for (register unsigned int leftbmp_h = 0; leftbmp_h < bmp1->bmp_Height; leftbmp_h++)
          { 
            bmp2->Pix_X = 0; 
            bmp2->Pix_Y = rightbmp_h;  
            bmp1->Pix_X = leftbmp_w;          
            bmp1->Pix_Y = leftbmp_h;
            if (IsSamePix(bmp1,bmp2,bmp1->Pix_X,bmp1->Pix_Y,bmp2->Pix_X,bmp2->Pix_Y))
              if (IsSameCol(bmp1,bmp2,bmp1->Pix_X,bmp1->Pix_Y,bmp2->Pix_X,bmp2->Pix_Y))  
                IsSameRect(bmp1,bmp2);
          }
        }        if ( MAXarea != 0)
       { 
          MergeDIB(bmp1, bmp2); 
          return TRUE;
       }
        MessageBox (NULL, "没有找到合并点,不给于合并", NULL, MB_OK);
        return FALSE;
    }long CDIB::GetPixOffset (unsigned int X, unsigned int Y, BMP* bmp)
    {
       if ( (X >= 0 && X< bmp->bmp_Width) && (Y >= 0 && Y < bmp->bmp_Height))
         return ( Y * bmp->bmp_line_w + X * (bmp->bmp_BitCount / 8));
       return 0;
    }BOOL CDIB::IsSamePix(BMP* bmp1, BMP* bmp2,int x1,int y1, int x2,int y2)
    {
      BYTE *p, *q;
      p = bmp1->lpDIB + GetPixOffset(x1, y1, bmp1);
      q = bmp2->lpDIB + GetPixOffset(x2, y2, bmp2);  for (register int i = 0; i< bmp1->bmp_BitCount / 8; i++)
        if ( abs(p[i] - q[i]) > 25 ) return FALSE;
        //if ( p[i] != q[i])   return FALSE; 
      return TRUE;

    BOOL CDIB::IsSameCol(BMP *bmp1, BMP *bmp2,int x1,int y1,int x2,int y2)
    {
      unsigned int below_h1 = bmp1->bmp_Height - y1;   // 左图当点象素到图底部的长
      unsigned int below_h2 = bmp2->bmp_Height - y2;   // 右图当点象素到图底部的长
      unsigned int h = (below_h1 > below_h2) ? below_h2 : below_h1; // 得到两图中到图底部最短的长
      for ( register unsigned int i = 0; i <h; i++ )
      {   
        //   得到下一象素继续比较
        if (!IsSamePix (bmp1, bmp2,x1,y1,x2,y2))
            return FALSE; 
        y1 += 1;      
        y2 += 1;
      }
      return TRUE;
    }BOOL CDIB::IsSameRect(BMP *bmp1, BMP *bmp2)
    {
       unsigned int x1,y1,x2,y2;
       unsigned int w1 = bmp1->bmp_Width - bmp1->Pix_X ;
       unsigned int w2 = bmp2->bmp_Width - bmp2->Pix_X;
       unsigned int w = (w1 > w2) ? w2 : w1;
      
       x1 = bmp1->Pix_X; y1 = bmp1->Pix_Y;
       x2 = bmp2->Pix_X; y2 = bmp2->Pix_Y;
       for ( register unsigned int i = 0; i < w; i++ )
       {
         if ( !IsSameCol(bmp1,bmp2,x1,y1,x2,y2) )
           return FALSE;
           x1 ++;
           x2 ++;
       }   unsigned int h = (bmp1->bmp_Height - bmp1->Pix_Y) < (bmp2->bmp_Height - bmp2->Pix_Y) ?  (bmp1->bmp_Height - bmp1->Pix_Y) : (bmp2->bmp_Height - bmp2->Pix_Y);
       if(i*h >MAXarea) 
       {
         MAXarea = i*h;
         overlap_info.left_starX = bmp1->Pix_X;
         overlap_info.left_starY = bmp1->Pix_Y;
         overlap_info.left_endX = i + bmp1->Pix_X;
         overlap_info.left_endY = h + bmp1->Pix_Y; 
         overlap_info.right_starX = bmp2->Pix_X;
         overlap_info.right_starY = bmp2->Pix_Y;
         overlap_info.right_endX = i + bmp2->Pix_X;
         overlap_info.right_endY = h + bmp2->Pix_Y; 
       }
       return TRUE;
    }void CDIB::MergeDIB(BMP* bmp1, BMP* bmp2)
    {
       BYTE* unitbuff;
      
       unsigned int unit_w = bmp2->bmp_Width + overlap_info.left_starX;         // 合并文件后的宽
       unsigned int unit_h = overlap_info.left_endY - overlap_info.left_starY;  // 合并文件后的高
       
       int byte_w = unit_w * (bmp1->bmp_BitCount/8);   // 得到行真实数据
       if(byte_w%4) byte_w = byte_w + (4 - byte_w%4);  // 得到一行的数据属占的字节数
       
       int imagedata = byte_w * unit_h;                // 得到整个文件数据的属占的字节数
       
       if (!(unitbuff = new BYTE[imagedata]))
       {  
         MessageBox(NULL, "合并文件申请内存时失败", "内存申请", MB_OK);
         return;
       } 
       
       BYTE *p1, *p2, *p3;
       p1 = bmp1->lpDIB + overlap_info.left_starY * bmp1->bmp_line_w;
       p2 = bmp2->lpDIB + overlap_info.right_starY * bmp2->bmp_line_w;
       p3 = unitbuff;
       for ( unsigned int i=0; i < unit_h; i++)
       {
         memcpy (p3, p1, overlap_info.left_starX * (bmp1->bmp_BitCount / 8));
         p3 += overlap_info.left_starX * (bmp1->bmp_BitCount / 8);
         p1 += bmp1->bmp_line_w;
         memcpy (p3, p2, bmp2->bmp_Width * (bmp2->bmp_BitCount / 8));
         p3 += bmp2->bmp_Width * (bmp2->bmp_BitCount / 8);
         p2 += bmp2->bmp_line_w;
         if ( (unsigned int)(p3 - unitbuff) % 4 != 0)
           p3 += 4 - (unsigned int)((p3 - unitbuff) % 4);
       }
      
       Tempbmp.bmp_BitCount = bmp1->bmp_BitCount;
       Tempbmp.bmp_Height = unit_h;
       Tempbmp.bmp_Width = unit_w;   if (Tempbmp.lpDIB != NULL) 
          Tempbmp.lpDIB =NULL;
       Tempbmp.lpDIB = new BYTE[imagedata];
       if ( !Tempbmp.lpDIB )
       {  
         MessageBox(NULL, "申请内存时失败", "内存申请", MB_OK);
         return;
       }
      
       if ( bmp1->bmp_BitCount == 8 )
       {
         if ( !Tempbmp.lpPalette != NULL)
           Tempbmp.lpPalette = NULL;
         // 存取颜色表
         Tempbmp.lpPalette = new BYTE[sizeof(RGBQUAD) * PALETTESIZE(8)];
     memcpy(Tempbmp.lpPalette, bmp1->lpPalette, sizeof(RGBQUAD) * PALETTESIZE(8));
       }
       if ( bmp1->bmp_BitCount == 24 )
         Tempbmp.lpPalette = NULL;
      
       // 数据恢复文件中数据的顺序
       for (  i = 0; i < unit_h; i++ )
            memcpy ( Tempbmp.lpDIB + byte_w * i, unitbuff + byte_w * (unit_h - i - 1), byte_w);
          //  数据写入文件
        CFile pf("b.bmp", CFile::modeCreate|CFile::modeWrite);
        if ( pf == NULL )
        {
          MessageBox (NULL, "Create Merge file failed!", "Create file", MB_OK);
          return;
        }
        BITMAPFILEHEADER bm;
       
      bm.bfType = 0x4D42;
       bm.bfSize = imagedata;
      bm.bfReserved1 = 0;
      bm.bfReserved2 = 0;
      bm.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
      if (bmp1->bmp_BitCount != 24)
      bm.bfOffBits += PALETTESIZE(bmp1->bmp_BitCount)*sizeof(RGBQUAD);
      pf.Write(&bm,sizeof(BITMAPFILEHEADER));
     
       BITMAPINFOHEADER bmi;
      bmi.biSize = sizeof(BITMAPINFOHEADER);
      bmi.biWidth = unit_w ;
      bmi.biHeight = unit_h;
      bmi.biPlanes=1;
      bmi.biBitCount= bmp1->bmp_BitCount;
      bmi.biCompression=BI_RGB;
      bmi.biSizeImage=0;
      bmi.biXPelsPerMeter=0;
      bmi.biYPelsPerMeter=0;
       bmi.biClrUsed=0;
      bmi.biClrImportant=0;
       pf.Write(&bmi,sizeof(BITMAPINFOHEADER));   if (bmp1->bmp_BitCount != 24)
      pf.Write(bmp1->lpPalette, PALETTESIZE(bmp1->bmp_BitCount)*sizeof(RGBQUAD));
      
        pf.Write(Tempbmp.lpDIB,byte_w * unit_h);
       
       delete[] unitbuff;
       MessageBox(NULL,"两图合并后的文件写入成功!","合并文件信息",0);
       return ;
    }
    比点-》比列-》比块
    我现在做的跟你做的差不多,也是拍了几次的图拼合的,亮度不一样,用些好模,有点难。
    上面的代码你看一下,可能看这种图没有很大的帮助。
    QQ里有没有加了我,一起交流一下,我晚上常在。
      

  5.   

    我在拼有色差图。把代码改了一点
    rightbmp_h= bmp2->bmp_Height / 3;  // 取右图中中间某点
          // 从右图高的1/3开始与左图的每一象素比较
        for ( register int leftbmp_w =bmp1->bmp_Width; leftbmp_w >=0 ; leftbmp_w--)
     if ( abs(p[i] - q[i]) > 25 ) return FALSE;  // 注这句
        if ( p[i] != q[i])   return FALSE;  // 用这句
    不好意思了。今晚有点事,不好意思,明天我在。