Sobel邊緣提取新_第1頁
Sobel邊緣提取新_第2頁
Sobel邊緣提取新_第3頁
Sobel邊緣提取新_第4頁
Sobel邊緣提取新_第5頁
已閱讀5頁,還剩23頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、Sobel邊緣提取一、動態分割視圖窗口,一邊顯示原來的圖像,一邊顯示邊緣提取的圖像,如下圖所示:具體步驟:1、 建立基于MFC的工程:注意在建立工程中,采用單文檔,然后點擊finish【完成】工程建立。2、 創建一個動態分割窗口視圖類,類名自擬。添加如下類函數:(1)BOOL CDynSplit:IsDynamic() return m_bDynSplit;(2)void CDynSplit:OnInvertTracker(const CRect &rect)if(!m_bDynSplit)CSplitterWnd:OnInvertTracker(rect);elsereturn;(3

2、)void CDynSplit:StartTracking(int ht)if(!m_bDynSplit)CSplitterWnd:StartTracking(ht);return;ASSERT_VALID(this);if (ht = noHit)return;/ GetHitRect will restrict 'm_rectLimit' as appropriateGetInsideRect(m_rectLimit);if (ht >= splitterIntersection1 && ht <= splitterIntersection225

3、)/ split two directions (two tracking rectangles)int row = (ht - splitterIntersection1) / 15;int col = (ht - splitterIntersection1) % 15;GetHitRect(row + vSplitterBar1, m_rectTracker);int yTrackOffset = m_ptTrackOffset.y;m_bTracking2 = TRUE;GetHitRect(col + hSplitterBar1, m_rectTracker2);m_ptTrackOf

4、fset.y = yTrackOffset;else if (ht = bothSplitterBox)/ hit on splitter boxes (for keyboard)GetHitRect(vSplitterBox, m_rectTracker);int yTrackOffset = m_ptTrackOffset.y;m_bTracking2 = TRUE;GetHitRect(hSplitterBox, m_rectTracker2);m_ptTrackOffset.y = yTrackOffset;/ center itm_rectTracker.OffsetRect(0,

5、m_rectLimit.Height()/2);m_rectTracker2.OffsetRect(m_rectLimit.Width()/2, 0);else/ only hit one barGetHitRect(ht, m_rectTracker);/ steal focus and captureSetCapture();/ set tracking state and appropriate cursorm_bTracking = TRUE;m_htTrack = ht;SetSplitCursor(ht);(4)void CDynSplit:StopTracking(BOOL bA

6、ccept)ASSERT_VALID(this);if (!m_bTracking)return;ReleaseCapture();/ erase tracker rectangleOnInvertTracker(m_rectTracker);if (m_bTracking2)OnInvertTracker(m_rectTracker2);m_bTracking = m_bTracking2 = FALSE;/ save old active viewCWnd* pOldActiveView = GetActivePane();/ m_rectTracker is set to the new

7、 splitter position (without border)/ (so, adjust relative to where the border will be)m_rectTracker.OffsetRect(-CX_BORDER , -CY_BORDER);m_rectTracker2.OffsetRect(-CX_BORDER, -CY_BORDER);if (bAccept)if (m_htTrack = vSplitterBox)SplitRow(m_rectTracker.top);else if (m_htTrack >= vSplitterBar1 &&

8、amp; m_htTrack <= vSplitterBar15)/ set row heightTrackRowSize(m_rectTracker.top, m_htTrack - vSplitterBar1);RecalcLayout();else if (m_htTrack = hSplitterBox)SplitColumn(m_rectTracker.left);else if (m_htTrack >= hSplitterBar1 && m_htTrack <= hSplitterBar15)/ set column widthTrackColu

9、mnSize(m_rectTracker.left, m_htTrack - hSplitterBar1);RecalcLayout();else if (m_htTrack >= splitterIntersection1 &&m_htTrack <= splitterIntersection225)/ set row height and column widthint row = (m_htTrack - splitterIntersection1) / 15;int col = (m_htTrack - splitterIntersection1) % 15

