科学网

 找回密码
  注册
科学网 标签 Visual 相关日志

tag 标签: Visual

相关日志

visual studio 2012 项目属性 无法打开,弹出错误提示:未将对象
baibing 2013-1-13 18:01
在Visualstudio2012中,我想修改项目的包含路径和库路径,于是打开项目-属性,然后点击左侧的“VC++目录”,就弹出提示: “未将对象的引用设置到对象的实例”, 若有高手可以恢复一下怎么回事。 不过,从 视图- 属性管理器 的 Microsoft.Cpp.Win32.user 中进入“VC++目录”,从而达到我们修改其包含和库目录的目的。 这个道理在下面的 转载文章中有所介绍。 在VisualStudio2010中配置VC++目录 http://blog.sina.com.cn/s/blog_72824f680100ps4c.html VS 2010在“工具-选项-项目和解决方案-VC++ 目录”的功能已经被否决,不再提供设置,如下图: IMG title="在VisualStudio2010中配置VC++目录" name=image_operate_19001295597286724 alt="在VisualStudio2010中配置VC++目录" src="http://s4.sinaimg.cn/middle/72824f68t9a568278ad33690" action-type="show-slide" action-data="http%3A%2F%2Fs4.sinaimg.cn%2Fmiddle%2F72824f68t9a568278ad33%26690" real_src="http://s4.sinaimg.cn/middle/72824f68t9a568278ad33690" 但是每个工程都要在“项目-属性-配置属性-VC++ 目录”中一一设置如OpenCV之类的公共库文件目录是件很麻烦的事,如何解决呢? 方案一: 1、先打开任意一个VC项目,再打开VS2010的属性管理器(视图-其他窗口- 属性管理器 ),如下图。 IMG title="在VisualStudio2010中配置VC++目录" name=image_operate_57301295596888892 alt="在VisualStudio2010中配置VC++目录" src="http://s6.sinaimg.cn/middle/72824f68t9a568ea5d085690" width=248 height=292 real_src="http://s6.sinaimg.cn/middle/72824f68t9a568ea5d085690" 双击任意“Microsoft.Cpp.Win32.user”,弹出属性页,在里面设置VC++目录即可。这样,该设置对所有VC项目都有效,见下图。 IMG title="在VisualStudio2010中配置VC++目录" name=image_operate_12331295597279011 alt="在VisualStudio2010中配置VC++目录" src="http://s10.sinaimg.cn/middle/72824f68t9a56a942ae99690" width=690 height=494 action-type="show-slide" action-data="http%3A%2F%2Fs10.sinaimg.cn%2Fmiddle%2F72824f68t9a56a942ae99%26690" real_src="http://s10.sinaimg.cn/middle/72824f68t9a56a942ae99690" 其实这种方法修改的结果会保存到%USERPROFILE%\appdata\local\microsoft\msbuild\v4.0下面的文件: Microsoft.Cpp.Win32.user.props。如果是64平台则是反应到Microsoft.Cpp.X64.user.props文件中。这两个文件都是在安装VS2010时产生的。所以很容易想到方案二了。 方案二: 1、定位到 %USERPROFILE%\appdata\local\microsoft\msbuild\v4.0(可以通过运行,或直接在windows资源管理器的地址栏中输入)。 2、使用词本或其他文本编辑工具修改 Microsoft.Cpp.Win32.user.props或Microsoft.Cpp.X64.user.props文件中的相关字段。
8435 次阅读|0 个评论
Visual Studio 2012 中使用环境变量
baibing 2013-1-11 22:33
Visual  Studio 2012 中使用环境变量
Visual Studio 2012 中 已经不再像vs6.0 那样,提供针对整个个workspace的 include、 lib 等目录设置了。 而每一个项目都要设置针对自己的 这些目录,并且这是通过引用环境变量的方式方便设置的。 环境变量就是操作系统的那个环境变量,代表的是一系列的目录。在VS2012中进行目录设置时可以直接引用。 用户可以在项目配置中 如 Include为例,直接输入 引用的环境变量; 点击进入 编辑后,再点击宏,可以见到下图,底面用户可以在已有的环境变量库中搜索是否已有可用的环境变量。可以添加到上面的空白中。
1 次阅读|0 个评论
visual studio Ultimate 2012 安装
baibing 2013-1-10 17:06
1、安装 安装后,按照要求,重新启动,总是弹出 Cannot find one or more components,。。。 从而无法启动。 重装了3次,问题竟然又没有了。不知什么原因。 这是遇到的第一个问题。 第二个问题,编译出错,提示缺少文件。使用Appwizard生成的程序编译连接也出错,解决方法见2: 另一个问题是,以上只是配置项目,如何将include 和lib一劳永逸设置?? 参考3、 为Visual Studio添加默认INCLUDE包含路径一劳永逸的方法(更新) 2、 fatal error C1083: 无法打开包括文件:“SDKDDKVer.h” http://www.global-webnet.com/Blog/post/2012/04/14/Kinect-SkeletalViewer-Cannot-open-include-file-SDKDDKVerh-No-such-file-or-directory.aspx The solution is 3 easy steps... While evaluating C++ development for the Kinect (for my http://SolrContrib.CodePlex.com project) I ran into issues compiling the newly installed project from the Sample (on a fresh install of Windows 8 and Visual Studio 2011). In the end I found that "the juice wasn't worth the squeeze"; the C# demos performed just as well as the C++ demos(in the same task that will meet my concerns) with a fraction of the coding (and learning curve). Binging a solution wasn't productive - I am a C# developer (with no understanding of the C++ environment) trying to compile a project under Windows 8 using Visual Studio 2011. I learned early thatwhen you liveon the bleeding edge that sometimes youhave to bleed, I was hemorrhaging. I did however find an excellent clue within the VS11: C++ include directories not set correctly in new project bug reported on the Microsoft site. There was enough information to let me know that I required a "Windows Kits" folder (WindowsSdkDir) which will hold the SDKDDKVer.h. Long story short the Bing trail took me to the following: Windows Driver Kit (WDK) 8 Consumer Preview: http://msdn.microsoft.com/en-us/windows/hardware/hh852362 Step #1 - Download and install this development kit,I wasn't trying to create Windows Drivers, however I felt it was safe to assume it would have everything Windows Drivers developers required to compile their C++ applications. The assumption paid off; afterI installed it, along withthe Windows Driver Frameworks (WDF) Co-Installers it will recommend that you install, the folders were now available! But I was still not compiling! I went back to bug report and like Jennifer I did not have the required "/shared" folder in the Include directories path (which she manually added). HOWEVER, I did note a checkbox setting inherit from parent or project defaults as I stumbled around trying to find "HOW"includes worked in thisenvironment(using the following steps): Step #2 - comply with the following steps Right click on SkeletalViewer Project Select Properties Open Configuration Properties (ref SkeletalViewer Property Pages in image below) Selected VC++ Directories (not shown in image) Select Include Directories (shown in image below) Click the dropdown box (down arrow icon) that will appear to right of input field Select Edit (you will see Include Directories windows shown in image below) Click the Macros button and scroll down to the WindowsSDK_Include path (shown below) I saw how the $(WindowsSDK_includePath), included with "Inherited values", contained my /Shared folder!!! I clicked the Checkbox Inherit from parent or project defaults, exited all windows applying updates as applicable. I Hit compile and I got another error - this time for a .lib file (can't recall what it was). 白冰做法:WDK是默认安装在C:\Program Files\Windows Kits中,具体将C:\Program Files (x86)\Windows Kits\8.0\Include - shared - um - winrt 三个目录包含到项目中。 这也可以直接通过在项目设置中添加引用这个$(WindowsSDK_includePath) 变量来实现,这个环境变量已经存在了,可以在宏中查到。 Step #3 - I followed the same steps from 5 on for the Library Directories path. 白冰做法:将C:\Program Files\Windows Kits\8.0\Lib\win7\km\x86 包含到 这个项目中。 这里也可以建立和引用环境变量的方式:可是如何在visual studio中为自己的工程添加环境变量?参见4 I Hit compile and Walla! I can compile and run the KinectViewer application! 3、 为Visual Studio添加默认INCLUDE包含路径一劳永逸的方法(更新) 你是否曾经也有过这样的问题: 用VS的时候,有时会用到一些非自带的库,例如WTL、Boost、DX等,每次需要用到时都要在项目属性里添加相应的include目录,久而久之觉得有点麻烦。是否有解决办法呢? 于是我便在网上找相关资料,在StackOverflow网站上找到一篇相关的文章( 原文链接 ),文章里提到的一个办法是修改 C:\Users\user\AppData\Local\Microsoft\MSBuild\v4.0\Microsoft.Cpp.Win32.user.props 这个文件,在这个文件里添加需要include的目录,之前我一直是用这个方法,也没啥问题。 当我安装了VS2012之后,问题变出现了。在VS2012上新建一个MFC的工程,什么也没动,居然编译不通过,提示找不到某些文件,我便联想到了是不是之前修改了影响到了,于是我果断把修改的那个文件恢复成默认的内容,再试,结果就没问题了。。。可是这样就得每次都手动添加WTL的目录了。。我便开始翻VS的一些配置文件。 解决方案一: 修改 " VS安装目录中的\VC\VCWizards\default.vcxproj " 这个文件,(这其实就是个xml文件) 如我的目录是" D:\Program Files\Microsoft Visual Studio 11.0\VC\VCWizards\default.vcxproj " 如果我要添加的目录是" D:\Program Files\Microsoft Visual Studio 11.0\VC\WTL\include "; 用文本编辑器打开这个文件,定位到文件末尾,在 /Project 之前插入如下内容 PropertyGroup IncludePath $(VCInstallDir)\WTL\include;$(IncludePath) / IncludePath / PropertyGroup $(VCInstallDir)\WTL\include; 就是需要添加的目录了。 $(VCInstallDir) 是VS里的环境变量(在我的电脑上就是" D:\Program Files\Microsoft Visual Studio 11.0\VC "),表示VC的安装目录。 $(IncludePath) 是表示原有的路径。实际上最终得到的路径如图里四个 如果需要添加lib文件的路径的话。格式就是 LibraryPath/LibraryPath 添加完后保存即可,新建一个项目后,在项目属性里可以看到目录已经加进去了。大功告成,VS2010也是用同样的方法,只不过目录不同了。 解决方案二: 这个方法是结合了开头提到的StackOverflow网站上的修改方法。 依然是修改 " VS安装目录中的\VC\VCWizards\default.vcxproj " 这个文件,只不过这里修改的地方不同,用文本编辑器打开该文件,查找" $(UserRootDir)\Microsoft.Cpp.$(Platform).user.props "这段内容, 其实这里就是指向了我电脑上的那个文件 C:\Users\HwangBae\AppData\Local\Microsoft\MSBuild\v4.0\Microsoft.Cpp.Win32.user.props ;这里我就想到了,为VS2010和VS2012指定不同的文件, 将" $(UserRootDir)\Microsoft.Cpp.$(Platform).user.props "全部替换成" $(UserRootDir)\ VC11\ Microsoft.Cpp.$(Platform).user.props "。 然后在 C:\Users\HwangBae\AppData\Local\Microsoft\MSBuild\v4.0 这个目录下创建了两个文件夹,分别命名为VC10和VC11,然后将 Microsoft.Cpp.Win32.user.props 复制到这两个文件夹,然后除了这两个文件夹外的文件均可删除,其他的文件VS会在那两个文件夹里自动重新创建的; 然后编辑 Microsoft.Cpp.Win32.user.props 这个文件,在 Project 节点下按照方法一的步骤插入同样的代码。在VS2010的目录下也做同样的替换。到此就完事了。测试无任何问题。 总结一下这两种方法的区别,方法一修改后,只对新建的项目有效,在没修改之前创建的项目是无效的,而方法对于之前创建的项目也有效。哪种方法比较适合大家自己取舍。 转载请标明出处,原文地址: http://www.cnblogs.com/hwangbae/archive/2012/06/24/2560463.html 如果觉得本文对您有帮助,请支持一下,您的支持是我写作最大的动力,谢谢。 4、 可是 如何在visual studio中为自己的工程添加环境变量 ? 右击"我的电脑"--选择"属性"---选择"高级"--选择"环境变量"--就可以新建自己的环境变量名了 如: 变量名:MicrosoftSDKDir 变量值:C:\ProgramFiles\MicrosoftSDKs\ 如果要设置目录 C:\ProgramFiles\MicrosoftSDKs\Windows\v6.0\Include 以后就可以在VC中设置目录的时候可以(设置default.vcxproj中的 LibraryPath/LibraryPath ) $(MicrosoftSDKDir)Include 了 5、 WTL for Visual Studio 2012 配置详解 学习WTL有一段时间了,因前段时间去参加国赛耽搁几周,回来之后便继续学习,一直对VS2012有爱的我便想在12上面写WTL,上WTL的SVN看到,已经添加了对VS11 beta的支持,其实11就是2012。。于是我便down下来。 网上搜集了一些WTL环境的配置的资料,都写得不错,我在这里做更详细的补充。 Step1: 从WTL的SVN上获取所需的文件,这里需要两份文件 WTL include文件 http://wtl.svn.sourceforge.net/viewvc/wtl/trunk/wtl/include/?view=tar WTL wizard文件 http://wtl.svn.sourceforge.net/viewvc/wtl/trunk/wtl/Wizards/AppWiz/?view=tar 上面提供的仅是Win32所需要的文件,如果需要WTL的其他资源或整个项目,请访问下面的链接 http://wtl.svn.sourceforge.net/viewvc/wtl/?view=tar (以上链接请直接在浏览器打开,勿使用迅雷之类的工具下载) 下载下来是tar.gz的压缩包 可以使用WinRar或者7z之类的软件解压,我这里用WinRar,解压出来后得到两个文件夹 AppWiz就是将WTL添加到VS创建向导里的一些文件,include就是WTL的头文件。 在AppWiz文件里,有一个Files文件夹和多个setupxx.js文件 这些js脚本文件可以帮你将向导文件添加到VS的目录里,不同版本的VS对应不同的js文件 ,例如VS2012就是setup110.js (带x表示Express版本),这里我为了方便管理,需要做出一些修改; 找到" VS安装目录\VC\VCWizards\AppWiz "这个目录,如我电脑上就是" D:\Program Files\Microsoft Visual Studio 11.0\VC\VCWizards\AppWiz ", 在这个目录下新建一个 WTL 文件夹,然后将 Files 文件夹和 setup110.js 移动到WTL文件夹下。 然后将 Files 文件夹重命名为 Application ,然后用记事本编辑 setup110.js ,定位到第60行。 将 var strSourceFolder = FileSys.BuildPath(strValue, "Files"); 修改成 var strSourceFolder = FileSys.BuildPath(strValue, "Application"); 然后打开cmd,执行如下代码 wscript //e :jscript "D:\Program Files\Microsoft Visual Studio 11.0\VC\VCWizards\AppWiz\WTL\setup110.js" 执行完会提示应用程序向导安装成功。 这里再说下另一种方法,先不将Files改为Application,js文件也不修改,直接在cmd里执行安装,安装完后,将Files修改为Application,然后找到 D:\Program Files\Microsoft Visual Studio 11.0\VC\vcprojects\WTLAppWiz.vsz 这个文件,用记事本打开该文件 将第六行 Param="ABSOLUTE_PATH = D:\Program Files\Microsoft Visual Studio 11.0\VC\VCWizards\AppWiz\WTL\Files" 改成 Param="ABSOLUTE_PATH = D:\Program Files\Microsoft Visual Studio 11.0\VC\VCWizards\AppWiz\WTL\Application" 其实吧,不改也是没啥影响,只不过我比较蛋疼。。。。 到这里就完成了向导的添加,如果有洁癖可以把js文件删除掉了。 Step2: 添加WTL的头文件,解压出来的include文件夹下有这些头文件 我的做法是在 D:\Program Files\Microsoft Visual Studio 11.0\VC 下创建了一个WTL文件夹,将include文件夹放进WTL。(也可以放其他目录,配置include目录时改下即可) include目录的添加请参考我的另一片文章 为Visual Studio添加默认INCLUDE包含路径一劳永逸的方法 http://www.cnblogs.com/hwangbae/archive/2012/06/24/2560463.html 由于VFC还未更新对VS2012的支持,我这里就不写VFC的配置了。 如果配置的过程中遇到了问题,欢迎在博客留言讨论或者Email我。 欢迎转载本文章,但请标明出处,原文地址: http://www.cnblogs.com/hwangbae/archive/2012/06/27/2565591.html 如果觉得本文对您有帮助,请支持一下,您的支持是我写作最大的动力,谢谢。 FAQ A: 在cmd里执行js脚本时出现错误: 没有文件扩展 “.js” 的脚本引擎。 怎么解决: Q: 打开注册表编辑器,定位到HKEY_CLASSES_ROOT\.js,将默认值改成JSFILE。
个人分类: 编程|106 次阅读|0 个评论
Microsoft visual studio 2008 + Intel.Visual.Fortran.Compiler
yaozhixiong 2013-1-2 11:41
Microsoft visual studio 2008 Intel.Visual.Fortran.Compiler.Professional.v11.0.061 试试这个来编程
个人分类: fortran|3903 次阅读|0 个评论
[转载]visual c++6.0编译xvid
grapeson 2012-12-7 09:20
看了很多人的博客,觉得不是很详细,所以自己总结一下用的笔记与大家分享一下,共同学习 搭建xvid环境: 一、如果你的VC6.0是sp6版本以下的 1.下载vc6.0SP5的升级包,支持SSE汇编指令安装vcpp5.exe时要它,从以下网址下载: http://download.microsoft.com/download/vstudio60ent/SP5/Wideband-Full/WIN98Me/EN-US/VS6sp5.exe 安装方法: a.直接单击Vs6sp5.exe,点击运行,选泽一个文件夹(如vcsp5)存放它解压出来的文件 b.在vcsp5文件下找到setupsp5.exe,点击后会自动安装,就OK了。 2.vc6.0默认情况下并不支持MMX/SSE等嵌入指令,所以要下载vcpp5.exe让其支持 二、如果你的VC6.0是sp6版本则可跳过1和2,但要做以下修改: a. xvidcore-1.1.3/src目录下的portab.h把#define uint64_t unsigned __int64去掉unsigned b. xvidcore-1.1.3/vfw/src目录下status.h把#define uint64_t unsigned __int64去掉unsigned 3.编译xvid开源代码(以xvid-1.1.3为例) 注:版本可以在xvid.h头文件下查 1.编译xvid要用到汇编,所以要再装汇编器如NASM-2.07-installer.rar,安装后把nasm.exe和ndisasm.exe拷贝到vc98/bin目录下,这样可 省第2步 2.打开空工程的VC,“tools—options——directories下的show directories for下的 Executable files”添加nasm的安装路径即可 如图(上传不 了图片) 3.xvid-1.1.3允许生成静态链接库libxvidcoe.lib或动态链接库xvidcore.dll。 在xvidcore-1.1.3/build/win32目录下的xvidcore.dsw 生成动态 链接库 在xvidcore-1.1.3/build/win32目录下的libxvidcore_static.dsp生成静态链接库 4.编译xvidcore-1.1.3/vfw下的vfw.dsw生成xvidvfw.dll和xvid.inf 5.编译xvidcore-1.1.3/dshow下的dshow.dsp生成xvid.ax, 不过在此之前要 安装directX建议使用directx9.0b,因为他包含有 directshow。最后也要链接其安装路径如: a.Include files(添加在最前面) D:/DXSDK/Include D:/DXSDK/Samples/C++/DirectShow/BaseClasses D:/Program Files/Microsoft Platform SDK for Windows XP SP2/Include b.Library files(添加在最前面) D:/DXSDK/Lib D:/DXSDK/Samples/C++/DirectShow/BaseClasses/lib 6.右键xvid.inf安装xvid 7.把要用到的.dll拷贝到自己的工程文件或者.lib到vc98/lib 8. 这样就OK了。。
2152 次阅读|0 个评论
Visual Basic与图像处理24
热度 1 prrsw 2012-10-14 16:45
Visual Basic与图像处理24
Visual Basic 与图像处理(三) 9 、 Laplacian 微分算子 前面讲的几种都是一阶微分算子,本节开始讲的是二阶微分算子,从理论上来说二阶微分算子比一阶微分算子更为敏感,因此能够提取到更多的细节信息。二阶微分算子中最常用也最简单的就是拉普拉斯( Laplacian )微分算子,可以用下面的公式进行表示: 上式也可以写成平时常见的模板形式: 本例的运行界面如下: Laplacian 滤波按钮对应的代码如下: Private Sub cmdLaplacianFilter_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim Temp(2, 2) As Integer Dim x As Integer, y As Integer Dim Dx As Integer, Dy As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight - 2 ' 边界像素直接不要了 DestImWidth = SourceImWidth - 2 ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的 Laplacian 滤波 For i = 1 To SourceImHeight - 2 ' 边界像素不处理 For j = 1 To SourceImWidth - 2 NGrayValue = 0 For x = 0 To 2 For y = 0 To 2 r = sbits(i + 1 - x, j + 1 - y, 0) g = sbits(i + 1 - x, j + 1 - y, 1) b = sbits(i + 1 - x, j + 1 - y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x, y) = 0.3 * r + 0.59 * g + 0.11 * b Next y Next x NGrayValue = Abs(4 * Temp(1, 1) - Temp(0, 1) - Temp(1, 0) - Temp(1, 2) - Temp(2, 1)) If NGrayValue 255 Then NGrayValue = 255 dbits(i - 1, j - 1, 0) = NGrayValue dbits(i - 1, j - 1, 1) = NGrayValue dbits(i - 1, j - 1, 2) = NGrayValue Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub 拉普拉斯算子还有许多变形形式,这里给出几种常用的变式: 由于拉普拉斯是一种微分算子,它的作用强调图像中的灰度等级的突变,在实际应用中可以将锐化结果叠加到原始图像中,这样既可以保护拉普拉斯锐化处理的效果,同时也能复原原始背景信息,用运算模板的形式表示如下: 这是的运行界面如下: 对比原图可以看出,经过这种方法强化的图像中,细节信息更为明显,上述织物图像表面纹理要比原图清晰得多。
3258 次阅读|2 个评论
Visual Basic与图像处理23
prrsw 2012-10-14 16:28
Visual Basic与图像处理23
Visual Basic 与图像处理 ( 三 ) 8 、 Priwitt 微分算子 Prewitt 微分算子的思路与 Sobel 微分算子的思路类似,也是在一个 3 × 3 模板下进行图像的锐化处理。 Prewitt 微分算子的定义如下: 上面的式子同样也可以用模板进行表示: Priwitt 微分算子与 Sobel 微分算子的模板基本一样,只是系数的微调,因此处理结果也基本一致,从肉眼很难看出明显的差别,本例的运行界面如下: Priwitt 滤波按钮对应的代码如下: Private Sub cmdPriwittFilter_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim Temp(2, 2) As Integer Dim x As Integer, y As Integer Dim Dx As Integer, Dy As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight - 2 ' 边界像素直接不要了 DestImWidth = SourceImWidth - 2 ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的 Priwitt 滤波 For i = 1 To SourceImHeight - 2 ' 边界像素不处理 For j = 1 To SourceImWidth - 2 NGrayValue = 0 For x = 0 To 2 For y = 0 To 2 r = sbits(i + 1 - x, j + 1 - y, 0) g = sbits(i + 1 - x, j + 1 - y, 1) b = sbits(i + 1 - x, j + 1 - y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x, y) = 0.3 * r + 0.59 * g + 0.11 * b Next y Next x Dx = -(Temp(0, 0) + Temp(0, 1) + Temp(0, 2)) + (Temp(2, 0) + Temp(2, 1) + Temp(2, 2)) Dy = -(Temp(0, 0) + Temp(1, 0) + Temp(2, 0)) + (Temp(0, 2) + Temp(1, 2) + Temp(2, 2)) NGrayValue = Sqr(Dx ^ 2 + Dy ^ 2) If NGrayValue 255 Then NGrayValue = 255 dbits(i - 1, j - 1, 0) = NGrayValue dbits(i - 1, j - 1, 1) = NGrayValue dbits(i - 1, j - 1, 2) = NGrayValue Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub
2589 次阅读|0 个评论
Visual Basic与图像处理22
prrsw 2012-10-14 16:15
Visual Basic与图像处理22
Visual Basic 与图像处理 ( 三 ) 7 、 Sobel 微分算子 Roberts 微分算法可以实现图像中细节轮廓信息的获取,但模板中只有 4 个像素点,计算机虽然小,但是作用范围也小。平时使用得更多的是 3 × 3 模板, Sobel 算子就是其中使用得最多的一种,与前面讲述的类似,首先用下面的公式进行微分算子的表示: 同样也可以利用模板表示上面的两个公式: Sobel 微分算子可以用下面的式子表示: 本例的运行界面如下: Sobel 滤波按钮对应的代码如下: Private Sub cmdSobelFilter_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim Temp(2, 2) As Integer Dim x As Integer, y As Integer Dim Dx As Integer, Dy As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight - 2 ' 边界像素直接不要了 DestImWidth = SourceImWidth - 2 ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的 Sobel 滤波 For i = 1 To SourceImHeight - 2 ' 边界像素不处理 For j = 1 To SourceImWidth - 2 NGrayValue = 0 For x = 0 To 2 For y = 0 To 2 r = sbits(i + 1 - x, j + 1 - y, 0) g = sbits(i + 1 - x, j + 1 - y, 1) b = sbits(i + 1 - x, j + 1 - y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x, y) = 0.3 * r + 0.59 * g + 0.11 * b Next y Next x Dx = -(Temp(0, 0) + Temp(0, 1) * 2 + Temp(0, 2)) + (Temp(2, 0) + Temp(2, 1) * 2 + Temp(2, 2)) Dy = -(Temp(0, 0) + Temp(1, 0) * 2 + Temp(2, 0)) + (Temp(0, 2) + Temp(1, 2) * 2 + Temp(2, 2)) NGrayValue = Sqr(Dx ^ 2 + Dy ^ 2) If NGrayValue 255 Then NGrayValue = 255 dbits(i - 1, j - 1, 0) = NGrayValue dbits(i - 1, j - 1, 1) = NGrayValue dbits(i - 1, j - 1, 2) = NGrayValue Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub
2985 次阅读|0 个评论
Visual Basic与图像处理21
prrsw 2012-10-14 15:59
Visual Basic与图像处理21
Visual Basic 与图像处理 ( 三 ) 6 、 Roberts 微分算子 前面介绍的两种微分算子,实际上是分别求出了水平和垂直方向上的细节信息。但在实际的图像处理之中,除了特殊用途之下才会使用到方向滤波,大部分二维图像处理时,需要同时获得两个方向上的细节信息,因此需要设计各向同性的微分算子用于图像的锐化处理。 Roberts 算子一种常用的微分算子,可以满足上述要求,其计算方法可以用下面的公式进行表示: 同样上面的公式可以用下面的两个模板进行表示: 本例的运行界面如下图所示: Roberts 滤波按钮对应的代码如下: Private Sub cmdRobertsFilter_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim Temp(1, 1) As Integer Dim x As Integer, y As Integer Dim Dx As Integer, Dy As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight - 1 ' 边界像素直接不要了 DestImWidth = SourceImWidth - 1 ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的 Roberts 滤波 For i = 0 To SourceImHeight - 2 ' 边界像素不处理 For j = 0 To SourceImWidth - 2 NGrayValue = 0 For x = 0 To 1 For y = 0 To 1 r = sbits(i + x, j + y, 0) g = sbits(i + x, j + y, 1) b = sbits(i + x, j + y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x, y) = 0.3 * r + 0.59 * g + 0.11 * b Next y Next x Dx = -Temp(0, 0) + Temp(1, 1) Dy = -Temp(0, 1) + Temp(1, 0) NGrayValue = Abs(Dx) + Abs(Dy) If NGrayValue 255 Then NGrayValue = 255 dbits(i, j, 0) = NGrayValue dbits(i, j, 1) = NGrayValue dbits(i, j, 2) = NGrayValue Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub
2768 次阅读|0 个评论
Visual Basic与图像处理20
prrsw 2012-10-14 15:35
Visual Basic与图像处理20
Visual Basic 与图像处理(三) 图像的锐化处理也是图像增强的一种方法,主要是为了突出图像中的部分细节或者增强被模糊了细节。从取样规律来说,在图像分辨率不足时,所获得的像素点可以认为是周围景物亮度的平均值,这种均值效率使得图像变得模糊,可以认为这种均值处理的方法与积分效应类似,与此相对,为了强化图像细节,可以对图像进行微分处理,后面介绍的锐化处理就可以看成为各种不同的微分算法。 从数学定义来看,微分的含义就是数据的变化率,由于图像是由离散的像素点表示的,因此图像的微分就是像素点的差值,称为差分。为了便于叙述,后文在不再区分微分和差分的概念。 5 、具有方向性的一阶微分算子 为了便于理解,首先从一些最简单的微分算子将其,这类一阶微分算法的最大特点就是可以获得图像中特定方向上的灰度变化情况,在特定的纹理分析、检测方法非常有效,有时会称为方向性锐化。 (1) 水平方向的微分算子 水平方向的微分算子就是为了获得图像在水平方向上的灰度变化率,对于像素点 f(x,y) ,水平算子的定义如下: 用前面讲述过的模板的概念,水平方向微分算法可以用下面的模板进行表示: 在实际运算中,可以对上述的计算结果取绝对值处理,以避免出现负值,本例的运行界面如下: 水平微分算子按钮对应代码如下: Private Sub cmdHonSharpFilter_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim Temp(2, 2) As Integer Dim x As Integer, y As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight - 2 ' 边界像素直接不要了 DestImWidth = SourceImWidth - 2 ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的均值滤波直方图统计 For i = 1 To SourceImHeight - 2 ' 边界像素不处理 For j = 1 To SourceImWidth - 2 NGrayValue = 0 For x = 0 To 2 For y = 0 To 2 r = sbits(i + 1 - x, j + 1 - y, 0) g = sbits(i + 1 - x, j + 1 - y, 1) b = sbits(i + 1 - x, j + 1 - y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x, y) = 0.3 * r + 0.59 * g + 0.11 * b Next y Next x NGrayValue = Abs(Temp(0, 0) + 2 * Temp(0, 1) + Temp(0, 2) - Temp(2, 0) - 2 * Temp(2, 1) - Temp(2, 2)) If NGrayValue 255 Then NGrayValue = 255 dbits(i - 1, j - 1, 0) = NGrayValue dbits(i - 1, j - 1, 1) = NGrayValue dbits(i - 1, j - 1, 2) = NGrayValue Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub 垂直方向滤波的方法与水平方向锐化滤波的方法基本一致,只是将模板修改如下: 垂直方向滤波的界面如下: 垂直锐化滤波按钮对应的代码如下: Private Sub cmdVSharpFilter_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim Temp(2, 2) As Integer Dim x As Integer, y As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight - 2 ' 边界像素直接不要了 DestImWidth = SourceImWidth - 2 ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的垂直锐化滤波 For i = 1 To SourceImHeight - 2 ' 边界像素不处理 For j = 1 To SourceImWidth - 2 NGrayValue = 0 For x = 0 To 2 For y = 0 To 2 r = sbits(i + 1 - x, j + 1 - y, 0) g = sbits(i + 1 - x, j + 1 - y, 1) b = sbits(i + 1 - x, j + 1 - y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x, y) = 0.3 * r + 0.59 * g + 0.11 * b Next y Next x NGrayValue = Abs(Temp(0, 0) + 2 * Temp(1, 0) + Temp(2, 0) - Temp(0, 2) - 2 * Temp(1, 2) - Temp(2, 2)) If NGrayValue 255 Then NGrayValue = 255 dbits(i - 1, j - 1, 0) = NGrayValue dbits(i - 1, j - 1, 1) = NGrayValue dbits(i - 1, j - 1, 2) = NGrayValue Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub
3205 次阅读|0 个评论
Visual Basic与图像处理19
prrsw 2012-10-12 14:47
Visual Basic与图像处理19
Visual Basic 与图像处理 ( 三 ) 4 、中值滤波 前面讲的均值滤波器等都是属于线性滤波器,容易带来图像细节的模糊,本节要讲的是一种非线性滤波器:中值滤波。中值滤波最早是有 J. W. Jukey 在 1971 年提出的一种一维信号处理技术,后来被拓展应用到二维图像处理技术之中。 所谓中值滤波,就是采用一个含有奇数个点的滑动窗口,将当前点灰度值(一般指窗口的中心点)用窗口中各点灰度值的中值来替代。由于一般采用的是奇数窗口,因此只要将各个像素点的灰度等级进行大小排序,中间的竖直就是中值;如果窗口是偶数(特殊情况)。就用排序后中间两个元素的均值来表示中值。 用前面均值滤波直接用线性方程来计算新的灰度值不一样的是,中值滤波首先要对当前窗口内的所有像素点的灰度值进行排序,一般有选择排序和冒泡排序两种方法,具体可参照相关的 Visual Basic 基础教程中的讲解,这里就不详细解释了。 中值滤波器窗口的形状有多种,有一维也有二维的,对于二维情况,中值滤波器的窗口形状和尺度对滤波结果影响也很大,因此需要根据实际的要求来选择滤波器的形状和尺寸。本例中示范一种最简单的 3 × 3 中值滤波,其余的情况读者可根据本例提供的相关代码适当修改得到,本例的运行界面如下: 3 × 3 中值滤波按钮对应的代码如下: Private Sub cmd33MedianFilter_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim x As Integer, y As Integer Dim Temp(8) As Integer, TV As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的中值滤波 For i = 1 To SourceImHeight - 2 ' 边界像素不处理 For j = 1 To SourceImWidth - 2 NGrayValue = 0 For x = 0 To 2 For y = 0 To 2 r = sbits(i + 1 - x, j + 1 - y, 0) g = sbits(i + 1 - x, j + 1 - y, 1) b = sbits(i + 1 - x, j + 1 - y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x * 3 + y) = 0.3 * r + 0.59 * g + 0.11 * b Next y Next x ' 选择排序 For x = 0 To 7 For y = x + 1 To 8 If Temp(x) Temp(y) Then TV = Temp(x) Temp(x) = Temp(y) Temp(y) = TV End If Next y Next x dbits(i, j, 0) = Temp(4) dbits(i, j, 1) = Temp(4) dbits(i, j, 2) = Temp(4) Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub
3601 次阅读|0 个评论
Visual Basic与图像处理18
prrsw 2012-10-12 09:33
Visual Basic与图像处理18
Visual Basic 与图像处理(三) 3 、特殊模板 有时候利用一些特殊的模板可以达到意外的效果,利用均值滤波类似的方法,只是改变模板就可能达到特殊的效果,这里以下面一个模板为例,可以达到边缘检测的效果: 下面是系统的 运行界面: 特殊模板按钮对应的代码如下: Private Sub cmdSpecialFilter_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim Temp(2, 2) As Integer Dim x As Integer, y As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的特殊模板滤波 For i = 1 To SourceImHeight - 2 ' 边界像素不处理 For j = 1 To SourceImWidth - 2 NGrayValue = 0 For x = 0 To 2 For y = 0 To 2 r = sbits(i + 1 - x, j + 1 - y, 0) g = sbits(i + 1 - x, j + 1 - y, 1) b = sbits(i + 1 - x, j + 1 - y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x, y) = 0.3 * r + 0.59 * g + 0.11 * b Next y Next x NGrayValue = Temp(0, 1) + Temp(1, 0) + Temp(2, 1) + Temp(1, 2) - 4 * Temp(1, 1) If NGrayValue 0 Then NGrayValue = 0 If NGrayValue 255 Then NGrayValue = 255 dbits(i, j, 0) = NGrayValue dbits(i, j, 1) = NGrayValue dbits(i, j, 2) = NGrayValue Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub
2660 次阅读|0 个评论
Visual Basic与图像处理17
prrsw 2012-10-12 08:17
Visual Basic与图像处理17
Visual Basic 与图像处理 ( 三 ) 2 、高斯滤波 高斯滤波与均值滤波方法接近,只是采用的模板不一样,均值滤波的模板中每个像素点权重是相等,而高斯滤波认为当前像素点的权重最大,距离越远的像素点在滤波结果中所占的权重越小,最常见的 3 × 3 高斯滤波器模板如下: 之所以称为高斯滤波,是因为上述模板是采样二维高斯函数得到的,下图就是 3 × 3 高斯滤波的运行界面: 3 × 3 高斯滤波按钮对应的代码如下: Private Sub cmd33GaussianFilter_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim Temp(2, 2) As Integer Dim x As Integer, y As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的高斯滤波 For i = 1 To SourceImHeight - 2 ' 边界像素不处理 For j = 1 To SourceImWidth - 2 For x = 0 To 2 For y = 0 To 2 r = sbits(i + 1 - x, j + 1 - y, 0) g = sbits(i + 1 - x, j + 1 - y, 1) b = sbits(i + 1 - x, j + 1 - y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x, y) = 0.3 * r + 0.59 * g + 0.11 * b Next y Next x NGrayValue = Temp(0, 0) + Temp(0, 1) * 2 + Temp(0, 2) + Temp(1, 0) * 2 + Temp(1, 1) * 4 + Temp(1, 2) * 2 + Temp(2, 0) + Temp(2, 1) * 2 + Temp(2, 2) dbits(i, j, 0) = NGrayValue / 16 dbits(i, j, 1) = NGrayValue / 16 dbits(i, j, 2) = NGrayValue / 16 Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub 5 × 5 高斯滤波器模板如下: 其滤波方法与前面介绍的方法一致,该部分运行界面如下: 5 × 5 高斯滤波按钮对应的代码如下: Private Sub cmd55GaussianFilter_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim Temp(4, 4) As Integer Dim x As Integer, y As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的高斯滤波 For i = 2 To SourceImHeight - 3 ' 边界像素不处理 For j = 2 To SourceImWidth - 3 NGrayValue = 0 For x = 0 To 4 For y = 0 To 4 r = sbits(i + 2 - x, j + 2 - y, 0) g = sbits(i + 2 - x, j + 2 - y, 1) b = sbits(i + 2 - x, j + 2 - y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x, y) = 0.3 * r + 0.59 * g + 0.11 * b Next y Next x NGrayValue = Temp(0, 0) + Temp(0, 1) * 2 + Temp(0, 2) * 4 + Temp(0, 3) * 2 + Temp(0, 4) ' 第一行 NGrayValue = NGrayValue + Temp(1, 0) * 2 + Temp(1, 1) * 4 + Temp(1, 2) * 8 + Temp(1, 3) * 4 + Temp(1, 4) * 2 ' 第二行 NGrayValue = NGrayValue + Temp(2, 0) * 4 + Temp(2, 1) * 8 + Temp(2, 2) * 16 + Temp(2, 3) * 8 + Temp(2, 4) * 4 ' 第三行 NGrayValue = NGrayValue + Temp(3, 0) * 2 + Temp(3, 1) * 4 + Temp(3, 2) * 8 + Temp(3, 3) * 4 + Temp(3, 4) * 2 ' 第四行 NGrayValue = NGrayValue + Temp(4, 0) + Temp(4, 1) * 2 + Temp(4, 2) * 4 + Temp(4, 3) * 2 + Temp(4, 4) ' 第五行 dbits(i, j, 0) = NGrayValue / 100 dbits(i, j, 1) = NGrayValue / 100 dbits(i, j, 2) = NGrayValue / 100 Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub
2903 次阅读|0 个评论
Visual Basic与图像处理16
热度 1 prrsw 2012-10-11 18:54
Visual Basic与图像处理16
Visual Basic 与图像处理 ( 三 ) 从本节开始介绍图像增强的知识,在图像的传送和转换,比如复制、扫描等过程中总要造成图像品质的下降,因此需要提供一定的方法对这些降质的图像进行改善处理。常用的一种方法就是将图像中感兴趣的特征进行选择性的突出,减弱次要信息,当然这种方法虽然能提高图像的可读性,但是改善后的图像不一定逼近原始图像,比如突出目标的轮廓、衰减图像的各种噪声,通常把这类方法称为图像增强技术。当然还有一类方法也能改善图像的质量,称为图像复原,这里先不进行阐述。 图像增强的方法通常可分为两大类,第一类就是在空间域内对图像的像素点灰度值直接进行处理,比如区域内进行均值、中值滤波;第二类方法是在频域内进行滤波,即将图像变换到频域,在频域内对图像进行某种运算增强,再变换回空间域,这部分内容在以后也会讲述到。本章讲述的是第一类方法。 1、 均值滤波 均值滤波是图像增强中最简单的一类,主要是为了减少图像中的噪声信号,常见的有 3 × 3 , 5 × 5 均值滤波,高斯模板滤波等,首先从最简单的 3 × 3 均值滤波开始讲起。 所谓 3 × 3 均值滤波就是将原图像中每个人像素点的灰度值与其八邻域的八个像素点的灰度值累加,将求得的平均值作为新图像中该像素点的均值,可以用下面的简单模板表示这种滤波方法: 均值滤波中要考虑的是边界像素的处理,最简单的一种处理方法是边界像素不作相应的处理,当然也有其他的处理方法,比如在图像周围补充一些像素,本例中采用边界像素直接复制的方法,系统的运行界面如下: 3 × 3 均值滤波按钮对应的代码如下: Private Sub cmdGrayEqua_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim Temp(2, 2) As Integer Dim x As Integer, y As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的均值滤波直方图统计 For i = 1 To SourceImHeight - 2 ' 边界像素不处理 For j = 1 To SourceImWidth - 2 NGrayValue = 0 For x = 0 To 2 For y = 0 To 2 r = sbits(i + 1 - x, j + 1 - y, 0) g = sbits(i + 1 - x, j + 1 - y, 1) b = sbits(i + 1 - x, j + 1 - y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x, y) = 0.3 * r + 0.59 * g + 0.11 * b NGrayValue = NGrayValue + Temp(x, y) Next y Next x dbits(i, j, 0) = NGrayValue / 9 dbits(i, j, 1) = NGrayValue / 9 dbits(i, j, 2) = NGrayValue / 9 Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub 5 × 5 均值滤波方法与此类似,只是将模板扩大,改变其中的几句话即可,代码如下: Private Sub cmd55MeanFilter_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim Temp(4, 4) As Integer Dim x As Integer, y As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的均值滤波直方图统计 For i = 2 To SourceImHeight - 3 ' 边界像素不处理 For j = 2 To SourceImWidth - 3 NGrayValue = 0 For x = 0 To 4 For y = 0 To 4 r = sbits(i + 2 - x, j + 2 - y, 0) g = sbits(i + 2 - x, j + 2 - y, 1) b = sbits(i + 2 - x, j + 2 - y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x, y) = 0.3 * r + 0.59 * g + 0.11 * b NGrayValue = NGrayValue + Temp(x, y) Next y Next x dbits(i, j, 0) = NGrayValue / 25 dbits(i, j, 1) = NGrayValue / 25 dbits(i, j, 2) = NGrayValue / 25 Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub 对应的软件运行界面如下: 从上述两个图可以看出,无论是 3 × 3 均值滤波,还是 5 × 5 均值滤波,都在一定程度上使得图像变得模糊,也就是说在滤除噪声信号的同时,也损失了图像的部分细节信号。
2904 次阅读|1 个评论
Visual Basic与图像处理15
prrsw 2012-10-11 16:12
Visual Basic 与图像处理(三) 通过动态数组减少 Point 方法的使用次数,可以有效的提高图像处理的速度, C 系列语言之所以在处理图像的时候速度较快,其实很大原因就是因为是从内存中直接读取图像数据。如果能完全放弃使用 Point 和 PSet 方法,直接获得图像数据,那么 Visual Basic 与 C 系列语言处理图像的速度并无明显差异,一种方法是直接读取文件的方法,对于初学者,还是不建议使用,因此没有必要,如果需要可以直接参考文件读取和写入的方法即可。这里推荐一种通过 API 函数直接完成图像读写的方法,主要涉及这样几个 API 函数: (1) 从 PictureBox 读入图像数据到数组中,用于取代 Point 方法。 Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long (2) 将数组数据直接映射到 PictureBox 中,用于取代 PSet 方法。 Declare Function SetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long (3) 获得控件句柄 Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long 为了便于对图像进行操作,自定义了一个数据类型 BIPMAP ,定义如下: Type BITMAP bmType As Long bmWidth As Long bmHeight As Long bmWidthBytes As Long bmPlanes As Integer bmBitsPixel As Integer bmBits As Long End Type 上述 API 函数定义和自定义变量都放置于标准模块之中。 在获取图像数据时,首先定义一个整型变量用于存放 PictureBox 中的图像句柄,然后调用 GetBitmapBits 函数获取图像数据,存放于数组中,需要注意的时, Visual Basic 获得的数据都默认为彩色图像,因此定义数组大小时,需要按照真彩色图像进行处理。将读取图像按钮代码做调整,使得读入图像的同时就获得图像数据,代码调整如下: Private Sub cmdReadImage_Click() Dim strFileName As String CDialog1.Filter = "bmp|*.bmp|jpg|*.jpg|gif|*.gif" ' 文件过滤,可以打开上述三类图像 CDialog1.ShowOpen If CDialog1.FileName "" Then strFileName = CDialog1.FileName PicSource.Picture = LoadPicture(strFileName) End If SourceImHeight = PicSource.Height SourceImWidth = PicSource.Width Dim tSBmpInfo As BITMAP Dim hSrcBmp As Long Dim x As Integer, y As Integer hSrcBmp = PicSource.Image.Handle ' 注意,这里只能使用 image ,而不能使用 picture ' 获得位图信息 Call GetObject(hSrcBmp, Len(tSBmpInfo), tSBmpInfo) ReDim ImageArray(1 To tSBmpInfo.bmWidthBytes, 1 To SourceImHeight) As Byte ' 获得源图与目标图二进制位 Call GetBitmapBits(hSrcBmp, tSBmpInfo.bmWidthBytes * tSBmpInfo.bmHeight, ImageArray(1, 1)) ' 注意起点是 (1,1) ReDim sbits(SourceImHeight - 1, SourceImWidth - 1, 2) As Byte ' 通过下面的转换,将数组转置为习惯的格式,当然也可以不转置,只是后面使用起来比较麻烦 For y = 1 To SourceImHeight For x = 1 To SourceImWidth sbits(y - 1, x - 1, 2) = ImageArray((x - 1) * 4 + 1, y) sbits(y - 1, x - 1, 1) = ImageArray((x - 1) * 4 + 2, y) sbits(y - 1, x - 1, 0) = ImageArray((x - 1) * 4 + 3, y) Next x Next y End Sub 在处理程序时,同样定义动态数组用于存储目标图像数据,处理完成后再利用 SetBitmapBits 一次性将数组显示于目标的 PictureBox 控件之中,同样以直方图均衡化为例,对应的“直方图均衡化按钮代码调整如下: Private Sub cmdGrayEqua_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim Hist(255) As Long ' 存放原直方图统计结果 Dim P(255) As Single ' 存放原直方图概率 Dim PA(255) As Single ' 存放原直方图累计分布概率 Dim Map(255) As Single ' 存放灰度等级映射结果 Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 ' 图像的直方图统计 For i = 0 To SourceImHeight - 1 For j = 0 To SourceImWidth - 1 r = sbits(i, j, 0) g = sbits(i, j, 1) b = sbits(i, j, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 GrayValue = 0.3 * r + 0.59 * g + 0.11 * b Hist(GrayValue) = Hist(GrayValue) + 1 Next j Next i P(0) = Hist(0) / SourceImHeight / SourceImWidth Map(0) = 255 * P(0) For i = 1 To 255 P(i) = P(i - 1) + Hist(i) / SourceImHeight / SourceImWidth Map(i) = 255 * P(i) Next i ' 图像的直方图均衡化 For i = 0 To SourceImHeight - 1 For j = 0 To SourceImWidth - 1 r = sbits(i, j, 0) g = sbits(i, j, 1) b = sbits(i, j, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 GrayValue = 0.3 * r + 0.59 * g + 0.11 * b dbits(i, j, 0) = Map(GrayValue) dbits(i, j, 1) = Map(GrayValue) dbits(i, j, 2) = Map(GrayValue) Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub 初学者可能觉得本例比较复杂,一下子跳跃的跨度较大,但只要熟悉下来,流程还是基本一致的,后面在做一些实例时,可能感觉更为明显。前面在做点运算时,每次计算只需要使用到一个点,本章开始讲述图像的增强,一般需要同时涉及到多个像素点,这里提出的数组存储数据的方法也便于这样的操作。 通过比对可以发现,采用本例的方法以后, Visual Basic 处理图像的速度就跟平时见到的 C 系列语言处理的图像的速度基本一致,如果想要进一步提高处理速度,就需要研究算法方面的内容,这个就不在这里进行讨论了。
2774 次阅读|0 个评论
Visual Basic与图像处理14
prrsw 2012-10-11 15:15
Visual Basic与图像处理14
Visual Basic 与图像处理(三) Visual Basic 做图像处理其实一直未专业人员所不屑,很大原因在于其速度不快,甚至很多初步接触图像处理的学生也是提到就皱眉,其实 Visual Basic 做图像处理理论研究并不是那么一无是处,尤其对于初学者,毕竟容易上手,能够快速的进行研究,还是有很多优点的,这里就不再辩论这个问题。 前文已经讲述了点运算的知识,也结合了一些实例来阐述 Visual Basic 进行图像处理的方法,从本节开始逐步进入稍微复杂的问题,但首先要解决的就是常说的处理速度的问题。本节还是从直方图均衡化那个实例下手,从实例分析来逐步提高运行速度。 引起 Visual Basic 图像处理速度慢的很大原因是前面说的非常多的两个函数 Point 和 PSet 方法,一个是从控件中取颜色点,一个是往控件界面上设置颜色点,无论取点还是设置点,都是要调用显存的,这显然会降低速度。在前面的直方图均衡化程序中,在灰度统计的时候遍历了一次图像,挨个取颜色点的值,而在后面设置颜色点,得到目标图像的时候,又得遍历一次图像,我们能想到的第一个办法就是尽量减少使用 Point 和 PSet 的次数。前面提到过,图像的本质就是一个矩阵,而矩阵在程序设计中往往是用数组进行表示的,如果在第一次取点以后就把得到的数据放置于数组中,那么后文再次调用这些数据时,就可以直接调用这个数组,可以有效的提高程序运行速度。 本例基于上述思路,采用数组来存储图像数据,由于在程序运行前,图像数据大小还不知道,因此需要采用动态数组来实现数据的存储,运行界面与前面的一样,如下图所示: 首先在窗口模块中定位了两个窗口级别的动态数组 SourceImData() 和 DestImData() ,在得到图像的高度和宽度以后就可以定义数组的大小,通过数组可以减少使用 Point 方法的次数,直方图均衡化按钮对应的代码调整如下: Private Sub cmdGrayEqua_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim Hist(255) As Long ' 存放原直方图统计结果 Dim P(255) As Single ' 存放原直方图概率 Dim PA(255) As Single ' 存放原直方图累计分布概率 Dim Map(255) As Single ' 存放灰度等级映射结果 Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim SourceImData(SourceImHeight - 1, SourceImWidth - 1) As Integer ReDim DestImData(DestImHeight - 1, DestImWidth - 1) As Integer ' 图像的直方图统计 For i = 0 To SourceImHeight - 1 For j = 0 To SourceImWidth - 1 PixelValue = PicSource.Point(j, i) r = PixelValue Mod 256 g = (PixelValue \ 256) Mod 256 b = PixelValue \ 65536 ' 插入图像处理的过程,对 r, g, b 进行处理 GrayValue = 0.3 * r + 0.59 * g + 0.11 * b SourceImData(i, j) = GrayValue Hist(GrayValue) = Hist(GrayValue) + 1 Next j Next i P(0) = Hist(0) / SourceImHeight / SourceImWidth Map(0) = 255 * P(0) For i = 1 To 255 P(i) = P(i - 1) + Hist(i) / SourceImHeight / SourceImWidth Map(i) = 255 * P(i) Next i ' 图像的直方图均衡化 For i = 0 To SourceImHeight - 1 For j = 0 To SourceImWidth - 1 NGrayValue = Map(SourceImData(i, j)) PicDest.PSet (j, i), RGB(NGrayValue, NGrayValue, NGrayValue) Next j Next i End Sub 如果细心对比,会发现通过这样一个改变,已经能稍微提高该程序的运行速度了,当然还是没有达到理想的要求,后面会继续讨论。
2551 次阅读|0 个评论
Visual Basic与图像处理13
热度 1 prrsw 2012-10-11 13:52
Visual Basic 与图像处理 ( 二 ) 到直方图均衡化结束,常见的点运算处理已经结束,适当总结两句,点运算是图像处理的入门,所谓入门也就是只有你跨过这个门槛才能算这个行业的人,但并不是你掌握了点运算就掌握了多少知识,而是希望学生通过学习这一章的知识知道图像处理的流程以及基本的实现方法。 本章所使用的方法以及涉及的理论并不复杂,也很容易掌握,但并不表示用处不大,比如本章涉及的阈值分割往往是检测类的图像分析所必须要涉及的一个步骤,只是在本章中阈值是自行设定的,而在具体实际问题时,需要采用一定的数学方法完成阈值的自动计算。我在上课时一直跟学生说,图像处理说到底也只是一个工具,分析具体问题时还是得到数学、信息等方面的知识,但是如果工具都掌握不好,也就无法解决实际的问题了。 即使是点处理可能也需要适当变通,前一段有个博士生在研究中发现直方图均衡化与 Photoshop 中的“自动对比度”菜单效果不一致,而在研究中发现利用“自动对比度”可以完成其论文研究中的其中一个步骤,就想找出这种操作的原理,我们找了好多本书都没有找到,而最后意外的在某个网页中发现了其中的原理介绍,顺利解决了这个问题。我想说的是,学无止境,并不是说你学会了一个东西就能解决所有问题,只有在不断研究之中,发现新的问题,解决新的问题,才能逐步提高自己的能力。 我在这里更新这个博客的目的,也是希望给初步进入这个研究领域的学生或者研究者提供一点点细微的帮助,希望大家一切都能够顺利。第一章终于结束了,我是一边编程,一边写这个文档,多多少少会出现一些问题,希望看到的同仁们不要笑话。
2332 次阅读|1 个评论
Visual Basic与图像处理12
prrsw 2012-10-11 13:40
Visual Basic与图像处理12
Visual Basic 与图像处理 ( 二 ) 9 、直方图均衡化 直方图均衡化也成为灰度均衡,是点运算较为复杂的一种,其基本原理是对图像中像素个数较多的灰度区域进行范围拓宽,而对像素较少的灰度区域,即在图像画面中不起主要作用的灰度值进行归并。一般在图像比较或者分割之前进行直方图均衡,可以使图像具有较为一致格式。比如由于光照条件使得同一背景图像有较大的亮度反差就可以利用直方图均衡化进行亮度调整。 设 f(i, j), g(i, j) 分别为原图像和处理后的图像,图像的灰度等级变换范围为 ,直方图均衡化可以按照以下的步骤进行: (1) 原图像直方图统计结果为 Hist ; (2) 求原图像直方图的灰度分布概率,记作 p ; (3) 计算元图像各个灰度等级的累计分布概率,记作 PA ,显然 PA =0, PA =1 ; (4) 进行直方图均衡化新的灰度值计算,将新的灰度值存放于映射 Map 中,其中: Map =255 × PA 。 从上述步骤来看,要做直方图均衡化,首先要计算直方图统计结果,然后再得到每个灰度等级对应的新的灰度等级,最后才能完成直方图均衡化操作。程序的实现与前面的类似,这里不在详细讲述,该例的运行界面如下图所示: 直方图均衡化按钮对应的代码如下: Private Sub cmdGrayEqua_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim Hist(255) As Long ' 存放原直方图统计结果 Dim P(255) As Single ' 存放原直方图概率 Dim PA(255) As Single ' 存放原直方图累计分布概率 Dim Map(255) As Single ' 存放灰度等级映射结果 Dim NGrayValue As Integer ThresholdValue = Val(txtThreshold) ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ' 图像的直方图统计 For i = 0 To SourceImHeight - 1 For j = 0 To SourceImWidth - 1 PixelValue = PicSource.Point(j, i) r = PixelValue Mod 256 g = (PixelValue \ 256) Mod 256 b = PixelValue \ 65536 ' 插入图像处理的过程,对 r, g, b 进行处理 GrayValue = 0.3 * r + 0.59 * g + 0.11 * b Hist(GrayValue) = Hist(GrayValue) + 1 Next j Next i P(0) = Hist(0) / SourceImHeight / SourceImWidth Map(0) = 255 * P(0) For i = 1 To 255 P(i) = P(i - 1) + Hist(i) / SourceImHeight / SourceImWidth Map(i) = 255 * P(i) Next i ' 图像的直方图均衡化 For i = 0 To SourceImHeight - 1 For j = 0 To SourceImWidth - 1 PixelValue = PicSource.Point(j, i) r = PixelValue Mod 256 g = (PixelValue \ 256) Mod 256 b = PixelValue \ 65536 ' 插入图像处理的过程,对 r, g, b 进行处理 GrayValue = 0.3 * r + 0.59 * g + 0.11 * b NGrayValue = Map(GrayValue) PicDest.PSet (j, i), RGB(NGrayValue, NGrayValue, NGrayValue) Next j Next i End Sub
2481 次阅读|0 个评论
Visual Basic与图像处理11
prrsw 2012-10-11 11:30
Visual Basic与图像处理11
Visual Basic 与图像处理 ( 二 ) 8 、灰度拉伸 灰度拉伸是将图像中不同灰度等级按照预定的方式进行拉伸,从实质上来说灰度拉伸是灰度线性变换的一种延伸,当然也不完全等同于灰度线性变换,而是对灰度等级进行分段,然后分别进行线性变换。灰度拉伸可以用下面的函数表达式表示: 式中 (x1, y1) 和 (x2, y2) 是灰度拉伸中两个转折点的坐标,如下图中的 A , B 两点。 相比于线性变换,灰度拉伸可以更灵活更改图像的灰度,可以根据需要选择性的变换某个灰度等级范围内的像素点。在本例中,采用图形化控制的方法设定上述两个转折点,这里涉及了一个平时称为“橡皮筋”的技术,在网络上有很多介绍橡皮筋技术的文章,在 Visual Basic 中利用 DrawMode 属性可以非常便捷的实现所谓的橡皮筋效果。在本例中专门放置了一个用于设定转折点的 PictureBox 控件,在 PictureBox 中鼠标左键按下时,选择第一个转折点,然后鼠标拖动到第二个转折点松开鼠标左键,当鼠标左键再次按下时,将 PictureBox 清空,重新设置转折点。整个系统的运行界面如下: 其中灰度拉伸按钮对应的代码如下: Private Sub cmdGrayStrech_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim Map(255) As Integer ' 采用映射模式计算拉伸后的灰度 Dim k(2) As Single, t(2) As Integer ' 存放三条直线的斜率和截距 Dim NGrayValue As Integer ThresholdValue = Val(txtThreshold) ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ' 第一条直线斜率和截距 k(0) = (255 - StartPY - 0) / (StartPX - 0) t(0) = 0 For i = 0 To StartPX Map(i) = i * k(0) + t(0) Next i ' 第二条直线斜率和截距 k(1) = ((255 - EndPY) - (255 - StartPY)) / (EndPX - StartPX) t(1) = (255 - EndPY) - k(1) * EndPX For i = StartPX + 1 To EndPX Map(i) = i * k(1) + t(1) Next i ' 第二条直线斜率和截距 k(2) = (255 - (255 - EndPY)) / (255 - EndPX) t(2) = (255 - EndPY) - k(2) * EndPX For i = EndPX + 1 To 255 Map(i) = i * k(2) + t(2) Next i ' 图像的灰度拉伸变换 For i = 0 To SourceImHeight - 1 For j = 0 To SourceImWidth - 1 PixelValue = PicSource.Point(j, i) r = PixelValue Mod 256 g = (PixelValue \ 256) Mod 256 b = PixelValue \ 65536 ' 插入图像处理的过程,对 r, g, b 进行处理 GrayValue = 0.3 * r + 0.59 * g + 0.11 * b NGrayValue = Map(GrayValue) PicDest.PSet (j, i), RGB(NGrayValue, NGrayValue, NGrayValue) Next j Next i End Sub 这里涉及的数组映射也是经常使用的一种技术,可以有效的提高软件的运行速度。 实现橡皮筋效应及转折点设置的代码分为三个部分,首先是鼠标左键按下,确定第一个转折点,然后是鼠标拖动时,实现的橡皮筋效果,最后鼠标左键抬起时,确定第二个转折点。第一个转折点和第二个转折点分别用窗口级变量来表示,分别是 StartPX, StartPY, EndPX, EndPY ,以便于后面计算直线的斜率和截距。 鼠标左键按下的代码如下: Private Sub PicDraw_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) If Button = vbLeftButton Then ' 将 PictureBox 清空 PicDraw.Cls ' 画个边框 PicDraw.Line (0, 0)-(0, 255), RGB(255, 255, 255) PicDraw.Line (0, 0)-(255, 0), RGB(255, 255, 255) PicDraw.Line (0, 255)-(255, 255), RGB(255, 255, 255) PicDraw.Line (255, 0)-(255, 255), RGB(255, 255, 255) ' 鼠标左键已经按下 Flag = True StartPX = X StartPY = Y txtFirst = "(" Str(StartPX) ", " Str(255 - StartPY) ")" Label8.Left = StartPX Label8.Top = StartPY Label8.Caption = txtFirst PicDraw.Line (0, PicDraw.Height - 1)-(StartPX, StartPY), RGB(255, 255, 0) PicDraw.Line (StartPX, PicDraw.Height - 1)-(StartPX, StartPY), RGB(255, 0, 0) PicDraw.Line (0, StartPY)-(StartPX, StartPY), RGB(255, 0, 0) EndPX = X EndPY = Y End If End Sub 由于 DrawMode 模式是异或,因此设置颜色时需要根据互补色。 鼠标拖动的代码如下,注意观察如何实现橡皮筋效果: Private Sub PicDraw_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) If Flag = True Then ' 擦去前面的线条 PicDraw.Line (StartPX, StartPY)-(EndPX, EndPY), RGB(255, 255, 0) ' 由于取的是异或,为了画蓝色的线,将前面两个量满置 EndPX = X EndPY = Y ' 画上新的线条,实现橡皮筋效果 PicDraw.Line (StartPX, StartPY)-(EndPX, EndPY), RGB(255, 255, 0) End If End Sub 鼠标左键抬起的时候,确定第二个转折点,代码如下: Private Sub PicDraw_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single) EndPX = X EndPY = Y txtSecond = "(" Str(EndPX) ", " Str(255 - EndPY) ")" Label9.Left = EndPX Label9.Top = EndPY Label9.Caption = txtSecond PicDraw.Line (EndPX, EndPY)-(PicDraw.Width - 1, 0), RGB(255, 255, 0) PicDraw.Line (PicDraw.Width - 1, EndPY)-(EndPX, EndPY), RGB(255, 0, 0) PicDraw.Line (EndPX, 0)-(EndPX, EndPY), RGB(255, 0, 0) Flag = False End Sub 需要注意的是 DrawMode 设置为 Xor Pen 表示在同一位置画同样的线时,将把原来的线擦除,从而可以实现橡皮筋效应,在窗体窗体时对 DrawMode 进行设置,代码如下: Private Sub Form_Load() PicDraw.DrawMode = 7 ' vbXorPen End Sub
3085 次阅读|0 个评论
Visual Basic与图像处理10
prrsw 2012-10-11 07:56
Visual Basic与图像处理10
Visual Basic 与图像处理(二) 7 、灰度窗口变换 灰度窗口变换是选择窗口中部分灰度等级的一种点运算方式,其实现方法与阈值变换类似。选择一定的灰度等级范围,在该范围内的灰度值保持不变,小于该范围下限的灰度值设置为 0 (黑色),而大于该范围上限的灰度值设置为 255 (白色)。灰度窗口变换可以用下面的函数形式进行表达: 这里的 L 表示窗口范围的下限, H 表示窗口范围的上限。 灰度窗口变换的在平时用途较为广泛,比如利用灰度窗口变换可以消除较暗或者较亮的背景,在软件设计时,该例与阈值变换非常相似,同样由两个 PictureBox 组成,另外在窗口中放置了两个文本框,分别用于存放窗口范围的下限和上限。本例的运行界面如下图所示 : 窗口变换按钮对应的代码如下: Private Sub cmdWindowTrans_Click() Dim i As Integer, j As Integer Dim PixelValue As Long Dim r As Integer, g As Integer, b As Integer Dim GrayValue As Integer Dim NGrayValue As Integer Dim L As Integer, H As Integer ThresholdValue = Val(txtThreshold) ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth L = Val(txtL) H = Val(txtH) ' 图像的窗口变换 For i = 0 To SourceImHeight - 1 For j = 0 To SourceImWidth - 1 PixelValue = PicSource.Point(j, i) r = PixelValue Mod 256 g = (PixelValue \ 256) Mod 256 b = PixelValue \ 65536 ' 插入图像处理的过程,对 r, g, b 进行处理 GrayValue = 0.3 * r + 0.59 * g + 0.11 * b If GrayValue L Then NGrayValue = 0 ElseIf GrayValue H Then NGrayValue = 255 Else NGrayValue = GrayValue End If PicDest.PSet (j, i), RGB(NGrayValue, NGrayValue, NGrayValue) Next j Next i End Sub
2882 次阅读|0 个评论

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-5-18 23:42

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部