青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

碎片圖像無縫拼合技術(shù)的VC++實現(xiàn)

摘要:本文講述了在Microsoft Visual C++ 6.0下多幅碎片圖像無縫拼合技術(shù)的實現(xiàn)原理和過程,并給出了部分關(guān)鍵代碼以供參考。

  關(guān)鍵字:Microsoft Visual C++ 6.0、圖像、無縫拼合、位圖文件

  一、 引言

  在測繪、文博等行業(yè)經(jīng)常會遇到這樣一種情況:觀測對象比較大,為保證分辨率又不能將其全部照下,只能進行局部照相,事后再將這些局部照相的重合部分去掉,拼合成一幅完整的圖像。以前多采用手工拼合,誤差較大,往往不能很好的實現(xiàn)無縫拼合,即使有少量的專業(yè)設(shè)備,成本也普遍較高。其實只需將照片通過掃描儀將其錄入到計算機中,通過程序處理,完全能很好的實現(xiàn)多幅圖像的無縫拼合,滿足實際需要,而且對于文博行業(yè)中常會遇到的破碎的、不規(guī)則對象如古舊字畫殘片等也能很好的進行無縫拼合。本文就對針對該程序的實現(xiàn)原理及過程做了簡要的介紹。

  二、 程序設(shè)計原理

  首先我們從實際出發(fā),我們是通過進行局部照相的手段來保存整體的全部信息,而要保證這些局部照片所含的信息之和能包括整體的全部信息就必然的使每兩幅鄰近的圖片有一部分交疊的部分,這樣才能保證在將整體對象劃分為若干局部照片而后再拼合成整體圖像的過程中不遺漏任何信息,即該劃分、拼合的整個過程是無損的。既然如此,我們只需能保證讓兩相鄰圖片的重疊部分能完全重合,那么我們也就能夠肯定在此狀態(tài)下的這兩幅圖像實現(xiàn)了無縫拼合。所以,問題就轉(zhuǎn)換為使相鄰圖片的重疊部分能完全重合,而判斷兩相同的圖像片段是否完全重疊可以用光柵掩碼來進行直觀的判斷,比如我們可以采用"異或"的掩碼,當相同位置上的兩幅圖片的像素相同時就為0即黑色,所以可以對兩圖片進行移動,只要重疊部分全黑,則表明此時兩圖像的重疊部分已準確的重合了,而此時也實現(xiàn)了圖像的無縫拼合。此后只需再采用"或"的光柵掩碼將合并后的圖像顯示出來,再通過拷屏等手段將其存盤即可。在實現(xiàn)拼合的全過程中主要涉及到圖像的拖放、圖像文件的讀取及顯示、光柵掩碼、拷屏以及內(nèi)存位圖的保存等多種技術(shù)。接下來就對這些技術(shù)的具體應(yīng)用進行介紹。

  三、 程序的具體實現(xiàn)

  在進行拼合之前,首先要將從掃描儀錄入的圖像從文件讀取到內(nèi)存中,并顯示出來。由于在拼合時采取的光柵操作掩碼是"異或",所以為保持圖像的原始面貌,可以在消息WM_ERASEBKGND 的響應(yīng)函數(shù)中用PatBlt函數(shù)將整個客戶區(qū)的初始背景設(shè)定為黑色:

……
pDC->PatBlt(0,0,rect.Width(),rect.Height(), BLACKNESS);
return TRUE;

  讀取位圖文件可以用LoadImage函數(shù)來實現(xiàn),m_sPath1指定了文件的路徑,LR_LOADFROMFILE屬性指定從文件中讀取位圖,返回值為該位圖的句柄:

……
HBITMAP hbitmap;
hbitmap=(HBITMAP)LoadImage(AfxGetInstanceHandle(),
m_sPath1,
IMAGE_BITMAP,0,0,
LR_LOADFROMFILE|LR_CREATEDIBSECTION);

  之后我們就可以創(chuàng)建一個和當前設(shè)備環(huán)境兼容的內(nèi)存設(shè)備環(huán)境hMemDC1,并將剛才讀取到內(nèi)存的位圖放置到該設(shè)備環(huán)境中:

