VC++图形图像处理代码

合集下载

VC++图形图像处理源代码

VC++图形图像处理源代码

delete pData; pData=NULL;
if(m_pBMI!=NULL) delete m_pBMI; m_pBMI=NULL; if(pfi!=NULL)
delete pfi; pfi=NULL; } CAvi::CAviCreate(CString &string)//读文件初始化该类 { HRESULT hr; pfi=new AVIFILEINFO; hr = AVIFileOpen(&pfile, // returned file pointer string, // file name OF_READ, // mode to open file with NULL); hr= AVIFileInfo(pfile, file://获取 AVI 信息,放入 pfi 中 pfi, sizeof(AVIFILEINFO) ); cx=pfi­>dwWidth;//图象宽、高 cy=pfi­>dwHeight; hr=AVIFileGetStream(//将 AVI 变成视频流 pfile, &pavi, streamtypeVIDEO, 0//LONG lParam ); m_pBMI=new BITMAPINFO;//定义 BMP 信息头 m_pBMI­>bmiHeader.biBitCount=24; m_pBMI­>bmiHeader.biClrImportant=0; m_pBMI­>bmiHeader.biClrUsed=0; m_pBMI­>bmiHeader.biCompression=BI_RGB; m_pBMI­>bmiHeader.biHeight=cy; m_pBMI­>bmiHeader.biWidth=cx; m_pBMI­>bmiHeader.biPlanes=1; m_pBMI­>bmiHeader.biSize=sizeof(BITMAPINFOHEADER); m_pBMI­>bmiHeader.biXPelsPerMeter=0; m_pBMI­>bmiHeader.biYPelsPerMeter=0; m_pBMI­>bmiHeader.biSizeImage=cx*cy*3; pData=(BYTE*)new char[cx*cy*3];//根据 AVI 中 BMP 图象的信息定义缓冲区 } BOOL CAvi::AviRead(int mFrame)//将 AVI 文件的 M 帧数据读入 PData 缓冲区 { HRESULT hr; hr= AVIStreamRead( pavi, mFrame, 1, pData, cx*cy*3,

用VC编程实现BMP图像裁切

用VC编程实现BMP图像裁切

5.5 用VC编程实现BMP图像裁切随着计算电子技术和计算机技术的发展,数字图像处理进入高速发展时期,许多成熟的图像处理软件如雨后春笋般层出不穷。

在大多数图像处理软件中都有图像裁切功能,用它能够快速提取感兴趣区域,去掉多余的图像内容。

那么怎样编程实现图像裁切呢,下面以BMP图像为例介绍一下如何用VC实现图像裁切。

先介绍第一种方法,将图像数据全部读入内存,然后将感兴趣区域裁切下来。

在许多数字图像处理的书中都有关于BMP图像存储结构的章节,这里就不再详细介绍了。

BMP文件一般分为四个部分:位图头文件、位图信息头、调色板和图像数据。

图像裁切要用到位图信息头中的几个参数值:biWidth(图像宽度)、biHeight(图像高度)、biBitCount(每个像素的位数)、biSizeImage(图像长度)。

图像裁切首先要确定裁切区域内每个像素在整幅图像中的位置,我们以裁切区域中心点像素位置起算,要注意的是图像数据的存储是从最下面一行的左边开始的。

如下图,Height是图像高,Width是图像宽,ctPoint是裁切区域中心点坐标,dwX和dwY分别是裁切区域的宽和高。

以256色图像为例(每个像素占一个字节),裁切区域左下角像素(也就是裁切后图像的第一个像素)位置为(Height-ctPoint.y-dwY/2-1)×Width+ctPoint.x-dwX/2,左下角像素位置确定了,裁切区域内的其他像素位置就很容易确定。

确定了裁切区域内每个像素的位置后,就可以把这些像素的值赋给裁切后图像的相应像素。

裁切后图像的位图信息头和调色板只要从原图像数据中拷贝就可以了,修改信息头中图像宽、高和长度值为裁切后的值。

按照上面的思路笔者用VC++ 6.0编写了一个图像裁切函数ClipDIB(),该函数首先计算裁切区域图像数据的大小,为裁切后的图像分配内存,然后将原图像的信息头、调色板拷贝给裁切后的图像,最后将原图像中裁切区域内的像素值赋给裁切后影像。

在VC++6.0中将JPG格式图片转换成BMP格式

在VC++6.0中将JPG格式图片转换成BMP格式

在VC++6.0中将JPG格式图片转换成BMP格式思路:利用GDI+来完成难点:(1)配置GDI开发环境,添加配置代码(2)在当文档程序中添加转换代码注意:本文档由ybdesire参考网上资料撰写完成,代码已经做过测试,可直接复制张贴实现过程:一、配置GDI开发环境(1)下载GDI+ SDK for Visual C++ 6.0/code/legacy/gdi/GDIPlus.zip下载的GDIPlus文件夹中有Includes,Lib文件夹和gdiplus.dll文件。

将Includes和Lib中的文件分别拷到VC6安装目录中的VC98\include和lib文件夹中;新建MFC项目后,才使用gdiplus.dll,到时候将它拷到对应工程的debug 文件夹下。

(2)新建MFC单文档应用程序show:1、在StdAfx.h 中添加如下代码#include <afxdtctl.h>#define ULONG_PTR ULONG#include <gdiplus.h>using namespace Gdiplus;#pragma comment(lib, "gdiplus.lib")2、如(1)中所说,将gdiplus.dll拷贝到本工程的Debug或Release目录下3、在show.h中的class CShowApp : public CWinApp中添加private:GdiplusStartupInput m_gdiplusStartupInput;ULONG_PTR m_pGdiToken;4、在show.cpp中的BOOL CShowApp::InitInstance()中添加GdiplusStartup(&m_pGdiToken,&m_gdiplusStartupInput,NULL);5、为CShow App添加名字为ExitInstance的虚函数的,并在ExitInstance中添加如下退出GDI+的代码GdiplusShutdown(m_pGdiToken);return CWinApp::ExitInstance();(3)测试GDI+是否配置成功void CShowView::OnDraw(CDC* pDC){CShowDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);Graphics graphics(pDC->m_hDC);Pen pen(Color(255, 0, 255));graphics.DrawLine(&pen, 0, 0, 200, 100);}若能成功运行,表明GDI+配置成功二、添加转换代码,实现将打开的JPG格式文件保存成BMP格式文件(1)在CSshowView中添加如下成员变量CString strOpenFileName;(2)在CSshowView中添加如下成员函数1、在CSshowView中添加ToWChar函数WCHAR* CShowView::ToWChar(char *str){//在GDI+中,有关字符的参数类型全部都是WCHAR类型的//该函数是将传统字符串进行转换static WCHAR buffer[1024];wcsset(buffer,0);MultiByteToWideChar(CP_ACP,0,str,strlen(str),buffer,1024);return buffer;}2、在CSshowView中添加GetImageCLSID函数int CShowView::GetImageCLSID(const WCHAR *format, CLSID *pCLSID) {UINT num=0;UINT size=0;ImageCodecInfo* pImageCodecInfo=NULL;GetImageEncodersSize(&num,&size);if(size==0)return FALSE; // 编码信息不可用// 分配内存pImageCodecInfo=(ImageCodecInfo*)(malloc(size));if(pImageCodecInfo==NULL)return FALSE; // 分配失败// 获得系统中可用的编码方式的所有信息GetImageEncoders(num,size,pImageCodecInfo);// 在可用编码信息中查找 format 格式是否被支持for(UINT i=0;i<num;++i){//MimeType: 编码方式的具体描述if (wcscmp(pImageCodecInfo[ i] .MimeType,format)==0){*pCLSID=pImageCodecInfo[i].Clsid;free(pImageCodecInfo);return TRUE;}}free(pImageCodecInfo);return FALSE;}3、在MFC ClassWixard中重载OnFileOpen()void CShowView::OnFileOpen(){static char szFilter[ ]="常见图像格式文件(*.*)|*.*|";CFileDialogdlgChoseImage(1,NULL,NULL,NULL,szFilter);if(dlgChoseImage.DoModal() ==IDOK){strOpenFileName=dlgChoseImage.GetPathName();// 打开文件后立即在窗口中显示 (重绘客户窗口)this->Invalidate() ;}}4、在MFC ClassWixard中重载OnFileSave()void CShowView::OnFileSave(){if( strOpenFileName.IsEmpty() ){AfxMessageBox("当前没有打开图像文件, 不能进行保存!");return;}// 建立图形对象Graphics graphics(GetDC()->m_hDC);// 装入当前已经打开的图像文件Imageimage(ToWChar(strOpenFileName.GetBuffer(strOpenFileName.GetLength() ) ));CString strFileSave;// 将其他格式的图像全部另存为 BMP 文件static char szFilter[ ]= "位图(*.BMP)|*.BMP|";CFileDialogdlgChoseImage(0,"BMP",strOpenFileName,NULL,szFilter);if(dlgChoseImage.DoModal() ==IDOK){strFileSave=dlgChoseImage.GetPathName();CLSID clsid;if(GetImageCLSID(L"image/bmp", &clsid)){image.Save(ToWChar(strFileSave.GetBuffer(strFileSave.GetLength() )), &clsid, NULL);// 将保存后的图像进行显示strOpenFileName=strFileSave;this->Invalidate() ;}}}参考资料[1]/poonjun/archive/2009/01/04/3701724.aspx[2]/DavidHu/articles/1191635.html[3]/bbsgcon.php?board=VisualC&num=785[4]《图像格式转换在数字仪表识别系统中的应用》刘娜, 汪仁煌, 庞然/*-------------------------------------------------------------*/扩展知识阅读[3] 色彩鲜艳漂亮的高品质图像,一个个形象的Windows图标,高速运动、活灵活现的三维动画,这些生动的图形无一不显示着程序设计者的艺术才华。

