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

提交评论