10、;TrackRowSize(m_rectTracker.top, row);TrackColumnSize(m_rectTracker2.left, col);RecalcLayout();else if (m_htTrack = bothSplitterBox)/ rectTracker is vSplitter (splits rows)/ rectTracker2 is hSplitter (splits cols)SplitRow(m_rectTracker.top);SplitColumn(m_rectTracker2.left);if ( (pOldActiveView = Get

11、ActivePane() && (pOldActiveView != NULL) )SetActivePane(-1, -1, pOldActiveView); / re-activate(5)在該類的頭文件(.h)中添加如下函數:voidSetDynamic(BOOL bDynSplit = TRUE) m_bDynSplit = bDynSplit; (6)為了防止出現錯誤,前面(1)-(4)函數添加采用:第6個函數直接放在該類的源文件(.cpp)文件中:void CDynSplit:OnMouseMove(UINT nFlags, CPoint pt)if(!m_bDyn

12、Split)CSplitterWnd:OnMouseMove(nFlags, pt);return;if (GetCapture() != this)StopTracking(FALSE);if (m_bTracking)/ move tracker to current cursor positionpt.Offset(m_ptTrackOffset); / pt is the upper right of hit detect/ limit the point to the valid split rangeif (pt.y < m_rectLimit.top)pt.y = m_re

13、ctLimit.top;else if (pt.y > m_rectLimit.bottom)pt.y = m_rectLimit.bottom;if (pt.x < m_rectLimit.left)pt.x = m_rectLimit.left;else if (pt.x > m_rectLimit.right)pt.x = m_rectLimit.right;if (m_htTrack = vSplitterBox |m_htTrack >= vSplitterBar1 && m_htTrack <= vSplitterBar15)if (m

14、_rectTracker.top != pt.y)OnInvertTracker(m_rectTracker);m_rectTracker.OffsetRect(0, pt.y - m_rectTracker.top);OnInvertTracker(m_rectTracker);else if (m_htTrack = hSplitterBox |m_htTrack >= hSplitterBar1 && m_htTrack <= hSplitterBar15)if (m_rectTracker.left != pt.x)OnInvertTracker(m_rec

15、tTracker);m_rectTracker.OffsetRect(pt.x - m_rectTracker.left, 0);OnInvertTracker(m_rectTracker);else if (m_htTrack = bothSplitterBox | (m_htTrack >= splitterIntersection1 &&m_htTrack <= splitterIntersection225)if (m_rectTracker.top != pt.y)OnInvertTracker(m_rectTracker);m_rectTracker.O

16、ffsetRect(0, pt.y - m_rectTracker.top);OnInvertTracker(m_rectTracker);if (m_rectTracker2.left != pt.x)OnInvertTracker(m_rectTracker2);m_rectTracker2.OffsetRect(pt.x - m_rectTracker2.left, 0);OnInvertTracker(m_rectTracker2);OnLButtonUp(MK_LBUTTON,pt);OnLButtonDown(MK_LBUTTON,pt);if(m_OldPoint != pt)R

17、edrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);m_OldPoint = pt;else/ simply hit-test and set appropriate cursorint ht = HitTest(pt);SetSplitCursor(ht);在源文件(.cpp)文件中添加如下代碼:BEGIN_MESSAGE_MAP(CDynSplit, CSplitterWnd)/AFX_MSG_MAP(CDynSplit)ON_WM_MOUSEMOVE()/AFX_MSG_MAPEND_MESSAGE_MAP()在頭文件中添加如

18、下代碼:protected:/AFX_MSG(CDynSplit)afx_msg void OnMouseMove(UINT nFlags, CPoint point);/AFX_MSGDECLARE_MESSAGE_MAP()(7)在頭文件中聲明兩個變量和一個枚舉類型:protected:CPoint m_OldPoint;BOOLm_bDynSplit;enum HitTestValuenoHit = 0,vSplitterBox = 1,hSplitterBox = 2,bothSplitterBox = 3, / just for keyboardvSplitterBar1 = 101

19、,vSplitterBar15 = 115,hSplitterBar1 = 201,hSplitterBar15 = 215,splitterIntersection1 = 301,splitterIntersection225 = 525;(8)在源文件中添加預定義:#define CX_BORDER1#define CY_BORDER1#define FAR_POINT_XY-10000(9)在頭文件里面添加:#ifndef _DYN_SPLITTER_H#define _DYN_SPLITTER_H3、 在框架類中操作(1)聲明上面剛剛創建類的一個類對象:protected:CDynSp

20、lit m_wndSplitter;(2)添加一個虛函數,實現代碼如下:在類的頭文件中:virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);在類的源文件中:BOOL CMainFrame:OnCreateClient( LPCREATESTRUCT,CCreateContext* pContext)/ create a splitter with 1 row, 2 columnsif (!m_wndSplitter.CreateStatic(this, 1, 2)TRACE0("Fail

21、ed to Splitter windown");return FALSE;/ add the first splitter pane - the default view in column 0if (!m_wndSplitter.CreateView(0, 0,pContext->m_pNewViewClass, CSize(275, 275), pContext)TRACE0("Failed to create first panen");return FALSE;/ add the second splitter pane - an input vi

22、ew in column 1if (!m_wndSplitter.CreateView(0, 1,RUNTIME_CLASS(CLineView2), CSize(0, 0), pContext)TRACE0("Failed to create second panen");return FALSE;/ activate the input viewSetActiveView(CView*)m_wndSplitter.GetPane(0,1);return TRUE;(3)添加第二個視圖類:這樣運行一下,就可以看到上面兩個視圖窗口了。二、讀BMP文件并顯示在左邊的視圖中。(

23、1)創建一個讀位圖文件的類。在該類的頭文件中添加:#ifndef _CDIB_H#define _CDIB_H在頭文件中聲明下來變量和函數:public: RGBQUAD* m_pRGB; BYTE* m_pData; UINT m_numberOfColors;BOOL m_valid; BITMAPFILEHEADER bitmapFileHeader; BITMAPINFOHEADER* m_pBitmapInfoHeader; BITMAPINFO* m_pBitmapInfo;int byBitCount;DWORD dwWidthBytes;char m_fileName256;

24、char* GetFileName(); BOOL IsValid(); DWORD GetSize(); UINT GetWidth(); UINT GetHeight(); UINT GetNumberOfColors(); RGBQUAD* GetRGB(); BYTE* GetData(); BITMAPINFO* GetInfo();DWORD GetDibWidthBytes();WORD PaletteSize(LPBYTE lpDIB);WORD DIBNumColors(LPBYTE lpDIB); void SaveFile(const CString filename);

25、void LoadFile(const char* dibFileName);具體實現函數如下:void CReadFile:LoadFile(const char* dibFileName)strcpy(m_fileName,dibFileName); CFile dibFile(m_fileName, CFile:modeRead); dibFile.Read(void*)&bitmapFileHeader,sizeof(BITMAPFILEHEADER); if (bitmapFileHeader.bfType = 0x4d42) DWORD fileLength = dibFi

26、le.GetLength(); DWORD size = fileLength -sizeof(BITMAPFILEHEADER); BYTE* pDib = (BYTE*)GlobalAllocPtr(GMEM_MOVEABLE, size); dibFile.Read(void*)pDib, size); dibFile.Close(); m_pBitmapInfo = (BITMAPINFO*) pDib; m_pBitmapInfoHeader = (BITMAPINFOHEADER*) pDib; m_pRGB = (RGBQUAD*)(pDib +m_pBitmapInfoHead

27、er->biSize); int m_numberOfColors = GetNumberOfColors(); if (m_pBitmapInfoHeader->biClrUsed = 0) m_pBitmapInfoHeader->biClrUsed =m_numberOfColors; DWORD colorTableSize = m_numberOfColors * sizeof(RGBQUAD); m_pData = pDib + m_pBitmapInfoHeader->biSize + colorTableSize;if (m_pRGB = (RGBQUA

28、D*)m_pData) / No color tablem_pRGB = NULL; m_pBitmapInfoHeader->biSizeImage = GetSize();m_valid = TRUE; else m_valid = FALSE; AfxMessageBox("This isn't a bitmap file!"); BOOL CReadFile:IsValid() return m_valid; char* CReadFile:GetFileName() return m_fileName; UINT CReadFile:GetWidth

29、() return (UINT) m_pBitmapInfoHeader->biWidth; UINT CReadFile:GetHeight() return (UINT) m_pBitmapInfoHeader->biHeight; DWORD CReadFile:GetSize() if (m_pBitmapInfoHeader->biSizeImage != 0) return m_pBitmapInfoHeader->biSizeImage;else DWORD height = (DWORD) GetHeight(); DWORD width = (DWOR

30、D) GetWidth(); return height * width; UINT CReadFile:GetNumberOfColors()int numberOfColors; if (m_pBitmapInfoHeader->biClrUsed = 0) &&(m_pBitmapInfoHeader->biBitCount < 9)switch (m_pBitmapInfoHeader->biBitCount)case 1: numberOfColors = 2; break;case 4: numberOfColors = 16; break;

31、case 8: numberOfColors = 256; elsenumberOfColors = (int) m_pBitmapInfoHeader->biClrUsed; return numberOfColors;DWORD CReadFile:GetDibWidthBytes() byBitCount=m_pBitmapInfoHeader->biBitCount;LONG nWidth=m_pBitmapInfoHeader->biWidth;dwWidthBytes = (DWORD)m_pBitmapInfoHeader->biWidth;/8-bits

32、if(byBitCount = 1) dwWidthBytes = (nWidth + 7) / 8;else if(byBitCount = 4) dwWidthBytes = (nWidth + 1) / 2;else if(byBitCount = 24) dwWidthBytes = 3 * nWidth ;while(dwWidthBytes & 3) != 0)dwWidthBytes+;return dwWidthBytes; BYTE* CReadFile:GetData() return m_pData;RGBQUAD* CReadFile:GetRGB() retu

33、rn m_pRGB;BITMAPINFO* CReadFile:GetInfo() return m_pBitmapInfo;WORD CReadFile:PaletteSize(LPBYTE lpDIB) return (DIBNumColors(lpDIB) * sizeof(RGBTRIPLE); WORD CReadFile:DIBNumColors(LPBYTE lpDIB) WORD wBitCount; / DIB bit count wBitCount = (LPBITMAPCOREHEADER)lpDIB)->bcBitCount; switch (wBitCount)

34、 case 1: return 2; case 4: return 16; case 8: return 256; default: return 0; void CReadFile:SaveFile(const CString filename) BITMAPFILEHEADER bmfHdr; / Header for Bitmap file LPBITMAPINFOHEADER lpBI; / Pointer to DIB info structure DWORD dwDIBSize; bmfHdr.bfType = 0x4d42; / "BM" lpBI = (LP

35、BITMAPINFOHEADER)m_pBitmapInfoHeader; dwDIBSize = *(LPDWORD)lpBI + PaletteSize(LPBYTE)lpBI); if (lpBI->biCompression = BI_RLE8) | (lpBI->biCompression = BI_RLE4) dwDIBSize += lpBI->biSizeImage; else DWORD dwBmBitsSize; / Size of Bitmap Bits only dwBmBitsSize = WIDTHBYTES(lpBI->biWidth)*(

36、DWORD)lpBI->biBitCount) * lpBI->biHeight; dwDIBSize += dwBmBitsSize; lpBI->biSizeImage = dwBmBitsSize; bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER); bmfHdr.bfReserved1 = 0; bmfHdr.bfReserved2 = 0; bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize + PaletteSize(LPB

37、YTE)lpBI); CFile dibFile(filename, CFile:modeWrite|CFile:modeCreate);dibFile.Write(&bmfHdr, sizeof(BITMAPFILEHEADER);dibFile.WriteHuge(lpBI, dwDIBSize);dibFile.Close();在源文件的上面引用下列庫和定義:#include "windowsx.h"#include "math.h"#define WIDTHBYTES(bits) (bits) + 31) / 32 * 4)(2)打開資源

38、視圖,如下圖:在“文件”菜單下,應用“打開”子菜單。添加“圖像處理”菜單。添加“顯示原圖像”子菜單。回到類視圖,在文檔類里面加入“文件”菜單下“打開”子菜單的消息處理函數:消息處理函數:void CLineDoc:OnFileOpen() / TODO: Add your command handler code hereCFileDialog dlg(TRUE,_T("BMP"),_T("*.BMP"),OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,_T("位圖文件(*.BMP)|*.BMP|"); if

39、(IDOK=dlg.DoModal () filename.Format ("%s",dlg.GetPathName() ); CReadfile.LoadFile(filename); CSobel.LoadFile(filename);statedoc=1;在文檔類的頭文件里面聲明:public: CReadFile CReadfile; CSobelEx CSobel; CString filename; int statedoc;(3)在第一個視圖類里面進行如下操作:打開類魔棒ClassWizard:添加“顯示原圖像”子菜單的消息處理函數:void CLineVie

40、w:OnAppearbmp() / TODO: Add your command handler code hereCLineDoc* pDoc = GetDocument();ASSERT_VALID(pDoc); filename=pDoc->filename;state1=1;Invalidate();在第一個視圖類的頭文件里面聲明:public: CString filename;int state1;修改ondraw繪圖函數:void CLineView:OnDraw(CDC* pDC)if(state1=1)CBitmap m_bitmap;HBITMAP hBitmap=(

41、HBITMAP)LoadImage(NULL,_T(filename),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_DEFAULTSIZE|LR_LOADFROMFILE); m_bitmap.Attach (hBitmap);CDC dcImage;if(!dcImage.CreateCompatibleDC (pDC)return;BITMAP bm;m_bitmap.GetBitmap (&bm); dcImage.SelectObject (&m_bitmap);pDC->BitBlt (0,0,bm.bmWidth ,bm.b

42、mHeight ,&dcImage,0,0,SRCCOPY);在文檔類頭文件里加入:#include "ReadFile.h"#include "SobelEx.h"在第二個視圖類中加入:#include "ReadFile.h"Readfile類頭文件中做如下操作:/#if !defined(AFX_READFILE_H_1B18FDF4_DBBC_4107_8F50_BF47EC94D9BA_INCLUDED_)/#define AFX_READFILE_H_1B18FDF4_DBBC_4107_8F50_BF47EC94

43、D9BA_INCLUDED_/#if _MSC_VER > 1000/#pragma once/#endif / _MSC_VER > 1000創建一個Sobel算法處理類:這個地方基類應為CReadFile在該類頭文件增加#include "ReadFile.h"在該類源文件增加以下三個函數:void CSobelEx:Sobel()int tempH; /模板高度int tempW; /模板寬度float tempC; /模板系數int tempMY; /模板中心元素Y坐標int tempMX; /模板中心元素X坐標float Template9; /模板數

44、組LPBYTE p_data; /原圖數據區指針 int wide,height; /原圖長、寬p_data=this->GetData (); wide=this->GetWidth (); height=this->GetHeight ();if (m_pBitmapInfoHeader->biBitCount<9)/灰度圖像 LPBYTE temp1=new BYTEwide*height; /新圖像緩沖區 LPBYTE temp2=new BYTEwide*height; /新圖像緩沖區 /拷貝原圖像到緩存圖像memcpy( temp1,p_data,wi

45、de*height); memcpy( temp2,p_data,wide*height);/設置Sobel模板參數tempW=3;tempH=3;tempC=1.0;tempMY=1;tempMX=1;Template0=-1.0; Template1=-2.0;Template2=-1.0;Template3=0.0;Template4=0.0;Template5=0.0;Template6=1.0;Template7=2.0;Template8=1.0;/調用Templat()函數Templat( temp1,wide,height,tempH,tempW,tempMX,tempMY,T

46、emplate,tempC); /設置Sobel模板參數 Template0=-1.0; Template1=0.0;Template2=1.0;Template3=-2.0;Template4=0.0;Template5=2.0;Template6=-1.0;Template7=0.0;Template8=1.0;/調用Templat()函數Templat( temp2,wide,height,tempH,tempW,tempMX,tempMY,Template,tempC); /求兩幅緩存圖像的最大值for(int j=0;j<height;j+)for(int i=0;i<w

47、ide;i+)if( temp2j*wide+i> temp1j*wide+i) temp1j*wide+i= temp2j*wide+i; /將緩存中的圖像復制到原圖數據區memcpy(p_data, temp1,wide*height);/刪除緩沖區delete temp1;delete temp2;else/24位彩色 int DibWidth; /原圖長、寬 DibWidth=this->GetDibWidthBytes(); /取得原圖的每行字節數 BYTE *p_temp1=new BYTEheight*DibWidth;BYTE *p_temp2=new BYTEhe

48、ight*DibWidth;/將緩存中的圖像復制到原圖數據區memcpy(p_temp1,p_data,DibWidth*height);memcpy(p_temp2,p_data,DibWidth*height);/設置Sobel模板參數tempW=3;tempH=3;tempC=1.0;tempMY=1;tempMX=1;Template0=-1.0; Template1=-2.0;Template2=-1.0;Template3=0.0;Template4=0.0;Template5=0.0;Template6=1.0;Template7=2.0;Template8=1.0;Templa

49、t24bit( p_temp1,DibWidth,height,tempH,tempW,tempMX,tempMY,Template,tempC); /設置Sobel模板參數 Template0=-1.0; Template1=0.0;Template2=1.0;Template3=-2.0;Template4=0.0;Template5=2.0;Template6=-1.0;Template7=0.0;Template8=1.0;Templat24bit( p_temp2,DibWidth,height,tempH,tempW,tempMX,tempMY,Template,tempC); /

50、求兩幅緩存圖像的最大值for(int j=0;j<height;j+)for(int i=0;i<wide;i+)if( p_temp2j*DibWidth+i> p_temp1j*DibWidth+i) p_temp1j*DibWidth+i= p_temp2j*DibWidth+i; memcpy(p_data,p_temp1,height*DibWidth); / 復制處理后的圖像 delete p_temp1; /刪除暫時分配內存 delete p_temp2; /刪除暫時分配內存void CSobelEx:Templat(BYTE *m_pdata, int wide, int height, int tempH, int tempW, int t

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論