请那位做过全景图像拼接的大虾指点, 我在做全景图像的拼接,是通行将重合部分分割成小块,再进行灰度的比较,以此来找到一条缝合曲线,但是无法做到无缝拼接, 各位,有这方面的经验的请谈谈如何来实现.
解决方案 »
- 支持MFC的控制台工程,为什么要包含一个CWinApp对象?
- 苦恼都问题..如何让MFC程序的后期维护更方便
- 在ACTIVEX中LOAD一个MFC DLL(含有一个dialog),当关闭浏览器时出现Assertion错误
- 我现在在资源中建了一个对话框,也建了这个对话框的类文件,可是它把类文件放在了工程目录下的res下,我手工把它复制到工程目录下,然后
- 非常郁闷,关于IE工具栏,望高手帮忙。
- 怎么样才能使自己的程序界面的字体能随Window界面风格的变化而变化?UP有分啊
- 请问如何实现程序保留最近访问过的路径,并且以访问的时间排序,最近访问的靠前.
- ★★★ 轻松取分,小问题,进来吧 :-) ★★★
- 如何用直接写数据缓冲区的方法合成2张256色的位图来达到透明的效果?3次bitblt太慢。
- 急!!!win2000中树控件为何不能显示中文?
- bcg控件使用问题系列之四————怎样OUTLOOK面板上的图标分配ID?
- ado的问题
http://expert.csdn.net/Expert/topic/1988/1988156.xml?temp=.2311975
参考一下。
{
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里有没有加了我,一起交流一下,我晚上常在。
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; // 用这句
不好意思了。今晚有点事,不好意思,明天我在。