vc2008 坐标图以及各种画图实例资料

vc2008 坐标图以及各种画图实例资料

绘制图像本章要求掌握用GDI+绘制直线、圆、长方形等图形,在第七章的基础上编写一个类似于“画图”图像图形处理程序8.1 绘图所用到的常用控件及类绘图用到的PictureBox,Image, Bitmap, OpenFileDialog,SaveFileDialog等控件或类在前一章已经进行了讲解。

现对所用的其它控件或类进行说明。

8.1.1 颜色在绘制图形时需要指定使用的颜色,在GDI+中,颜色用System.Drawing.Color 结构来表示的。

1 红绿蓝(RGB)值监视器可以显示的颜色总数非常大——超过160万。

其确切的数字是2的24次方,即16 777 216。

显然,我们需要对这些颜色进行索引,才能指定在给定的某个像素上要显示什么颜色。

给颜色进行索引的最常见方式是把它们分为红绿蓝成分,每种成份的光分为256种不同的强度,其值在0~255之间。

2 设置颜色的方法●可以调用静态函数Color.FromArgb()指定该颜色的红绿蓝值。

其格式为public static Color FromArgb (int red,int green,int blue)例如:Color red = Color.FromArgb(255, 0, 0);Color green = Color.FromArgb(0, 255, 0);Color blue = Color.FromArgb(0, 0, 255);●获取系统定义的颜色使用FromArgb()构造颜色是一种非常灵活的技巧,因为它表示我们可以指定人眼能辨识出的任何颜色。

但是,如果要得到一种简单、标准、众所周知的纯色,例如红色或蓝色,命名想要的颜色是比较简单的。

因此Microsoft还在Color中提供了许多静态属性,每个属性都返回一种命名的颜色。

在下面的示例中,把窗口的背景色设置为白色时,就使用了其中一种属性:this.BackColor = Color.White;// 与以下语句效果一样// this.BackColor = Color.FromArgb(255, 255 , 255);8.1.2 画笔和钢笔本节介绍Pen和Brush,在绘制图形时需要使用它们。

VC图像处理——指纹的识别

VC图像处理——指纹的识别
()显示图像 3 由于要显示的 B P M 格式图像是与设备无关的图像 ,必须 通过编程来实现对于每个像素的显示。M C中 Ve 类的 o - F iw n D w函数负责具体绘制客户区的工作,利用 o D 函数来实 a r nr w a 现此功能。程序流程: 首先要利用 G D u et tc n e o m 获取文档类中
择或输入来确定打开的文件路径。
9 指纹图像细化模块:把二值化的指纹图像细化, . 使脊
线的宽度达到单像素。
2 内存中保存 H B . I D 对象: 管理内存中的 H B I D 对象, 包
数据流图如图 1 所示。
括把从文件打开模块得到的图像数据存人 H B I D 对象, 处理图 像的长宽等其他模块需要的 H B I D 对象的属性,以及保证别的
M a B众 目 支 5色 图 运 s e e g O 犷 前只 持之 位 的 算 6
一} ‘ 系统提示’。M J O NO M IN MB K BC N F R A O I T
_/ 锁 除 定 /解
2 /返回
「U 二 t n e r

) :GO白 l k G O A D C G t 以B 几 n c日日 七 B L p O > eH (} I ! O bU )
实 j 用第一 智慧密集
二 留幽.困 围田目.国 圈,.团… … 团… 田目曰二 圈固.圈 胭.国.圈 别二 回困圈国.圈 .困田.衍 皿困 二 田.… 圈.田‘二 沪