hMemDC1=::CreateCompatibleDC(NULL);
SelectObject(hMemDC1,hbitmap);
::DeleteObject(hbitmap); //釋放掉用過的位圖句柄
Invalidate();

  至于位圖的顯示,由于需要頻繁的拖動和其他處理,將其放置于OnDraw函數(shù)中較為合理,需要更新顯示時只需顯式地用Invalidate()函數(shù)刷新即可。OnDraw()中的顯示位圖部分最好用BitBlt函數(shù)來完成,該函數(shù)負責(zé)把hMemDC1中的位圖放置到pDC頁面中以完成內(nèi)存頁面的置換,其處理速度還是比較快的:

……
::BitBlt(pDC->m_hDC,m_nX1,m_nY1, m_nWidth1,m_nHeight1,
hMemDC1,0,0,m_dwRop);
……

  函數(shù)中的m_dwRop變量對光柵操作碼進行設(shè)置,初始為SRCINVERT即光柵異或操作,當拼合成功需要顯示合并后的效果時再將其設(shè)定為SRCPAINT光柵或操作。

  我們可以通過對鼠標消息響應(yīng)函數(shù)的編程來實現(xiàn)在客戶區(qū)內(nèi)的位圖拖放,按照Windows系統(tǒng)的習(xí)慣,首先在鼠標左鍵的響應(yīng)函數(shù)中通過PtInRect()函數(shù)判斷鼠標在左鍵按下時是否是落在位圖上,如果是就可以在鼠標左鍵彈起之前將圖片隨鼠標拖動了,顯然這部分應(yīng)在WM_MOUSEMOVE消息的響應(yīng)函數(shù)內(nèi)編寫代碼:

……
if(m_bCanMove1==true) //在移動之前鼠標左鍵是在圖片上點擊的
{
 int dx=m_nOldX1-m_nX1; //計算鼠標距離圖片原點的距離
 int dy=m_nOldY1-m_nY1;
 m_nX1=point.x-dx; //計算新的圖片原點的坐標(客戶區(qū)坐標)
 m_nY1=point.y-dy;
 Invalidate(); //更新視圖
}
m_nOldX1=point.x; //保存上一次的鼠標位置
m_nOldY1=point.y;
……

  到此為止,可以運行程序?qū)Χ喾槠瑘D像進行拼合了,用鼠標拖動一幅圖像在另一幅圖像邊緣移動,由于采用了"異或"的光柵掩碼,兩幅圖片交疊的地方顏色會發(fā)生改變,但只有完全重合時才會全黑,表明此時的拼合是無縫的,將掩碼換為"或"即可將拼合后的圖像顯示出來。但此時只是保留在內(nèi)存中,還要經(jīng)過進一步的處理,才能將合并后的圖像存盤保留。

  首先要對合并后的圖像所在的矩形框的位置、大小進行判斷,可以用下面的類似代碼來完成(本例同時最多能有4幅圖像進行拼合):

……
int temp1,temp2,x0,y0,x1,y1;
temp1=m_nX1<m_nX2?m_nX1:m_nX2;
if(m_sPath3!="")//如果有3幅圖片參與拼合
{
 if(m_sPath4!="")//如果有4幅圖片參與拼合
  temp2=m_nX3<m_nX4?m_nX3:m_nX4;
 else
  temp2=m_nX3;
  x0=temp1<temp2?temp1:temp2;
}
else
 x0=temp1;
 ……
 temp1=m_nX1+m_nWidth1>m_nX2+m_nWidth2?m_nX1+m_nWidth1:m_nX2+m_nWidth2;
 if(m_sPath3!="")
 {
  if(m_sPath4!="")
   temp2=m_nX3+m_nWidth3>m_nX4+m_nWidth4?m_nX3+m_nWidth3:m_nX4+m_nWidth4;
  else
   temp2=m_nX3+m_nWidth3;
   x1=temp1>temp2?temp1:temp2;
 }
 else
  x1=temp1;

  可以用類似的代碼計算出y0和y1。在進行屏幕截圖之前必須將由x0,y0,x1,y1構(gòu)成的矩形由客戶坐標轉(zhuǎn)換成屏幕坐標,可以用ClientToScreen()函數(shù)來實現(xiàn)。下面是將屏幕指定區(qū)域以位圖形式拷貝到內(nèi)存中去的函數(shù)的主要實現(xiàn)代碼:

HBITMAP CImageView::CopyScreenToBitmap(LPRECT lpRect)
{
 ……
 // 確保選定區(qū)域不為空矩形
 if(IsRectEmpty(lpRect))
  return NULL;
 //為屏幕創(chuàng)建設(shè)備描述表
 hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
 //為屏幕設(shè)備描述表創(chuàng)建兼容的內(nèi)存設(shè)備描述表
 hMemDC = CreateCompatibleDC(hScrDC);
 ……
 // 創(chuàng)建一個與屏幕設(shè)備描述表兼容的位圖
 hBitmap = CreateCompatibleBitmap(hScrDC, lpRect->Width(),lpRect->Height());
 // 把新位圖選到內(nèi)存設(shè)備描述表中
 hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
 // 把屏幕設(shè)備描述表拷貝到內(nèi)存設(shè)備描述表中
 BitBlt(hMemDC, 0, 0, lpRect->Width(),lpRect->Height, hScrDC, lpRect->left lpRect->top, SRCCOPY);
 //得到屏幕位圖的句柄
 hBitmap =(HBITMAP)SelectObject(hMemDC, hOldBitmap);
 //清除
 DeleteDC(hScrDC);
 DeleteDC(hMemDC);
 ……
 // 返回位圖句柄
 return hBitmap;
}

  當把拼合后的區(qū)域拷貝到內(nèi)存,并獲取到該內(nèi)存位圖的句柄后可以將其通過剪貼板傳送到其他圖形處理軟件中進行進一布的處理,也可以按照位圖的格式直接將其保存成文件,為方便計,本例采用了后者。其實現(xiàn)過程主要是根據(jù)剛才獲取到的內(nèi)存位圖句柄按格式填充BMP文件的信息頭以及像素陣列,下面就結(jié)合實現(xiàn)的關(guān)鍵代碼進行介紹:
首先獲取設(shè)備描述表句柄,并用函數(shù)GetDeviceCaps()獲取到當前顯示分辨率下每個像素所占字節(jié)數(shù),并據(jù)此計算出調(diào)色板的大小:

……
hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC);
if (iBits <= 1)
 wBitCount = 1;
else if (iBits<= 4)
 wBitCount = 4;
else if (iBits<= 8)
 wBitCount = 8;
else if (iBits <= 24)
 wBitCount = 24; //計算調(diào)色板大小
……

  然后就可以設(shè)置位圖信息頭結(jié)構(gòu)了,其中bi 是BITMAPINFOHEADER 結(jié)構(gòu)的實例對象:

……
if (wBitCount <= 8)
 dwPaletteSize = (1<<wBitCount) *sizeof(RGBQUAD); //設(shè)置位圖信息頭結(jié)構(gòu)
 GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
 bi.biSize = sizeof(BITMAPINFOHEADER);
 bi.biWidth = Bitmap.bmWidth;
 bi.biHeight = Bitmap.bmHeight;
 bi.biPlanes = 1;
 bi.biBitCount = wBitCount;
 bi.biCompression = BI_RGB;
 bi.biSizeImage = 0;
 bi.biXPelsPerMeter = 0;
 bi.biYPelsPerMeter = 0;
 bi.biClrUsed = 0;
 bi.biClrImportant = 0;

  用GlobalAlloc()函數(shù)根據(jù)計算的結(jié)果為位圖內(nèi)容分配內(nèi)存,并返回分配得到的內(nèi)存句柄hDib,并用GetStockObject()來設(shè)置缺省狀態(tài)下的調(diào)色板:

……
dwBmBitsSize = ((Bitmap.bmWidth*wBitCount+31)/32)*4*Bitmap.bmHeight;
hDib = GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi; // 處理調(diào)色板
hPal = GetStockObject(DEFAULT_PALETTE);
if (hPal)
{
 hDC = ::GetDC(NULL);
 hOldPal =SelectPalette(hDC, (HPALETTE)hPal, FALSE);
 RealizePalette(hDC);
}
// 獲取該調(diào)色板下新的像素值
GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize,
(BITMAPINFO*)lpbi, DIB_RGB_COLORS);
//恢復(fù)調(diào)色板
if (hOldPal)
{
 SelectPalette(hDC,(HPALETTE)hOldPal, TRUE);
 RealizePalette(hDC);
 ::ReleaseDC(NULL,hDC);
}
……

  最后的工作就是創(chuàng)建位圖文件了,需要把設(shè)置好的位圖文件頭和像素點陣信息依次保存到文件中,其中bmfHdr 是BITMAPFILEHEADER位圖文件頭結(jié)構(gòu)的實例對象,需要按照BMP位圖的存盤格式對其進行設(shè)置:

……
fh = CreateFile(lpFileName,
GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL);
// 設(shè)置位圖文件頭
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER)+ dwPaletteSize;
//寫入位圖文件頭
WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
// 寫入位圖文件其余內(nèi)容
WriteFile(fh, (LPSTR)lpbi, dwDIBSize,&dwWritten, NULL);
……

  四、程序的實例檢測

  下面就通過一個實例--拼合一幅古代國畫殘片來對程序的拼合效果進行檢測。其中圖一到圖三是拼合前的三幅古代國畫殘片,圖四是經(jīng)過本程序處理后存盤得到的經(jīng)過無縫合成的圖片。經(jīng)過檢測,拼合效果還是相當不錯的,在碎片圖像的銜接處根本沒有接縫的存在:

碎片圖像無縫拼合技術(shù)的VC++實現(xiàn)(圖一)
圖一

碎片圖像無縫拼合技術(shù)的VC++實現(xiàn)(圖二)
圖二

 
碎片圖像無縫拼合技術(shù)的VC++實現(xiàn)(圖三)
圖三

碎片圖像無縫拼合技術(shù)的VC++實現(xiàn)(圖四)
圖四
 

  小結(jié)

  本程序通過一個實例講述了處理圖片無縫拼合的一種實用方法,在測繪、勘察、文博等行業(yè)均有較大的應(yīng)用潛力。在理解了程序的設(shè)計思路和編程思想的前提下,結(jié)合具體的實際需求,通過對本文具體代碼的改動可以設(shè)計出更適合本單位實際情況的類似軟件。另外,本文所講述的截取并保存屏幕技術(shù)在類似程序的編制上也可以提供一定的參考。本程序在Windows 2000 Professional下,由Microsoft Visual C++ 6.0編譯通過。

posted on 2008-09-10 19:27 wrh 閱讀(243) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


導(dǎo)航

<2008年4月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

統(tǒng)計

常用鏈接

留言簿(19)

隨筆檔案

文章檔案

