




已阅读5页,还剩3页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Visual C+6.0开发灰度位图处理9/10/2001 9:41:14 刘涛 蒋建国yesky图像处理技术已经类生活的各个领域并得到越来越多的应用,图像处理所涉及的图像格式有很多种,如TIF、JEMP、BMP等等,工程应用中经常要处理256级的灰度BMP图像,如通过黑白采集卡采集得到的图像。BMP灰度图像作为Windows环境下主要的图像格式之一,以其格式简单,适应性强而倍受欢迎。在进行图像处理时,操作图像中的像素值就要得到图像阵列;经过处理后的图像的像素值存储起来;显示图像时要正确实现调色板,结合这些问题,文章针对性的给出了操作灰度BMP图像时的部分函数实现代码及注释。一、 BMP位图操作BMP位图包括位图文件头结构BITMAPFILEHEADER、位图信息头结构BITMAPINFOHEADER、位图颜色表RGBQUAD和位图像素数据四部分。处理位图时要根据文件的这些结构得到位图文件大小、位图的宽、高、实现调色板、得到位图像素值等等。对于256级灰度图像每个像素用8bit表示颜色的索引值,这里要注意的一点是在BMP位图中,位图的每行像素值要填充到一个四字节边界,即位图每行所占的存储长度为四字节的倍数,不足时将多余位用0填充。在处理图像应用程序的文档类(CdibDoc.h)中声明如下宏及公有变量:#define WIDTHBYTES(bits) (bits) + 31) / 32 * 4)/计算图像每行象素所占的字节数目HANDLE m_hDIB;/存放位图数据的句柄CPalette* m_palDIB;/指向调色板Cpalette类的指针CSize m_sizeDoc; file:/初始化视图的尺寸1、 读取灰度BMP位图根据BMP位图文件的结构,操作BMP位图文件读入数据,重载了文挡类的OnOpenDocument函数如下:BOOL CDibDoc:OnOpenDocument(LPCTSTR lpszPathName)CFile file;CFileException fe;if (!file.Open(lpszPathName, CFile:modeRead | CFile:shareDenyWrite, &fe)AfxMessageBox(文件打不开);return FALSE;/打开文件DeleteContents();/删除文挡BeginWaitCursor();BITMAPFILEHEADER bmfHeader;/定义位图文件头结构DWORD dwBitsSize;HANDLE hDIB;LPSTR pDIB;BITMAPINFOHEADER *bmhdr;/指向位图信息头结构的指针dwBitsSize = file.GetLength();/得到文件长度if (file.Read(LPSTR)&bmfHeader, sizeof(bmfHeader) !=sizeof(bmfHeader)return FALSE;if (bmfHeader.bfType != 0x4d42) file:/检查是否为BMP文件return FALSE;hDIB=(HANDLE) :GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);file:/申请缓冲区if (hDIB = 0)return FALSE;pDIB = (LPSTR) :GlobalLock(HGLOBAL)hDIB); file:/得到申请的缓冲区的指针if (file.ReadHuge(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER) !=dwBitsSize - sizeof(BITMAPFILEHEADER) ):GlobalUnlock(HGLOBAL)hDIB);hDIB=NULL;return FALSE;/读数据,包括位图信息、位图颜色表、图像像素的灰度值bmhdr=(BITMAPINFOHEADER*)pDIB;/为指向位图信息头结构的指针付值:GlobalUnlock(HGLOBAL)hDIB);if (*bmhdr).biBitCount!=8) file:/验证是否为8bit位图return FALSE;m_hDIB=hDIB;InitDIBData(); file:/自定义函数,根据读入的数据得到位图的宽、高、颜色表file:/ 来得到初始化视的尺寸、生成调色板EndWaitCursor();SetPathName(lpszPathName);/设置存储路径SetModifiedFlag(FALSE); / 设置文件修改标志为FALSEreturn TRUE;2、 灰度位图数据的存储为了将图像处理后所得到的像素值保存起来,重载了文档类的OnSaveDocument函数,其具体实现如下:BOOL CDibDoc:OnSaveDocument(LPCTSTR lpszPathName)CFile file;CFileException fe;BITMAPFILEHEADER bmfHdr; / 位图文件头结构LPBITMAPINFOHEADER lpBI; file:/指向位图信息结构的指针DWORD dwDIBSize;if (!file.Open(lpszPathName, CFile:modeCreate |CFile:modeReadWrite | CFile:shareExclusive, &fe)AfxMessageBox(文件打不开);/打开文件BOOL bSuccess = FALSE;BeginWaitCursor();lpBI = (LPBITMAPINFOHEADER) :GlobalLock(HGLOBAL) m_hDIB);if (lpBI = NULL)return FALSE;dwDIBSize = *(LPDWORD)lpBI + 256*sizeof(RGBQUAD); / Partial CalculationDWORD dwBmBitsSize;/BMP文件信息结构所占的字节数dwBmBitsSize=WIDTHBYTES(lpBI-biWidth)*(DWORD)lpBI-biBitCount) *lpBI-biHeight;/ 存储时位图所有像素所占的总字节数dwDIBSize += dwBmBitsSize; lpBI-biSizeImage = dwBmBitsSize; / 位图所有像素所占的总字节数file:/以下五句为文件头结构填充值bmfHdr.bfType =0x4d42; / 文件为BMP类型bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);/文件总长度bmfHdr.bfReserved1 = 0;bmfHdr.bfReserved2 = 0;bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI-biSize+ 256*sizeof(RGBQUAD);file:/位图数据距问件头的偏移量file.Write(LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER);/写文件头file.WriteHuge(lpBI, dwDIBSize);file:/将位图信息(信息头结构、颜色表、像素数据)写入文件:GlobalUnlock(HGLOBAL) m_hDIB);EndWaitCursor();SetModifiedFlag(FALSE); / back to unmodifiedreturn TRUE;二、 调色板的操作灰度图像要正确显示,必须实现逻辑调色板和系统调色板 ,通过在主框架类中处理Windows定义的消息WM_QUERYNEWPALETTE 、WM_PALETTECHANGED及视图类中处理自定义消息WM_DOREALIZE(该消息在主框架窗口定义如下:#define WM_REALIZEPAL (WM_USER+100))来实现调色板的操作。void CMainFrame:OnPaletteChanged(CWnd* pFocusWnd) file:/总实现活动视的调色板CMDIFrameWnd:OnPaletteChanged(pFocusWnd);CMDIChildWnd* pMDIChildWnd = MDIGetActive();if (pMDIChildWnd = NULL)returnCView* pView = pMDIChildWnd-GetActiveView();ASSERT(pView != NULL);SendMessageToDescendants(WM_DOREALIZE, (WPARAM)pView-m_hWnd);file:/通知所有子窗口系统调色板已改变BOOL CMainFrame:OnQueryNewPalette()/提供实现系统调色板的机会/ 实现活动视的调色板CMDIChildWnd* pMDIChildWnd = MDIGetActive();if (pMDIChildWnd = NULL)return FALSE; / no active MDI child frame (no new palette)CView* pView = pMDIChildWnd-GetActiveView();ASSERT(pView != NULL);file:/通知活动视图实现系统调色板pView-SendMessage(WM_DOREALIZE, (WPARAM)pView-m_hWnd);return TRUE;LRESULT CDibView:OnDoRealize(WPARAM wParam, LPARAM)/实现系统调色板ASSERT(wParam != NULL);CDibDoc* pDoc = GetDocument();if (pDoc-m_hDIB = NULL)return 0L; / must be a new documentCPalette* pPal = pDoc-m_palDIB;file:/调色板的颜色表数据在InitDIBData()函数中实现if (pPal != NULL)CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()-m_pMainWnd;ASSERT_KINDOF(CMainFrame, pAppFrame);CClientDC appDC(pAppFrame);CPalette* oldPalette = appDC.SelectPalette(pPal, (HWND)wParam) != m_hWnd);file:/只有活动视才可以设为FALSE,/ 即根据活动视的调色板设为前景调色板 if (oldPalette != NULL)UINT nColorsChanged = appDC.RealizePalette();/实现系统调色板if (nColorsChanged 0)pDoc-UpdateAllViews(NULL);/更新视图appDC.SelectPalette(oldPalette, TRUE);file:/将原系统调色板置为逻辑调色板elseTRACE0(tSelectPalette failed in CDibView:OnPaletteChangedn);注:在调用API函数显示位图时,不要忘记设置逻辑调色板,即背景调色板,否则位图将无法正确显示三、图像的数字化处理通过以上读文件的操作,已经得到图像数据,由于得到的数据包括多余信息,所以在进行数字图像处理时要进一步删除多余信息,只对位图的像素进行操作,以基于模板的高通滤波为例来讲述数字图像处理的实现 :void CDibView:OnMENUHighPass() HANDLE data1handle;LPBITMAPINFOHEADER lpBi;CDibDoc *pDoc=GetDocument();HDIB hdib; unsigned char *hData; unsigned char *data;hdib=pDoc-GetHDIB();BeginWaitCursor();lpBi=(LPBITMAPINFOHEADER)GlobalLock(HGLOBAL)hdib);hData=(unsigned char*)FindDIBBits(LPSTR)lpBi);pDoc-SetModifiedFlag(TRUE);data1handle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lpBi-biWidth*8)*lpBi-biHeight);data=(unsigned char*)GlobalLock(HGLOBAL)data1handle);AfxGetApp()-BeginWaitCursor();int i,j,s,t,ms=1;int sum=0,sumw=0;int mask33=-1,-1,-1,-1,9,-1,-1,-1,-1;for(i=0; ibiHeight; i+)for(j=0; jbiWidth; j+) sumw=0; sum=0;for(s=(-ms); s=ms; s+)for(t=(-ms); t=0) & (j+t)=0) & (i+s)biHeight) & (j+t)biWidth)sumw += mask1+s1+t;sum+=*(hData+(i+s)*WIDTHBYTES(lpBi-biWidth*8)+(j+t)*mask1+s1+t;if(sumw=0) sumw=1; sum/=sumw;if(sum255)sum=255;if(sumbiWidth*8)+j)=sum;for( j=0; jbiHeight; j+)for( i=0; ibiWidth; i+)*(hData+i*WIDTHBYTES(lpBi-biWidth*8)+j)=*(data+i*WIDTHBYTES(lpBi-biWidth*8)+j); AfxGetApp()-EndWaitCursor();GlobalUnlock(HGLOBAL)hdib);GlobalUnlock(data1handle);EndWaitCursor();Invalidate(TRUE);四、图像的基本操作处理1、图像平移图像平移只是改变图像在屏幕上的位置,图像本身并不发生变化。假设原图像区域左上角坐标为(x0, y0),右下角坐标为(x1, y1),将图像分别沿x和y轴平移dx和dy,则新图像的左上角坐标为(x0+dx, y0+dy),右下角坐标为(x1+dx, y1+dy)。坐标平移变换公式为:x1 = x + dxy1 = y + dy在屏幕上实现图像的移动分为四个步骤: 读原图像到缓冲区; 擦除视图上原图像; 计算平移后的新坐标。 利用API函数:StretchDIBits()在新的左上角坐标位置处重新显示原图像。其中,擦除原图像的方法与图形变换中擦除原图形的方法一致,在实现中仍采用XOR异或方式画图擦除原图像。对于新坐标值的计算还需要考虑边界情况,不要在图像平移后超出允许的屏幕范围。2、图像颠倒图像颠倒是指把定义好的图像区域上下翻转地显示在屏幕上。分析图像颠倒的过程,可发现每行的图像信息都保持不变,而只是改变了行的顺序,将第一行与最后的第n行相互交换,第二行与第n 1行交换,依此类推,从而实现了图像的颠倒。只需采用按行交换的方式,即可方便地修改缓冲区内容,实现图像的颠倒。基本步骤如下:(1)将原图像读入缓冲区,并擦除原图像;(2) 计算图像的高度,即行数height;计算图像宽度width;根据宽度、高度生成新缓冲区;(3)把第一行与最末行交换,第2行与第n1行交换,依此类推,直至全部交换完毕。既原图中的(x、y)点,在新生成的图象中对应为x1=x,y1=height-1-y。把原图中的象素值读入新缓冲区的(x1,y1)点处。(4)把交换后的图像缓冲区内容重新显示在屏幕上。3、图像镜像变换镜像变换是指将指定区域的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年非公路矿用自卸车行业研究报告及未来行业发展趋势预测
- 政治课第一单元第二课第二框教学课件
- 内部沟通工具
- 兖州电焊安全培训中心课件
- 中国邮政2025宜宾市秋招个人客户经理岗位高频笔试题库含答案
- 汽修基础电路培训课件
- 中国邮政2025甘肃省秋招系统维护岗位高频笔试题库含答案
- 2025年保鲜展示柜行业研究报告及未来行业发展趋势预测
- 如何在工作职责中找到自己的定位
- 中国邮政2025吕梁市秋招平台产品经理岗位高频笔试题库含答案
- 第一单元 第2课《童真时光》 【人教版】美术 三年级上册
- 广州市公安局天河分局招聘辅警考试真题2024
- 2025年全国货运驾驶员职业技能资格考试试题(基础知识)含答案
- GB/T 46150.2-2025锅炉和压力容器第2部分:GB/T 46150.1的符合性检查程序要求
- 2025年甘肃省高考历史真题卷含答案解析
- 中华优传统文化(慕课版)教案
- 2025广东广州市国资委选调公务员2人笔试模拟试题及答案解析
- 美容美发店2025年营销方案创新解析
- 档案知识培训课件
- 肱骨髁上骨折
- 2025年中药师证考试真题及答案
评论
0/150
提交评论