曰B 心 ( I ” e tP) H hl B D 2 /设夏脏标记 _ -
_ _ _一 -
户口 、 to fd抽 ( 〔 口心 沼诊 d 治 奋9拍口 ) M i
单击事件, 处理函 数是oleqaz( nna e) n t u i ) Eh c(函数。 n E l e 和o n

在VC_中使用Kodak图像编辑控件

在VC_中使用Kodak图像编辑控件

收稿日期:2000 09 19作者简介:丁有和,1969 ,硕士,南京师范大学电气与电子工程学院讲师,主要研究方向为CAD/CA M.在VC ++中使用Kodak 图像编辑控件丁有和(南京师范大学电气与电子工程学院,南京,210042)[摘要] 重点讨论Kodak 图像编辑控件在VC++中的使用方法及其功能的实现.[关键词] VC ++;图像控件;Kodak;ActiveX 控件[中图分类号]TP317.4; [文献标识码]B; [文章编号]1008 1925(2001)03 0063 03众所周知,Visual C++[1]的静态Picture 控制功能是比较弱的,它只能显示出在资源中的图标、位图、光标以及图元文件的内容,而不像VB 在Image 控件可以显示出绝大多数的外部图像文件(B MP 、GIF 、JPEG 等).因此,想要在VC++对话框或其他窗口中显示外部图像文件则只能借助于第三方提供的控件.Kodak 图像控件组就是一组非常专业、适用并随Windows 98一起安装,由Eastman Software 公司提供给Microsoft 的32位ActiveX 控件.该控件组包括Kodak 图像编辑、管理、批注、扫描及缩略图控件,它们能处理AWD(传真文档,仅用于Windows 98)、B MP 、DCX 、JPG 、PCX 、TIFF 、XIF 、GI F 、WIFF 等类型的图像文件,并提供了批注、裁剪、缩放、滚动、剪贴板操作以及许多常用图像文件管理功能.文献[2]中虽对Kodak 缩略图控件作了一些论述,但这里着重讨论Kodak 图像编辑控件在VC++中的使用方法及其功能的实现.1 一般使用方法Kodak 图像编辑控件兼有图像处理和批注的功能.在Visual C++中插入图像编辑控件的操作方法和其它普通的Ac tiveX 控件一样,一般都遵循下面的过程(以基于对话框程序为例):创建一个基于对话框的项目ImgDemo.选择 Project Add To Pojec t Components and C ontrols 菜单,弹出 Components and C ontrols 对话框.在此对话框中选择 Registered ActiveX Controls ,将 Kodak 图像编辑控件 组件相关的 类 插入.打开IDD_I MGDEMO_DIALOG 对话框资源模板,并添加 Kodak 图像编辑控件 ,保留其缺省的ID 号.删除 取消 按钮,将 确定 按钮的标题改为 退出 ,再添加 打开 按钮(ID_I MAGE _OPEN).用ClassWizard 为Kodak 图像编辑控件添加成员变量m_ImgEdit,为 打开 按钮增加B N_CLIC KED 消息处理,并添加下列代码:第1卷第3期2001年南京师大学报(工程技术版)JOURNAL OF NANJING NORMAL UNIVERSITY(E NGINEERING AND TEC HNOLOGY)Vol.1No.32001void CImgDemoDlg::OnImgOpen(){CFileDialog dlg(TRUE);dlg.m_ofn.lpstrFilter= 所有图像\0*.bmp;*.gif;*.jpg;*.pcx;*.tif \0\所有文件(*.*)\0*.*\0\0 ;if(dlg.DoModal()==IDOK){m_ImgEdit.SetImage(dlg.GetPathNa me()); //设置控件相关联的图像m_ImgEdit.SetPage(1);//设置图像显示页面m_ImgEdit.Display();//显示图像}}运行并测试,结果如图1所示.图2 页面属性 图对话框1 例ImgDemo 运行结果2 图像处理Kodak 图像编辑控件能对显示的图像进行复制和粘贴、旋转和倒置、缩放和滚动等操作,其相关的操作函数(方法)如表1所示.表1 Kodak 图像编辑控件的常用图像操作操作函数功能描述复制和粘贴ClipboardCopyClipboardCutClipboardPas teCompletePas te将用户选择的图像区域内容和批注复制到剪贴板中将用户选择的图像区域内容和批注剪切到剪贴板中将剪贴板中的数据粘贴到指定位置处将剪贴板中的数据完全粘贴到控件所在的全部区域旋转和倒置RotateLeftRotateRightFlip向左旋转图像向右旋转图像倒置图像缩放和滚动Fi tToZoom ToSelecti onSetZoomScrollImage 改变图像在控件窗口显示的比例将选定的区域放大至整个控件窗口设置从2到6554的显示比例百分数滚动图像需要说明的是,在表1操作函数中,有许多参数是VARIANT 数据类型.该类型广泛用于ActiveX 中,使用时要注意设置VARI ANT 变量的具体类型.例如:南京师大学报(工程技术版)第1卷第3期(2001年)VARIAN T vb;vb.vt=VT_BOO L; //设置具体的数值类型为BO OLvb.boolVal=TRUE;m_ImgEdi t.Fit To(1,vb);但对于VARI ANT 的字符串型变量来说,一般不能直接对其赋值,这时可以用MFC 的COLeVariant 进行转换,例如:COlE Vari ant vb( MyString ); //直接构造除了使用上述操作函数外,用户还可用VC++的ClassWizard 映射控件相关的消息(事件)来执行自己的代码.例如若映射控件的SelectionRectDrawn 消息,并添加下列代码:void CImgDemoDl g::OnSelectionRectDrawnEdi tctrl1(long Left,long Top,long Wi dth,long Height){m_ImgEdi t.Z oomToSelec tion();m_ImgEdi t.DeleteSelectedAnnotations(); //取消用户选定的区域}则当用户的在控件窗口中用鼠标划定某个区域后,将自动调用ZoomToSelec tion 函数来放大显示图像.当然,用户也可调用Sho wPageProperties 函数显示 页面属性 对话框,用来设置当前显示页图像的调色板、压缩方式以及显示分辨率和大小,如图2所示.3 图像批注图像批注是Kodak 图像编辑控件的非常引人注目的一大特色,它能让用户从图3所示的 批注工具箱 中选择一个工具在图像中进行批注.图4 橡皮戳 图属性对话框3 批注工具箱 具体批注时一般可采用下列步骤:首先调用AddAnnotationGroup 函数添加一个新的批注层.然后再调用SelectAnnotationGroup 将刚才添加的新批注层设为当前批注层.调用SelectTool 函数选择一个批注工具,这时用户就可在显示的图像中进行批注了.调用BurnInAnnotations 将当前批注作永久保留,或调用Hide AnnotationGroup 等函数对指定批注层进行隐藏等操作.需要说明的是:当用户选择 文件中的文本 工具进行批注时,它还将弹出 选择文本文件 对话框让用户指定某个文本文件.在决定使用 橡皮戳 批注工具前,用户必须调用SetRubberStampItem 函数设置橡皮戳菜丁有和:在VC++中使用Kodak 图像编辑控件南京师大学报(工程技术版)第1卷第3期(2001年)单中某个菜单项(具体的菜单项可通过GetRubberStampMenuIte ms获得)方能进行橡皮戳批注.若嫌此过程比较复杂且不够直观,用户也可直接调用ShowRubberStampDialog函数来显示如图4的对话框,当用户选择其中的橡皮戳选项,并按 确定 按钮后,就可用此橡皮戳进行批注了.至此,用户可根据以上论述方便地在VC++中使用Kodak图像编辑控件了.[参考文献][1] 丁有和.Visual C++程序员基础教程[M].山东:青岛出版社,1999[2] 丁有和.Visual C++图形图像编程技巧[M].山东:青岛出版社,2000Application of Kodak Image Edit Control to Visual C++D ing Youhe(College of Elec tronic and Electrical Engineeri ng,Nanjing Normal Universi ty,Nanjing,210042,PRC)Abstract:This paper discusses the application of the Kodak image edit control to Visual C++and functional i mplementation.Key words:VC++,i mage controls,Kodak,activeX controls(责任编辑:严海琳)(上接第62页)[2] Bellcore.GR-30-CORE[Z].Issue1.December.1994[3] GB15279-94.自动电话机技术条件[S]A kind of110Reporting-to-police System Based onCity Telephone Subscriber LineSun qichang,Shi Bing,Liu Guojin(Center for Analysi s and Measurement,Nanjing Normal Univers ity,Nanji ng,210097,PRC)Abstract:The Content of thi s article is about a desi gn scheme of a110rep orting-to-police system based on ci ty telephone subscriber Line.By using the service work that the telecommunication bureau provides caller information to subscriber (inserts caller nu mber and other relevan t information between the first and the second ringing of the subscriber terminal), this scheme sets up a platform using binary frequency shi ft keying(FSK)decode technique on the subscriber side,receives the caller(reporting side)telephone number,then through the data base in the service equip ment,finds the caller (reporting side)material and information,and chooses the corresponding police action plan.Key words:caller number,binary frequency shi ft keying(FSK),110reporting-to-police system(责任编辑:严海琳)。

VC++在数字图像处理中的应用

VC++在数字图像处理中的应用

VC++在数字图像处理中的应用赵兆(湖南信息职业技术学院,长沙,410001)摘要:随着信息时代的到来,图像信息已经成为信息社会的基本信息之一。

数字图像处理是对图像信息的基本处理方法,它通过一些繁杂的算法对大量的图像的数据进行运算以达到人们满意的图像效果。

Visual C++在图像处理的效率显著,因此本文主要介绍使用V isual C++实现数字图像处理的常用算法,介绍了Visual C++在图像处理中的基本方法和应用上的技巧。

关键词:V isual C++;数字;图像处理;方法一、开发语言的选择图形图像的处理的时间消耗较一般算法多,提高处理效率很有必要,因此选择合适的语言进行算法的描述显得尤为重要。

本文选择Visual C++,其主要优势在于以下三个方面:(1)执行效率高。

C++的执行代码经过编译后生成的是汇编语言,它可以直接在处理器上运行,因此它的执行效率较高。

(2)较高的灵活度。

指针是C++的一种特殊的数据类型,能够获取和直接操纵地址,实现动态存储分配内存。

掌握指针就能更有效地使用内存空间,C++中指针的使用,很大幅度上提高了编程的灵活度。

(3)提高了内容使用效率。

对于图形图像数据的处理而言,大量信息的图像数据处理需要占用较大的内存,而计算机内存是有限的。

在相对有限的内存空间,必须更有效率的使用才能比较好的完成数据处理运算。

由于C++语言支持对内存的直接分配和释放,提高了内容的使用效率,也大大提高了图像处理效率。

二、数字图像的概念就计算机系统而言,图像是以栅格结构的画面存储形式。

而栅格结构将图像划分为分布均匀的栅格,每个栅格为一个像素。

显式的记录每个像素的光度值(亮度/彩色);而像素的坐标值确是规则地隐含的,其位置按规则排列。

在Windows环境下,最重要的图像就是位图(Bitmap),即位映像(bit map)。

图像从色度学理论观念来讲,颜色可以由红(Red)、绿(Green)、蓝(Blue)3种基本颜色按不同的比例组合而成。

自己积累的一些EmguCV代码(主要有图片格式转换,图片裁剪,图片翻转,图片旋转和图片平移等功能)

自己积累的一些EmguCV代码(主要有图片格式转换,图片裁剪,图片翻转,图片旋转和图片平移等功能)

⾃⼰积累的⼀些EmguCV代码(主要有图⽚格式转换,图⽚裁剪,图⽚翻转,图⽚旋转和图⽚平移等功能)using System;using System.Drawing;using Emgu.CV;using Emgu.CV.CvEnum;using Emgu.CV.Structure;namespace ZNLGIS{public class ImageClass{//图⽚裁剪public static Image<Bgr, Byte> Cut(Image<Bgr,Byte> image ,Rectangle rectangle){System.Drawing.Size roisize = new Size(260,380);IntPtr dst = CvInvoke.cvCreateImage(roisize, Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 3);CvInvoke.cvSetImageROI(image.Ptr, rectangle);CvInvoke.cvCopy(image.Ptr, dst, IntPtr.Zero);return OpenCVEmguCVDotNet.IplImagePointerToEmgucvImage<Bgr, Byte>(dst);}//图⽚裁剪public static Image<Bgr, Byte> Cut2(Image<Bgr,Byte> image,int oldwidth,int oldheight){int x = image.Width - oldwidth;int y = image.Height - oldheight;System.Drawing.Size roisize = new System.Drawing.Size(oldwidth, oldheight); //要裁剪的图⽚⼤⼩IntPtr dst = CvInvoke.cvCreateImage(roisize, Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 3);System.Drawing.Rectangle rect = new System.Drawing.Rectangle(x/2, y/2, oldwidth, oldheight);CvInvoke.cvSetImageROI(image.Ptr, rect);CvInvoke.cvCopy(image.Ptr, dst, IntPtr.Zero);return OpenCVEmguCVDotNet.IplImagePointerToEmgucvImage<Bgr, Byte>(dst);}//图⽚翻转public static Image<Bgr, Byte> FlipImage(Image<Bgr, Byte> image, bool isHorizontal){if (isHorizontal){CvInvoke.cvFlip(image.Ptr, IntPtr.Zero, FLIP.HORIZONTAL);}else{CvInvoke.cvFlip(image.Ptr, IntPtr.Zero, FLIP.VERTICAL);}return image;}//图⽚旋转public static Image<Bgr, Byte> RotateImage(Image<Bgr, Byte> image_old, double angle, bool clockwise){IntPtr image_temp;double anglerad = Math.PI * (angle / 180);int newwidth = (int)Math.Abs(image_old.Bitmap.Height * Math.Sin(anglerad)) +(int)Math.Abs(image_old.Bitmap.Width * Math.Cos(anglerad)) + 1;int newheight = (int)Math.Abs(image_old.Bitmap.Height * Math.Cos(anglerad)) +(int)Math.Abs(image_old.Bitmap.Width * Math.Sin(anglerad)) + 1;image_temp = CvInvoke.cvCreateImage(new Size(newwidth, newheight), IPL_DEPTH.IPL_DEPTH_8U, 3);CvInvoke.cvZero(image_temp);int flag = -1;if (clockwise){flag = 1;}float[] m = new float[6];int w = image_old.Bitmap.Width;int h = image_old.Bitmap.Height;m[0] = (float)Math.Cos(flag * angle * Math.PI / 180);m[1] = (float)Math.Sin(flag * angle * Math.PI / 180);m[3] = -m[1];m[4] = m[0];m[2] = w * 0.5f;unsafe{void* p;IntPtr ptr;fixed (float* pc = m){p = (void*)pc;ptr = new IntPtr(p);}IntPtr M = CvInvoke.cvMat(2, 3, MAT_DEPTH.CV_32F, ptr);CvInvoke.cvGetQuadrangleSubPix(image_old.Ptr,image_temp,M);}return OpenCVEmguCVDotNet.IplImagePointerToEmgucvImage<Bgr, Byte>(image_temp);}//图⽚平移public static Image<Bgr, Byte> Py(Image<Bgr, Byte> src,int x,int y){System.Drawing.Size roisize = new Size(src.Width, src.Height);Image<Bgr, Byte> dst = new Image<Bgr, byte>(src.Width, src.Height, new Bgr(Color.Transparent));int i, j;int w = src.Width;int h = src.Height;if (x >= 0 && y >= 0){for (i = 0; i < w - x; i++){for (j = 0; j < h - y; j++){CvInvoke.cvSet2D(dst, j + y, i + x, CvInvoke.cvGet2D(src, j, i));}}}else if (x >= 0 && y < 0){for (i = 0; i < w - x; i++){for (j = -y; j < h; j++){CvInvoke.cvSet2D(dst, j + y, i + x, CvInvoke.cvGet2D(src, j, i));}}}else if (x < 0 && y >= 0){for (i = -x; i < w; i++){for (j = 0; j < h - y; j++){CvInvoke.cvSet2D(dst, j + y, i + x, CvInvoke.cvGet2D(src, j, i));}}}else{for (i = -x; i < w; i++){for (j = -y; j < h; j++){CvInvoke.cvSet2D(dst, j + y, i + x, CvInvoke.cvGet2D(src, j, i));}}}return OpenCVEmguCVDotNet.IplImagePointerToEmgucvImage<Bgr, Byte>(dst);}}}using System;using System.Drawing;using System.Drawing.Imaging;using System.Runtime.InteropServices;using Emgu.CV;using Emgu.CV.CvEnum;namespace ZNLGIS{public class OpenCVEmguCVDotNet{/// <summary>/// 将MIplImage结构转换到IplImage指针;/// 注意:指针在使⽤完之后必须⽤Marshal.FreeHGlobal⽅法释放。

C#对图像像素处理的三种方式

C#对图像像素处理的三种方式

C#对图像像素处理的三种⽅式在C#中,可以采⽤直接获取像素法(GetPixel)、内存拷贝法和指针法(unsafe)来获取图像像素并进⾏处理。

下⾯以图像的灰度化为例说明具体的处理⽅法和速度的⽐较(1G内存,P4处理器测试)。

1.GetPixel⽅法GetPixel(i,j)和SetPixel(i, j,Color)可以直接得到图像的⼀个像素的Color结构,但是处理速度⽐较慢,处理⼀副180*180的图像⼤约需要100.48ms。

private void pixel_Click(object sender, EventArgs e){if(curBitmap != null){myTimer.ClearTimer();myTimer.Start();Color curColor;int ret;for (int i = 0; i < curBitmap.Width; i++){for (int j = 0; j < curBitmap.Height ; j++){curColor = curBitmap.GetPixel(i,j);ret = (int)(curColor.R * 0.299 + curColor.G * 0.587 + curColor.B * 0.114);curBitmap.SetPixel(i, j, Color.FromArgb(ret, ret, ret));}}myTimer.Stop();timeBox.Text = myTimer.Duration.ToString("####.##") + "毫秒";Invalidate();}}2.内存拷贝法内存拷贝法就是采⽤System.Runtime.InteropServices.Marshal.Copy将图像数据拷贝到数组中,然后进⾏处理,这不需要直接对指针进⾏操作,不需采⽤unsafe,处理速度和指针处理相差不⼤,处理⼀副180*180的图像⼤约需要1.32ms。

C++中图像处理的类之一CxImage

C++中图像处理的类之一CxImage

C++中图像处理的类之⼀CxImageCxImage 是⼀个C++类,可以加载、保存、显⽰,转换BMP, JPEG, GIF, PNG, TIFF, MNG, ICO, PCX, TGA, WMF, WBMP, JBG, J2K 等格式图像。

Cximage以位图为基础,并附加⼀些信息保存信息。

Code:class CxImage{...protected:void* pDib; //contains the header, the palette, the pixelsBITMAPINFOHEADER head; //standard headerCXIMAGEINFO info; //extended informationBYTE* pSelection; //selected regionBYTE* pAlpha; //alpha channelCxImage** pLayers; //generic layers}CxImage::head 是⼀个位图头,CxImage::pDib 是通常的位图。

CxImage::info 是⼀个存储在不同格式之间的许多共享信息。

Code:typedef struct tagCxImageInfo {DWORD dwEffWidth; //DWORD aligned scan line widthBYTE* pImage; //THE IMAGE BITSvoid* pGhost; //if this is a ghost, pGhost point to the bodyDWORD dwType; //original image formatchar szLastError[256]; //debugginglong nProgress; //monitorlong nEscape; //escapelong nBkgndIndex; //used for GIF, PNG, MNGRGBQUAD nBkgndColor; //used for RGB transparencyBYTE nQuality; //used for JPEGlong nFrame; //used for TIF, GIF, MNG : actual framelong nNumFrames; //used for TIF, GIF, MNG : total number of//framesDWORD dwFrameDelay; //used for GIF, MNGlong xDPI; //horizontal resolutionlong yDPI; //vertical resolutionRECT rSelectionBox; //bounding rectangleBYTE nAlphaMax; //max opacity (fade)bool bAlphaPaletteEnabled; //true if alpha values in the palette are// enabled.bool bEnabled; //enables the painting functionslong xOffset;long yOffset;DWORD dwEncodeOption; //for GIF, TIF : 0=def.1=unc,2=fax3,3=fax4,// 4=pack,5=jpgRGBQUAD last_c; //for GetNearestIndex optimizationBYTE last_c_index;bool last_c_isvalid;long nNumLayers;DWORD dwFlags;} CXIMAGEINFO;CxImage对象还是多层的集合。

C#图像处理(各种旋转、改变大小、柔化、锐化、雾化、底片、浮雕、黑白、滤镜效果)

C#图像处理(各种旋转、改变大小、柔化、锐化、雾化、底片、浮雕、黑白、滤镜效果)

C#图像处理(各种旋转、改变⼤⼩、柔化、锐化、雾化、底⽚、浮雕、⿊⽩、滤镜效果)⼀、各种旋转、改变⼤⼩注意:先要添加画图相关的using引⽤。

//向右旋转图像90°代码如下:private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e){Graphics g = e.Graphics;Bitmap bmp = new Bitmap("rama.jpg");//加载图像g.FillRectangle(Brushes.White, this.ClientRectangle);//填充窗体背景为⽩⾊Point[] destinationPoints = {new Point(100, 0), // destination for upper-left point of originalnew Point(100, 100),// destination for upper-right point of originalnew Point(0, 0)}; // destination for lower-left point of originalg.DrawImage(bmp, destinationPoints);}//旋转图像180°代码如下:private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e){Graphics g = e.Graphics;Bitmap bmp = new Bitmap("rama.jpg");g.FillRectangle(Brushes.White, this.ClientRectangle);Point[] destinationPoints = {new Point(0, 100), // destination for upper-left point of originalnew Point(100, 100),// destination for upper-right point of originalnew Point(0, 0)}; // destination for lower-left point of originalg.DrawImage(bmp, destinationPoints);}//图像切变代码:private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e){Graphics g = e.Graphics;Bitmap bmp = new Bitmap("rama.jpg");g.FillRectangle(Brushes.White, this.ClientRectangle);Point[] destinationPoints = {new Point(0, 0), // destination for upper-left point of originalnew Point(100, 0), // destination for upper-right point of originalnew Point(50, 100)};// destination for lower-left point of originalg.DrawImage(bmp, destinationPoints);}//图像截取:private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e){Graphics g = e.Graphics;Bitmap bmp = new Bitmap("rama.jpg");g.FillRectangle(Brushes.White, this.ClientRectangle);Rectangle sr = new Rectangle(80, 60, 400, 400);//要截取的矩形区域Rectangle dr = new Rectangle(0, 0, 200, 200);//要显⽰到Form的矩形区域g.DrawImage(bmp, dr, sr, GraphicsUnit.Pixel);}//改变图像⼤⼩:private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e){Graphics g = e.Graphics;Bitmap bmp = new Bitmap("rama.jpg");g.FillRectangle(Brushes.White, this.ClientRectangle);int width = bmp.Width;int height = bmp.Height;// 改变图像⼤⼩使⽤低质量的模式g.InterpolationMode = InterpolationMode.NearestNeighbor;g.DrawImage(bmp, new Rectangle(10, 10, 120, 120), // source rectanglenew Rectangle(0, 0, width, height), // destination rectangleGraphicsUnit.Pixel);// 使⽤⾼质量模式//positingQuality = CompositingQuality.HighSpeed;g.InterpolationMode = InterpolationMode.HighQualityBicubic;g.DrawImage(bmp,new Rectangle(130, 10, 120, 120),new Rectangle(0, 0, width, height),GraphicsUnit.Pixel);}//设置图像的分辩率:private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e){Graphics g = e.Graphics;Bitmap bmp = new Bitmap("rama.jpg");g.FillRectangle(Brushes.White, this.ClientRectangle);bmp.SetResolution(300f, 300f);g.DrawImage(bmp, 0, 0);bmp.SetResolution(1200f, 1200f);g.DrawImage(bmp, 180, 0);}//⽤GDI+画图private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e){Graphics gForm = e.Graphics;gForm.FillRectangle(Brushes.White, this.ClientRectangle);for (int i = 1; i <= 7; ++i){//在窗体上⾯画出橙⾊的矩形Rectangle r = new Rectangle(i*40-15, 0, 15,this.ClientRectangle.Height);gForm.FillRectangle(Brushes.Orange, r);}//在内存中创建⼀个Bitmap并设置CompositingModeBitmap bmp = new Bitmap(260, 260,System.Drawing.Imaging.PixelFormat.Format32bppArgb);Graphics gBmp = Graphics.FromImage(bmp);positingMode = positingMode.SourceCopy; // 创建⼀个带有Alpha的红⾊区域// 并将其画在内存的位图⾥⾯Color red = Color.FromArgb(0x60, 0xff, 0, 0);Brush redBrush = new SolidBrush(red);gBmp.FillEllipse(redBrush, 70, 70, 160, 160);// 创建⼀个带有Alpha的绿⾊区域Color green = Color.FromArgb(0x40, 0, 0xff, 0);Brush greenBrush = new SolidBrush(green);gBmp.FillRectangle(greenBrush, 10, 10, 140, 140);//在窗体上⾯画出位图 now draw the bitmap on our windowgForm.DrawImage(bmp, 20, 20, bmp.Width, bmp.Height);// 清理资源bmp.Dispose();gBmp.Dispose();redBrush.Dispose();greenBrush.Dispose();}//在窗体上⾯绘图并显⽰图像private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e){Graphics g = e.Graphics;Pen blackPen = new Pen(Color.Black, 1);if (ClientRectangle.Height / 10 > 0){for (int y = 0; y < ClientRectangle.Height; y += ClientRectangle.Height / 10){g.DrawLine(blackPen, new Point(0, 0), new Point(ClientRectangle.Width, y));}}blackPen.Dispose();}C# 使⽤Bitmap类进⾏图⽚裁剪在Mapwin(⼿机游戏地图编辑器)⽣成的地图txt⽂件中添加⾃⼰需要处理的数据后转换成可在⼿机(Ophone)开发环境中使⽤的字节流地图⽂件的⼩⼯具,其中就涉及到图⽚的裁剪和⽣成了。

VC++实现图像二值处理

VC++实现图像二值处理

Visual C++实现二值图像处理二值图像是一种简单的图像格式,它只有两个灰度级,即"0"表示黑色的像素点,"255"表示白色的像素点,至于如何从一幅普通的图像获得二值图像,请参考我近期在天极网上发表的《Visual C++编程实现图像的分割》一文。

二值图像处理在图像处理领域占据很重要的位置,在具体的图像处理应用系统中,往往需要对于获得的二值图像再进一步进行处理,以有利于后期的识别工作。

二值图像处理运算是从数学形态学下的集合论方法发展起来的,尽管它的基本运算很简单,但是却可以产生复杂的效果。

常用的二值图像处理操作有许多方法,如腐蚀、膨胀、细化、开运算和闭运算等等。

本文对这些内容作些研究探讨,希望对爱好图像处理的朋友有所帮助。

一、腐蚀和膨胀形态学是一门新兴科学,它的用途主要是获取物体拓扑和结果信息,它通过物体和结构元素相互作用的某些运算,得到物体更本质的形态。

它在图像处理中的应用主要是:b5E2RGbCAP1.利用形态学的基本运算,对图像进行观察和处理,从而达到改善图像质量的目的;2.描述和定义图像的各种几何参数和特征,如面积,周长,连通度,颗粒度,骨架和方向性。

限于篇幅,我们只介绍简单二值图像的形态学运算,对于灰度图像的形态学运算,有兴趣的读者可以看有关的参考书。

二值图像基本的形态学运算是腐蚀和膨胀,简单的腐蚀是消除物体的所有边界点的一种过程,其结果是使剩下的物体沿其周边比原物体小一个像素的面积。

如果物体是圆的,它的直径在每次腐蚀后将减少两个像素,如果物体在某一点处任意方向上连通的像素小于三个,那么该物体经过一次腐蚀后将在该点处分裂为二个物体。

简单的膨胀运算是将与某物体接触的所有背景点合并到该物体中的过程。

过程的结果是使物体的面积增大了相应数量的点,如果物体是圆的,它的直径在每次膨胀后将增大两个像素。

如果两个物体在某一点的任意方向相隔少于三个像素,它们将在该点连通起来。

Visual+C++实现数字图像增强处理

Visual+C++实现数字图像增强处理

前言对于一个图像处理系统来说,可以将流程分为三个阶段,在获取原始图像后,首先是图像预处理阶段、第二是特征抽取阶段、第三是识别分析阶段。

图像预处理阶段尤为重要,如果这阶段处理不好,后面的工作根本无法展开。

在实际应用中,我们的系统获取的原始图像不是完美的,例如对于系统获取的原始图像,由于噪声、光照等原因,图像的质量不高,所以需要进行预处理,以有利于提取我们感兴趣的信息。

图像的预处理包括图像增强、平滑滤波、锐化等内容。

图像的预处理既可以在空间域实现,也可以在频域内实现,我们主要介绍在空间域内对图像进行点运算,它是一种既简单又重要的图像处理技术,它能让用户改变图像上像素点的灰度值,这样通过点运算处理将产生一幅新图像。

下面我们开始介绍与图像点运算的相关知识。

一、图像的直方图图像直方图是图像处理中一种十分重要的图像分析工具,它描述了一幅图像的灰度级内容,任何一幅图像的直方图都包含了丰富的信息,它主要用在图象分割,图像灰度变换等处理过程中。

从数学上来说图像直方图是图像各灰度值统计特性与图像灰度值的函数,它统计一幅图像中各个灰度级出现的次数或概率;从图形上来说,它是一个二维图,横坐标表示图像中各个像素点的灰度级,纵坐标为各个灰度级上图像各个像素点出现的次数或概率。

如果不特别说明,本讲座中的直方图的纵坐标都对应着该灰度级在图像中出现的概率。

我们的例子是在一个对话框中显示一个图像的直方图,为实现该目的,我们定义了一个名为"ZFT"的对话框类用来显示图像的直方图,具体实现代码和效果图如下(关于代码实现部分可以参考笔者2001年在天极网上发表的一篇VC实现数字图像处理的文章)://////////////////////////////////直方图对话框构造函数;ZFT::ZFT(CWnd* pParent /*=NULL*/): CDialog(ZFT::IDD, pParent)//ZFT为定义的用来显示直方图的对话框类;{Width=Height=0;//对话框初始化阶段设置图像的宽和高为"0";}////////////////////////对话框重画函数;void ZFT::OnPaint(){CRect rect;//矩形区域对象;CWnd *pWnd;//得到图片框的窗口指针;pWnd=GetDlgItem(IDC_Graphic);//得到ZFT对话框内的"Frame"控件的指针;file://(IDC_Graphic为放置在对话框上的一个"Picture"控件,并讲类型设置为"Frame")。

VC++数字图像处理

VC++数字图像处理

Visual C++数字图像处理广义地讲,凡是记录在纸介质上的、拍摄在底片和照片上的、显示在电视、投影仪和计算机屏幕上的所有具有视觉效果的画面都可以称为图像。

根据图像记录方式的不同,图像可分为两大类:一类是模拟图像(Analog Image),另一类是数字图像(Digital Image)。

模拟图像是通过某种物理量(光、电等)的强弱变化来记录图像上各点的亮度信息的,例如模拟电视图像;而数字图像则完全是用数字(即计算机存储的数据)来记录图像亮度信息的。

所谓数字图像处理(Digital Image Processing),就是指用数字计算机及其他相关的数字技术,对数字图像施加某种或某些运算和处理,从而达到某种预期的处理目的。

随着数字技术和数字计算机技术的飞速发展,数字图像处理技术在近 20 多年的时间里,迅速发展成为一门独立的有强大生命力的学科,其应用领域十分广泛。

作为数字图像处理技术的实现环节,本书将在 Visual C++环境下介绍图像各种典型算法的编程实现。

而作为一本书的开始,本章我们将介绍图像编程的基础知识,如数字图像的点阵数据、调色板概念、BMP 文件结构以及设备无关位图(DIB)等,它是后面章节学习的基础。

1.1 图像、颜色表和色彩空间1.1.1 图像组成数字图像的基本单位是像素(Pixel),也就是说,数字图像是像素的集合。

如图 1-1 所示,图中每个格点代表一个像素,该图是一个白色背景下包含灰色矩形的图像。

图 1-1 放大后的矩形图像数字图像通常存放在计算机的外存储器设备中,例如硬盘、光盘等,在需要进行显示和处理时才被调入内存的数组中。

从本质上讲,图像数据在计算机内存或硬盘中是以字符型数据存在的,这与其他整型数据或者浮点型数据没有任何区别,都是一种数字表达符号,当把它在计算机屏幕上显示出来时,才是我们人眼看到的真正有意义的数字图像。

普通的显示器屏幕也是由许多点(像素)构成的,显示时,电子枪每次从左到右、从上到下进行扫描,为每个像素着色,利用人眼的视觉暂留效应就可以显示出一屏完整的图像。

Cimage类处理图像像素(数据)的3种方式(转)

Cimage类处理图像像素(数据)的3种方式(转)

Cimage类处理图像像素(数据)的3种⽅式(转)这⾥只讨论对图像像素的处理,cimage类的具体⽤法查相关资料#include <atlimage.h> //VS2010以后不⽤加这个……………………CImage m_Image; //或CImage* m_Image; 下⾯例⼦程序我⽤的CImage m_Image; 只是⼀个⽤成员选择符,⼀个⽤指针操作,效率上可能有所差异下⾯是3种⽅法:⼀、⽤Cimage类的成员函数进⾏处理这⾥假设你已经加载了图像位图,并与CImage对象m_Image相关联。

相关成员函数主要有:GetPixel 返回像素颜⾊SetPixel 设置像素颜⾊如:m_Image.SetPixel( i-1, j-1, RGB(rr,gg,bb));SetPixelRGB 设置像素的红绿蓝如:m_Image.SetPixelRGB(x,y,avg,avg,avg);SetColorTable 设置调⾊板颜⾊分量(红、绿、蓝)值GetWidth 宽度(以像素为单位)GetHeight ⾼度1、程序⽰例1)⼀个双线性插值放⼤程序。

[cpp]1. if (m_Image.IsNull())2. return;3. // 创建对话框4. DlgInterpolation TranPara;5. //显⽰对话框,提⽰⽤户设定量6. if (TranPara.DoModal() != IDOK)7. return;8. int k=TranPara.m_inter;9. BeginWaitCursor();10. CImage m_Image1;11. if (! m_Image1.IsNull())12. {13. m_Image1.Destroy();14. }15. m_Image1.Create( m_Image.GetWidth()*k, m_Image.GetHeight()*k, 24,0);16. // 四个最临近象素的坐标17. int x1, x2;18. int y1, y2;19. // 四个最临近象素值20. unsigned char f1, f2, f3, f4;21. // ⼆个插值中间值22. unsigned char f12, f34;23. //计算结果24. int fr,fb,fg;25. double epsilon = 0.001;26. COLORREF pixel11,pixel12,pixel21,pixel22;27. int nHeight1 = m_Image1.GetHeight();28. int nWidth1 = m_Image1.GetWidth();29. int nHeight = m_Image.GetHeight();30. int nWidth = m_Image.GetWidth();31. double m=((double)nWidth1-1)/((double)nWidth-1);32. for (int i=0; i<nWidth1; i++)33. {34. for (int j=0; j<nHeight1; j++)35. {36. double x=double((double)i/m);37. double y=double((double)j/m);38. //计算四个最临近象素的坐标,+1向右下⽅移动39. x1 = (int) x;40. x2 = x1 + 1;41. y1 = (int) y;42. y2 = y1 + 1;43. if( (x < 0) || (x > nWidth - 1) || (y < 0) || (y > nHeight - 1))44. {45. //要计算的点不在源图范围内,返回-146. continue;47. }48. else49. {50. if (fabs(x - nWidth + 1) <= epsilon )51. {52. // 要计算的点在图像右边缘上53. if (fabs(y -nHeight + 1) <= epsilon)54. {55. // 要计算的点正好是图像最右下⾓那⼀个象素,直接返回该点象素值56. pixel11 = m_Image.GetPixel(x1,y1);57. f1 = (unsigned char)GetRValue(pixel11);58. fr=(int)f1;59. f1 = (unsigned char)GetGValue(pixel11);60. fg=(int)f1;61. f1 = (unsigned char)GetBValue(pixel11);62. fb=(int)f1;63. }64. else65. {66. // 在图像右边缘上且不是最后⼀点,直接⼀次插值即可67. pixel11 = m_Image.GetPixel(x1,y1);68. pixel12 = m_Image.GetPixel(x1,y2);69. f1 = (unsigned char)GetRValue(pixel11);70. f3 = (unsigned char)GetRValue(pixel12);71. fr= (int) (f1 + (y -y1) * (f3 - f1));72. f1 = (unsigned char)GetGValue(pixel11);73. f3 = (unsigned char)GetGValue(pixel12);74. fg= (int) (f1 + (y -y1) * (f3 - f1));75. f1 = (unsigned char)GetBValue(pixel11);76. f3 = (unsigned char)GetBValue(pixel12);77. fb= (int) (f1 + (y -y1) * (f3 - f1));78. }79. }80. else if (fabs(y - nHeight + 1) <= epsilon)81. {82. // 要计算的点在图像下边缘上且不是最后⼀点,直接⼀次插值即可83. pixel11 = m_Image.GetPixel(x1,y1);84. pixel21 = m_Image.GetPixel(x2,y1);85. f1 = (unsigned char)GetRValue(pixel11);86. f2 = (unsigned char)GetRValue(pixel21);87. fr=(int) (f1 + (x -x1) * (f2 - f1));88. f1 = (unsigned char)GetGValue(pixel11);89. f2 = (unsigned char)GetGValue(pixel21);90. fg=(int) (f1 + (x -x1) * (f2 - f1));91. f1 = (unsigned char)GetBValue(pixel11);92. f2 = (unsigned char)GetBValue(pixel21);93. fb=(int) (f1 + (x -x1) * (f2 - f1));94. }95. else96. {97. pixel11 = m_Image.GetPixel(x1,y1);98. pixel12 = m_Image.GetPixel(x1,y2);99. pixel21 = m_Image.GetPixel(x2,y1);100. pixel22 = m_Image.GetPixel(x2,y2);101. // 计算四个最临近象素值102. f1 = (unsigned char)GetRValue(pixel11);103. f2 = (unsigned char)GetRValue(pixel21);104. f3 = (unsigned char)GetRValue(pixel12);105. f4 = (unsigned char)GetRValue(pixel22);106. f12 = (unsigned char) (f1 + (x - x1) * (f2 - f1));107. f34 = (unsigned char) (f3 + (x - x1) * (f4 - f3));108. fr= (int) (f12 + (y -y1) * (f34 - f12));109. f1 = (unsigned char)GetGValue(pixel11);110. f2 = (unsigned char)GetGValue(pixel21);111. f3 = (unsigned char)GetGValue(pixel12);112. f4 = (unsigned char)GetGValue(pixel22);113. f12 = (unsigned char) (f1 + (x - x1) * (f2 - f1));114. f34 = (unsigned char) (f3 + (x - x1) * (f4 - f3));115. fg= (int) (f12 + (y -y1) * (f34 - f12));116. f1 = (unsigned char)GetBValue(pixel11);117. f2 = (unsigned char)GetBValue(pixel21);118. f3 = (unsigned char)GetBValue(pixel12);119. f4 = (unsigned char)GetBValue(pixel22);120. f12 = (unsigned char) (f1 + (x - x1) * (f2 - f1));121. f34 = (unsigned char) (f3 + (x - x1) * (f4 - f3));122. fb= (int) (f12 + (y -y1) * (f34 - f12));123. }124. }125. m_Image1.SetPixel(i,j, RGB(fr,fg,fb));126. }127. }128. m_Image.Destroy();129. m_Image.Create( m_Image1.GetWidth(), m_Image1.GetHeight(), 24, 0);130. COLORREF pixel;131. for (int i=0; i<nWidth1; i++)132. {133. for (int j=0; j<nHeight1; j++)134. {135. pixel = m_Image1.GetPixel(i,j);136. int y=GetRValue(pixel);137. int p=GetGValue(pixel);138. int b=GetBValue(pixel);139. m_Image.SetPixelRGB(i,j,GetRValue(pixel),GetGValue(pixel),GetBValue(pixel));140. }141. }142. m_Image1.Destroy();143. Invalidate();144. EndWaitCursor();2)处理视频帧[cpp]1. ……2. Defog(imageprosses, nimgWidth, nimgheigt);/*我加的⼀个雾天图像增强的动态库,imageprosses是视频的⼀帧,输⼊imageprosses处理,并输出imageprosses*/3. int rr = 0, gg = 0, bb = 0;4. for (int i = 0; i < nimgWidth; i++)5. {6. for (int j = 1; j <= nimgheigt; j++)7. {8. bb=(int)imageprosses[3*i*j];9. gg=(int)imageprosses[3*i*j+1];10. rr=(int)imageprosses[3*i*j+2];11. m_Image.SetPixel(i, j-1, RGB(rr,gg,bb));/*设置⼀帧图像的像素值⽤来显⽰*/12. }13. }14. ……2、⽐较:⾮常慢。

(转)C#进行图像处理的几种方法(Bitmap,BitmapData,IntPtr)

(转)C#进行图像处理的几种方法(Bitmap,BitmapData,IntPtr)

(转)C#进⾏图像处理的⼏种⽅法(Bitmap,BitmapData,IntPtr)转⾃C#进⾏图像处理的⼏种⽅法本⽂讨论了C#图像处理中Bitmap类、BitmapData类和unsafe代码的使⽤以及字节对齐问题。

Bitmap类命名空间:System.Drawing封装 GDI+ 位图,此位图由图形图像及其属性的像素数据组成。

Bitmap 是⽤于处理由像素数据定义的图像的对象。

利⽤C#类进⾏图像处理,最⽅便的是使⽤Bitmap类,使⽤该类的GetPixel()与SetPixel()来访问图像的每个像素点。

下⾯是MSDN中的⽰例代码:public void GetPixel_Example(PaintEventArgs e){// Create a Bitmap object from an image file.Bitmap myBitmap = new Bitmap("Grapes.jpg");// Get the color of a pixel within myBitmap.Color pixelColor = myBitmap.GetPixel(50, 50);// Fill a rectangle with pixelColor.SolidBrush pixelBrush = new SolidBrush(pixelColor);e.Graphics.FillRectangle(pixelBrush, 0, 0, 100, 100);}可见,Bitmap类使⽤⼀种优雅的⽅式来操作图像,但是带来的性能的降低却是不可忽略的。

⽐如对⼀个800*600的彩⾊图像灰度化,其耗费的时间都要以秒为单位来计算。

在实际项⽬中进⾏图像处理,这种速度是决对不可忍受的。

BitmapData类命名空间:System.Drawing.Imaging指定位图图像的属性。

BitmapData 类由 Bitmap 类的 LockBits 和 UnlockBits ⽅法使⽤。

C语言BMP图片处理

C语言BMP图片处理

C语言 BMP图片处理BMP是bitmap的缩写形式,bitmap顾名思义,就是位图也即Windows位图。

它一般由4部分组成:文件头信息块、图像描述信息块、颜色表(在真彩色模式无颜色表)和图像数据区组成。

在系统中以BMP为扩展名保存。

打开Windows的画图程序,在保存图像时,可以看到三个选项:2色位图(黑白)、16色位图、256色位图和24位位图。

这是最普通的生成位图的工具,在这里讲解的BMP位图形式,主要就是指用画图生成的位图(当然,也可以用其它工具软件生成)。

现在讲解BMP的4个组成部分:1.文件头信息块0000-0001:文件标识,为字母ASCII码“BM”。

0002-0005:文件大小。

填写。

0006-0009:保留,每字节以“00”000A-000D:记录图像数据区的起始位置。

各字节的信息依次含义为:文件头信息块大小,图像描述信息块的大小,图像颜色表的大小,保留(为01)。

2.图像描述信息块000E-0011:图像描述信息块的大小,常为28H。

0012-0015:图像宽度。

0016-0019:图像高度。

001A-001B:图像的plane(平面?)总数(恒为1)。

001C-001D:记录像素的位数,很重要的数值,图像的颜色数由该值决定。

001E-0021:数据压缩方式(数值位0:不压缩;1:8位压缩;2:4位压缩)。

0022-0025:图像区数据的大小。

0026-0029:水平每米有多少像素,在设备无关位图(.DIB)中,每字节以00H 填写。

002A-002D:垂直每米有多少像素,在设备无关位图(.DIB)中,每字节以00H 填写。

002E-0031:此图像所用的颜色数,如值为0,表示所有颜色一样重要。

3.颜色表颜色表的大小根据所使用的颜色模式而定:2色图像为8字节;16色图像位64字节;256色图像为1024字节。

其中,每4字节表示一种颜色,并以B(蓝色)、G(绿色)、R(红色)、alpha(像素的透明度值,一般不需要)。

Visual C++数字图像处理典型案例详解

Visual C++数字图像处理典型案例详解

第1章 数字图像处理软件开发概述“心有多大,舞台就有多大。

”开发数字图像处理软件,需要想象力,而要把想象变成现实,则需要得心应手的开发平台。

目前常用于开发数字图像处理软件的平台可以粗略地分为通用平台和专用平台两大类。

通用平台不是专门针对数字图像处理软件开发而打造的,但是却可以用于开发数字图像处理系统,如Visual C++、Matlab等。

为了提高开发效率,通用平台往往结合专门的软件包(如OpenCV、VTK 等)或工具箱(如Matlab中的Image Processing工具箱等)进行数字图像处理软件开发。

专用平台则是专为数字图像处理或更进一步的机器视觉系统开发量身定制的,这类开发平台中均内置了大量专门用于数字图像处理的数据结构、对象、函数或组件模块,可供开发人员方便地调用,在更高的层次上进行数字图像处理系统的开发,如Halcon、VisionPro等。

本章主要介绍本书将要用到的几种开发平台及其配置和使用方法。

本章要点Visual C++处理数字图像的基本方法在Visual C++中使用OpenCV在Visual C++中使用VTK1.1 Visual C++“工欲善其事,必先利其器。

”Visual C++便是众多开发工具中的“一把所向披靡的利器”。

Visual C++(简称VC)是Microsoft公司的Visual Studio开发工具箱中的一个C++程序开发环境。

自诞生以来,凭借着C++语言的强大威力、开发环境的良好支持,以及与Windows操作系统的“血缘”关系,一直是Windows操作系统环境下最主要的开发工具之一。

使用VC可以完成各种各样应用程序的开发,从底层软件到上层直接面向用户的软件,而且用VC开发出的产品与Windows操作系统最具“亲和力”。

掌握了VC,就等于进入了Windows编程的自由王国。

VC在数字图像处理软件开发中也占据着极其重要的地位。

第1章Visual C++1.1.1 Visual C++概述VC是一个面向对象的可视化集成开发系统,它不但具有程序框架自动生成、灵活方便的类管理、代码编写和界面设计集成交互操作、可开发多种程序等优点,而且通过简单的设置就可使其生成的程序框架支持数据库接口、OLE2、WinSock网络、3D控制界面。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档