收藏夾

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美jizz19性欧美| 亚洲精品久久久久久下一站| 久久成人免费电影| 亚洲欧美日韩精品一区二区| 亚洲女人天堂成人av在线| 在线一区二区三区做爰视频网站| 亚洲无限av看| 性欧美激情精品| 久久精品国产99精品国产亚洲性色| 亚洲尤物在线| 久久精品麻豆| 欧美激情在线有限公司| 91久久精品一区二区三区| 亚洲黄色三级| 亚洲一区二区网站| 久久一区二区三区av| 欧美美女bb生活片| 国产日韩欧美黄色| 亚洲日本免费| 欧美一级专区| 亚洲电影下载| 亚洲欧美欧美一区二区三区| 久久综合久久综合久久| 欧美日韩一区二区三区四区五区| 国产一区二区三区奇米久涩| 日韩午夜在线电影| 久久精品人人做人人爽| 亚洲国产一区在线| 欧美一级在线视频| 欧美日韩在线观看视频| 激情91久久| 性欧美精品高清| 亚洲人成亚洲人成在线观看| 亚洲欧美99| 欧美日韩麻豆| 亚洲黄色在线观看| 久久综合九色综合欧美狠狠| 一区二区三区四区五区视频| 久久尤物视频| 国产主播精品| 午夜精品久久久久久久久| 亚洲国产经典视频| 久久综合亚州| 一区二区三区在线视频观看| 欧美亚洲在线播放| 一区二区不卡在线视频 午夜欧美不卡在 | 先锋亚洲精品| 日韩写真视频在线观看| 久久一区二区三区av| 国产日韩欧美视频| 亚洲一区二区三区免费观看| 亚洲国产日韩一区| 欧美aa国产视频| 亚洲高清二区| 欧美成人在线影院| 牛牛国产精品| 亚洲免费av电影| 91久久综合亚洲鲁鲁五月天| 欧美大片在线看免费观看| 亚洲激情影院| 亚洲国产一区二区在线| 欧美国产亚洲另类动漫| 99国产精品久久| 亚洲精品乱码久久久久| 亚洲午夜未删减在线观看| 亚洲国产另类久久久精品极度| 久久综合九色综合欧美就去吻| 黄色综合网站| 欧美成人免费在线观看| 你懂的国产精品| 一区二区三区久久| 99pao成人国产永久免费视频| 欧美麻豆久久久久久中文| 夜夜嗨av一区二区三区免费区| 91久久久精品| 国产精品色一区二区三区| 欧美在线视屏| 久久美女性网| 99国产精品久久久| 亚洲在线一区二区| 国产一区二区三区在线观看免费视频 | av成人老司机| 国产精品久久久久77777| 久久久国产精品一区| 免费观看成人| 亚洲欧美日韩综合国产aⅴ| 欧美专区在线播放| 亚洲精品一区二区三区99| 亚洲视频在线一区| 亚洲第一级黄色片| 9久草视频在线视频精品| 国产一区二区三区av电影 | 亚洲国产精品一区二区第一页| 欧美日韩亚洲视频| 久久免费视频在线观看| 欧美成人精品h版在线观看| 亚洲欧美一区二区三区久久| 久久亚洲综合网| 亚洲欧美影院| 欧美国产日韩精品| 久久精品麻豆| 欧美丝袜一区二区| 欧美成人精品高清在线播放| 国产精品蜜臀在线观看| 亚洲大片一区二区三区| 国产日产亚洲精品系列| 91久久精品日日躁夜夜躁国产| 国产视频一区二区在线观看 | 国产日韩成人精品| 最新国产精品拍自在线播放| 国模吧视频一区| 亚洲天堂免费观看| 99国产精品久久久久久久| 久久久综合网| 久久精品国产欧美激情| 国产精品v欧美精品v日韩| 亚洲精品日日夜夜| 欧美午夜精品理论片a级大开眼界| 六月婷婷久久| 国产欧美短视频| 中日韩美女免费视频网站在线观看| 亚洲国产精品专区久久| 欧美一区二区高清| 欧美伊人影院| 国产精品久久久一区二区三区| 亚洲三级影院| 日韩香蕉视频| 欧美精品久久一区| 亚洲欧洲日本一区二区三区| 亚洲国产精品第一区二区| 久久久久在线观看| 麻豆成人综合网| …久久精品99久久香蕉国产| 久久狠狠亚洲综合| 久久夜色精品国产欧美乱| 国产欧美日韩精品专区| 亚洲综合色噜噜狠狠| 亚洲欧美福利一区二区| 国产精品理论片在线观看| 亚洲一区二区三区视频| 亚洲欧美成aⅴ人在线观看| 欧美日韩日本视频| 日韩视频在线观看| 亚洲一区二区不卡免费| 国产精品久久亚洲7777| 亚洲欧美国产日韩中文字幕| 久久国产免费| 伊人精品成人久久综合软件| 久久精品视频在线看| 欧美jizzhd精品欧美巨大免费| 亚洲国产一二三| 欧美日本亚洲韩国国产| 在线综合+亚洲+欧美中文字幕| 午夜精品视频在线| 国产在线精品一区二区夜色| 美女精品视频一区| 日韩小视频在线观看专区| 午夜日韩av| 在线视频国内自拍亚洲视频| 欧美激情综合五月色丁香小说| 999亚洲国产精| 久久人人爽国产| 99精品久久久| 国产一区二区观看| 欧美国产第二页| 亚洲免费一级电影| 亚洲高清免费| 欧美在线在线| 亚洲精选视频在线| 国产日韩一级二级三级| 免费不卡在线视频| 亚洲香蕉网站| 欧美风情在线观看| 亚洲欧美日韩视频一区| 亚洲国产美女| 国产精品色午夜在线观看| 免费在线欧美黄色| 亚洲欧美网站| 99国产精品久久久| 欧美91视频| 欧美在线亚洲在线| 亚洲视频碰碰| 亚洲欧洲精品一区二区三区 | 亚洲精品国产精品乱码不99| 国产精品久久久久久久久久直播 | 欧美在线影院| 一本大道久久a久久精品综合| 久久久久久亚洲精品中文字幕| 日韩一区二区久久| 黄色亚洲免费| 国产精品捆绑调教| 欧美日本中文| 欧美1区免费| 久久精品亚洲国产奇米99| 亚洲视频免费观看| 亚洲麻豆国产自偷在线| 亚洲国产日日夜夜| 欧美激情中文不卡| 欧美成人亚洲成人| 久热国产精品视频|