精华内容
下载资源
问答
  • 它是一款容易使用的图像编辑、图像处理软件,上仅具有常见的图像裁剪、图像旋转、图像拼接、灰度处理、马赛克、消除红眼等等基本的图像处理功能,而且还有强大的特色功能。 吉大图像处理软件功能: 可以加载图片、...
  • Linux图形图像处理软件

    千次阅读 2014-07-10 11:43:42
    Linux图形图像处理软件 来源: 作者:otto  一说到Linux,多数朋友可能会认为它虽然功能强大,但其命令行形式的界面使用起来太不方便了。其实,现在的Linux不仅具有如同Windows 9x一样漂亮易用的图形界面,...

    Linux图形图像处理软件

    来源: 作者:otto
        一说到Linux,多数朋友可能会认为它虽然功能强大,但其命令行形式的界面使用起来太不方便了。其实,现在的Linux不仅具有如同Windows 9x一样漂亮易用的图形界面,而且在图形界面下运行的应用程序也不少,本文将对Linux下的图形图像处理软件做些介绍,笔者所使用的Linux是Turbo Linux 6.0简体中文版。

      Linux下的图形图像处理软件比较丰富,从功能上可以把它们大致分为以下几类:图像处理工具,如GIMP等;绘图工具,如XPaint、Kpaint等;图像浏览工具,如gtk_see、Compupic、电子眼ee、gqview及Kview等;图标制作工具,如Kicon等;抓图工具,如KsnapShot等;三维模型设计软件,如AC3D、IRIT、PIXCON等等。也许有的朋友会问,很多软件Linux光盘中都没有,到哪里才能下载啊?笔者建议朋友们可以首先到ftp://sunsite.unc.edu/pub/Linux/apps/graphics/等比较大型的Linux软件下载站点去看看,这些地方能够找到大量的图形图像应用软件,另外本文后面还给出了一些软件的具体下载站点。

      图像处理工具

      Linux下的图像处理工具中,比较有名的要数GIMP了。GIMP是GNU图像处理程序(GNU Image Manipulation Program)的缩写,它是一个完全免费的自由软件包,适用于对图像进行各种艺术处理。GIMP的功能相当强大,它可以作为一个简单的绘图程序来使用,也可以作为一个高质量的图像处理软件来使用,它还有图像格式转换等功能。GIMP具有良好的可扩展性,它支持带插件参数的高级脚本接口,对每件工作——无论是最简单的任务,还是最复杂的图像处理过程,都可以很容易地用脚本来描述。由于其功能相当强大,GIMP被誉为Linux下处理图像的法宝,是Linux下的Photoshop。

      用户想要得到GIMP,可到GIMP的专门网站http://www.gimp.org去下载,这里不仅有GIMP的最新版本,还有GIMP的开发库、详细的软件使用手册等,不过都是英文的。需要下载的文件是gimp-1.0.4.tar.bz2。

      一、安装步骤

      1.运行命令:# cp gimp-1.0.4.tar.bz2 /tmp,将gimp-1.0.4.tar.bz2拷到/tmp目录下。

      2.运行命令:# bunzip2 gimp-1.0.4.tar.bz2,解压缩这个文件,/tmp目录下会生成一个叫gimp-1.0.4.tar的文件。

      3.运行命令:# tar xvf gimp-1.0.4.tar,将会在/tmp目录下生成一个叫做gimp-1.0.4的子目录,GIMP的所有文件就存放在这个目录下。

      4.运行命令:# cd gimp-1.0.4,进入到GIMP程序所在的目录,准备配置和编译它,此时最好阅读一下Install文件来了解安装的步骤和注意事项。

      5.连续运行下面三个命令:# ./configure、#make、# make install,它将会对GIMP进行配置和编译,如果在编译时出现问题,可以参考Install文件来查找原因。

      6.安装成功后,运行/usr/local/bin/gimp即可启动GIMP。

      GIMP的界面比Photoshop简洁,启动时只有一个看起来和Photoshop很相似的工具栏(图1)。只有当我们打开图像文件,并用鼠标右键单击图像时才会弹出一系列的选单选项(图2)。

      图1

      二、GIMP软件特点

      1.全套的绘图工具,包括笔刷(Brush)、铅笔(Pencil)、喷枪(AirBrush)等;

      2.平板式内存管理,能够处理的图像尺寸大小只受磁盘自由空间限制;

      图2

      3.支持各种常见图像格式,包括: gif、jpg、png、xpm、tiff、tga、mpeg、ps、pdf、pcx、bmp等;

      4.过程数据库允许从外部程序调用内部的GIMP函数;

      5.无限次的Undo/Redo(仅受磁盘空间的限制);

      6.支持旋转、缩放、裁剪及反转等变形工具;

      7.具有多种选择工具,如矩形、椭圆、自由、模糊、曲线及智能;

      8.插件功能允许用户任意增加新的文件格式及新的效果滤镜,现已提供了100多个插件。

      另外,GIMP对Web图片设计也有不错的支持,同时还提供了一个屏幕抓图工具——屏幕快照,效果不错。

      绘图工具

      一、XPaint

      XPaint是X11所带的一个彩色图像编辑工具,与Windows中的画图程序功能相似,支持编辑各种图像格式,包括PPM、XBM、TIFF等。XPaint的用户界面如图3所示,界面从功能上被分成两块区域,一块是工具区,用于选择当前绘画要进行的操作;另一块是绘图区,用于创建/修改图像。每个绘图窗口允许拥有自己的调色板和模式集。

      图3

      XPaint对显示模式有所依赖,在存储图像的时候将会把图像调整为当前的显示模式(例如,在灰色模式环境下打开一幅彩色图像,重新存盘时会被存储为灰色图像)。XPaint的使用方法比较简单,相信朋友们一学就会。

      二、KPaint

      KPaint是KDE提供的一个与XPaint类似的绘图工具,其用户界面如图4所示。

      图4

      KPaint支持所有常见的图像文件格式,用户可以选择不同的笔、刷子或形状来绘制和修改图像,KPaint的调色板的功能比较不错。由于KPaint与XPaint和Windows画图的使用方法差不多,这里就不再详细介绍了。

      图像浏览工具

      与Windows一样,Linux下的图像浏览工具也非常丰富,下面介绍其中几款比较常用的软件。

      一、电子眼ee

      “电子眼ee”是一个在GNOME窗口环境下浏览图像的软件,它是随GNOME软件包一块分发的。当正确安装好GNOME后,在主选单的图形栏上就会出现电子眼的图标。电子眼可以浏览bmp、tif、gif、xpm等格式的图像文件,使用方法非常简单。图5是电子眼的文件操作界面,用户可以选择一次装入多个文件,并可预览图像。电子眼也支持对图像进行一些基本的编辑操作,如灰度控制、放大、缩小和旋转等。

      图5

      电子眼虽然功能比较简单,但仍不失为一个好的图像浏览工具。

      二、GQview

      GQview也是一个在GNOME窗口环境下浏览图像的软件。其功能和使用方法与电子眼差不太多,只是要更直观一些。GQview的用户界面如图6所示,左边是选单条、工具栏、目录列表及图形文件列表,右边是图像浏览区,在图像文件列表中选择文件后,就可以在右边区域进行浏览了。

      图6

      GQview自身的图像编辑功能比较弱,但它支持调用外部的图像处理软件,除了GIMP、电子眼等软件外,用户还可根据需要让GQview启动其他编辑软件。

      三、Compupic

      Compupic是由Photodex公司开发的一个共享软件,它是一个相当优秀的图像浏览工具,读者朋友可以到www.Photodex.com去下载最新版本。笔者下载的文件名为compupic-4_6_1022-i386-Linux_tar,用tar解压后会生成一个compupic-4_6_1022-i386-Linux的目录,在该目录下运行./ compupic -install即可完成安装。安装完毕后,运行$ compupic或$ /usr/local/bin/compupic,就可以启动Compupic。

      Compupic的用户界面(图7)很像Windows下的应用程序,其目录树部分几乎就是Windows资源管理器的翻版,使用起来非常直观。Compupic支持浏览各种格式的图像文件,甚至包括ICO文件及Adobe的PSD文件,它还可查看WAV和MPEG等多媒体文件,以及浏览文本文件及二进制文件。

      图7

      图标制作工具

      下面主要介绍一下KDE自带的图标编辑器Kiconedit,朋友们还可以到互联网上找到不少其他的图标制作工具。

      Kiconedit的用户界面如图8所示,其窗口分为五个区域:主工具栏、绘图工具栏、栅格、状态栏及调色板。主工具栏用于创建、打开文件,以及裁减、复制、放大、缩小等操作;绘图工具栏列出了一些绘图工具,如画笔、填充,以及选择绘画形状等;栅格是制作图标的地方。此外,Kiconedit还有比较详尽的联机帮助,这对初学者很有好处。

      图8

      总的来说,Kiconedit是一个相当不错的图标制作工具,使用它可以很方便地为自己的程序创建漂亮的图标。

      抓图工具

      KSnapshot是KDE环境下的一个简单的图像捕捉工具,它能捕获整个桌面或者单个窗口的图像,并能以各种文件格式保存该图像,其用户界面如图9所示。在KDE的中文环境下,KSnapshot的界面是中文的,因此使用起来很容易上手,本文的所有图片都是用它抓下来的。KSnapshot具有自启动功能,能够将在抓图之前选择的窗口显示到桌面的最前面,另外,它还有延迟功能,允许延迟一段时间抓图,用户可以借此机会来调整好窗口的布局,很象照相机的延迟拍摄功能。

      图9

      三维模型设计软件

      Linux下的三维模型设计软件还是比较丰富的,但因为这类软件开发起来比较复杂,因此自由软件并不太多,朋友们可到http://metalab.unc.edu等网站去搜寻一下。下面主要介绍一下AC3D,下载地址为:http://www.comp.lancs.ac.uk/computing/users/andy/ac3d/

      download/ac3dlxredhatsw2.tgz。下载完毕后,用tar将ac3dlxredhatsw2.tgz解包,无需安装,在X Window下直接运行其中的ac3d命令即可启动AC3D。

      AC3D是一个多种平台下的三维模型设计软件,有Windows、SGI、Linux等多种版本,在各种平台下其文件格式是互相兼容的。

      AC3D的用户界面如图10所示,怎么样,是不是有点儿眼熟?的确,AC3D的用户界面同3DS很相似,并且其建模功能也类似于3DS。

      图10

      用户界面共有四个视图窗口,四个窗口可以同时显示,也可以只单独显示其中的一个。AC3D具有的一些特点包括:支持隐藏/显示物体,以便在编辑复杂场景时提高速度;内嵌有快速OpenGL 3D渲染器,能很快得到渲染结果;提供多达七个位置的灯光;支持24位色的调色板;支持实时渲染的材质;支持多种文件格式的输入/输出,如3DS、DXF、VRML、RIB等等;具有二维造型功能。此外,AC3D还支持插件。

      比较遗憾的是,从上述网站下载的AC3D只是一个免费的演示版,其功能比正式版要少,如果要获得正式版,就必须向开发商购买。
    展开全文
  • 常用图像处理软件

    千次阅读 2019-10-30 12:01:00
    1、 最著名的开源图像软件:GIMP。 开发语言:C GIMP号称Linux下的PhotoShop,总观其工程,确实达到了PhotoShop早期版本的功能。三大利器:选区、图层、蒙板一应俱全,滤镜也非常丰富,支持插件。缺点就是界面不...

    1、 最著名的开源图像软件:GIMP。

          开发语言:C

          GIMP号称Linux下的PhotoShop,总观其工程,确实达到了PhotoShop早期版本的功能。三大利器:选区、图层、蒙板一应俱全,滤镜也非常丰富,支持插件。缺点就是界面不美观,用户体验差,执行速度在Windows下慢(Linux下不清楚)。

          官方网址为:http://www.gimp.org/

          源码下载:因其源码体积过大,请大家直接到其官网下载。

          对应的可执行文件可在官方网站下载。可以很方便的查看源代码。

    2、 微软曾支持过的"开源"图像软件:Paint.NET

          开发语言:C#

      Paint.Net是Windows 平台上的一个图像和照片处理软件,早期定位于MSPaint的免费替代软件,支持图层、通道、无限制的历史记录、特效和许多实用工具,在3.3版本之前开源,之后由于种种原因放弃开源。其界面看起来有点像Photoshop,执行速度上也不快。

          官方网站:http://www.getpaint.net/

          源码下载:http://files.cnblogs.com/Imageshop/Paint.net.rar

     3、一个响当当的图像开源软件:ImageEditor 

         开发语言:Java

         一个用JAVA开发的图像处理软件,具有图层、选区、滤镜以及其他一些工具。整体来说较上述两个软件稍次一些,但依旧强劲。提供了很多独特的滤镜算法,工具箱中的透视变形工具很给力,是用JAVA开发图像值得借鉴的好代码。算法的执行速度一般。

          官方网址为:http://www.jhlabs.com/

          源码下载:http://files.cnblogs.com/Imageshop/jhlabs.rar

          源码中包含对应的EXE文件,但需要机器上安装了JAVA运行环境方可正常运行。

    4、优秀的图像操作类库: CxImage

         开发语言:C++

         它可以快捷地存取、显示、转换各种图像,自带了较多图像模式转换算法,以及一些滤镜,是VC使用者最为常用的图像类库。

         官方网址:http://www.codeproject.com/KB/graphics/cximage.aspx

         源码下载:http://files.cnblogs.com/Imageshop/cximage.rar

    5、国人的开源图像处理软件: Imagestone

         开发语言:C++ 

         ImageStone是一套功能强大的C++图像处理库,能读写JPG、GIF、PNG、TIFF、TGA等多种图像文件,有多达100多中预定义的特效。其算法很多是取自GIMP的代码,如果认为GIMP的代码过于复杂,可以从该软件中很轻松分解出你需要的部分。

          官方网址为:http://www.codeproject.com/KB/graphics/ImageStone.aspx

          源码下载:http://files.cnblogs.com/Imageshop/ImageStone.rar

    6、基于AForge.NET的开源软件:iplab

         开发语言:C#

         和CxImage似乎是一个作者,包含了很多滤镜,也有一些图像识别上常用的分析方法。

         官方网址为:http://www.codeproject.com/KB/GDI-plus/Image_Processing_Lab.aspx 

         源码下载:http://www.codeproject.com/KB/GDI-plus/Image_Processing_Lab/iplab_src.zip

    7、一款VB值得爱好者学习的软件:iBmp

          开发工具:VB6

          虽然在提供的算法上没有什么太多值得说明的地方,但在图像缩放的坐标计算、偏移、图像导航器方面的代码确实值得大家学习。

          官方网址为:http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=42376&lngWId=1

          源码下载:http://files.cnblogs.com/Imageshop/iBMP.rar

    8、图像编码解码的利器:FreeImage、ImageMagick

          开发语言:C

          FreeImage 是一款免费的、开源的、跨平台(Windows 、Linux 和Mac OS X )的,支持20 多种图像类型的(如BMP 、JPEG 、GIF 、PNG 、TIFF 等)图像处理库。其最大优点就是采用插件驱动型架构,具有快速、灵活、简单易用的特点,得到了广泛使用。

         ImageMagick是一套功能强大、稳定而且免费的工具集和开发包,可以用来读、写和处理超过89种基本格式的图片文件,包括流行的TIFF、JPEG、GIF、 PNG、PDF以及PhotoCD等格式。利用ImageMagick,你可以对图片进行改变大小、旋转、锐化、减色或增加特效等操作,并将操作的结果以相同格式或其它格式保存。

     

    9、其他的一些开源软件:

        (1) PhotoSprite:一个国产的用C#开发的类似PHOTOSHOP的软件(太抬举他了),用到了很多图形算法,新手可以参考。

         下载地址:http://files.cnblogs.com/Imageshop/PhotoSprite.rar

         (2)FilterExplorer: 一个小的VC写的图像处理代码,有一些比较好的滤镜代码。

         下载地址:http://files.cnblogs.com/Imageshop/FilterExplorer.rar

     

     

     

    展开全文
  • 基于OpenCVSharp的图像处理软件

    万次阅读 多人点赞 2019-01-08 19:32:47
    目录 ...目的在于方便图像处理人员在具体编写OpenCV程序前,提前能够对图像进行简单处理,进而帮助开发人员分析该如何对图像进行处理。 使用C#对界面和逻辑进行开发。界面开发的工具有很多,例如使...

    目录

    1 任务与目的

    2 方案总体设计

    3 C#界面设计

    4 OpenCVSharp功能实现

    5 打包与运行

    6 总结


    1 任务与目的

    本次任务是设计一个能够实现OpenCV部分功能的图像处理软件。目的在于方便图像处理人员在具体编写OpenCV程序前,提前能够对图像进行简单处理,进而帮助开发人员分析该如何对图像进行处理。

    使用C#对界面和逻辑进行开发。界面开发的工具有很多,例如使用C++与QT进行开发。OpenCV针对C++有专用的库,与QT也有良好的支持,但是开发时间与C#比较长,并且生成的应用程序安装包较大。不光是OpenCV相关的库文件需要打包进应用程序安装包,还有QT界面相关的库文件也需要添加。过大的应用程序相当于简单的功能,两者并不协调,所以使用C#进行界面逻辑的开发更为快捷方便。

    使用OpenCVSharp实现图像处理功能。在目前针对C#的计算机视觉库主要有两种,EmguCV和OpenCVSharp。EmguCV的优势在于不仅仅提供了计算机视觉函数接口并且提供了一系列界面控件接口,但目前只支持OpenCV1的书写风格。但是是通过把C++封装成动态链接库在C#中调用,这样在修改算法的过程中就会非常的不方便,封装DLL的时候也比较麻烦。对于OpenCVSharp的工具,从名字就可以看出其是OpenCV提供给C#的接口。OpenCVSharp是OpenCV的.NET wrapper,它比EmguCV更接近于原始的OpenCV。网上常见的免费版EmguCV则是GUN协议,任何发表都需要至少公布你的源代码,相比之下OpenCVSharp则是相对温和多的LGUN协议,对商业应用友好(基本上相当于BSD)。OpenCVSharp提供了OpenCV和OpenCV2两种书写风格。因此设计使用OpenCVSharp进行图像处理的功能实现。

    以下是方案对比表:

                                                                                    表1-1 不同方案对比表

    开发方案对比

    C#

    C++&QT

    原始OpenCV

    \

    界面开发速度较快

    库文件调用方便

    安装包大

    商业友好

    EmguCV

    界面开发速度快

    库文件调用不方便

    安装包较大

    商业不友好

    \

    OpenCVSharp

    界面开发速度快

    库文件调用方便

    安装包较小

    商业友好

    \

     

    因此选用C#与OpenCVSharp搭配在VS2017下进行图像处理软件的开发。


    2 方案总体设计

     设计的应用程序用于进行简单的图像处理功能,因此考虑包含以下功能:

                                                                                      表2-1 设计功能表

    功能

    基本方法

    打开图片

    C#中OpenFileDialog控件

    保存图片

    C#中SaveFileDialog控件

    开\关摄像头

    OpenCVSharp的VideoCapture方法

    图像处理功能选择

    C#中ListBox控件

    图像处理

    OpenCVSharp的各类图像处理方法

    图像显示

    C#中PictureBox控件

    图像处理步骤队列

    C#中ListBox控件

    消息通知

    C#中TextBox控件

    图像处理功能参数调整

    C#中NumericUpDown控件

    要实现以上各项功能,除了使用表中第二列所示的基本方法外,还需要将C#控件与OpenCVSharp中的各类图像处理方法紧密联系。

    设计将图像处理功能选择ListBox与OpenCVSharp的各类图像处理方法一一对应,而方法的各项参数统一存放在一个多维数组里,C#中NumericUpDown控件在执行图像处理功能参数调整的时候通过调取这个多维数组,来实现修改参数的功能。用户通过点击选择图像处理功能,对图像处理步骤队列ListBox中的元素进行添加,程序内部通过判断这些元素及其排列,选择对应的OpenCVSharp图像处理方法对图像进行处理。

    这些步骤的简化示意图如下:

     

                                                                               图2-1 设计相关示意图

    以下将详细介绍C#界面的设计和OpenCVSharp功能实现。


     

    3 C#界面设计

     

    在一个C#窗体中添加需要的控件,主要包括:按键(Button)、列表(ListBox)、图像显示窗(PictureBox)、文字显示窗(TextBox)等。对各控件属性进行设置,例如按键名称、功能选择列表元素等。

    程序由个人独立开发,设计一个独特的图标和应用程序名称,由本人命名为“sa蛋OpenCV试验器”。

    显示效果如图所示:

                                                                                  图3-1 主C#窗体控件布局效果

    布局与界面效果设计完成后,对各个控件进行逻辑编程。

    • 打开图片

    打开图片功能与摄像头功能同时开启并不方便图像显示,因此当摄像头开启时,点击“打开图片”按键不弹出文件选择界面,同时在“通知消息显示”中通知应先关闭摄像头再打开图片。打开文件功能由C#的OpenFileDialog类实现,相关程序如下图所示:

                                                                           图3-2 打开图片功能部分程序图

    选择要打开的文件后,OpenFileDialog类的FileName变量会返回文件地址。

    • 保存图片

    保存图片功能实现与打开图片步骤类似。

    • 打开摄像头

    点击“打开摄像头”按钮后,会触发此按钮的点击事件,从而执行如下程序:

    private void button3_Click(object sender, EventArgs e)
    
    {
    
    camera = new VideoCapture(0);
    
    cameraopen = true;

    VideoCapture为OpenCVSharp所提供的摄像头类,可以方便快捷地开启摄像头;cameraopen为自定义的bool型标识符,由于表示摄像头是否已开启。

    • 关闭摄像头

    关闭摄像头代码如下:

    private void button4_Click(object sender, EventArgs e)
    
    {
    
    if(cameraopen == true)
    
    {
    
      camera.Dispose();
    
      cameraopen = false;

    使用VideoCapture类的Dispose()方法即可关闭摄像头。

    • 使用说明

    点击“使用说明”按钮弹出一个消息显示窗体,此窗体由C#的MessageBox类实现,程序如下:

    private void button7_Click(object sender, EventArgs e)
    
    {
    
    MessageBox.Show("此为传感器理论与研究方法……",  "使用说明", MessageBoxButtons.OK);
    
    }

    MessageBox类的Show()方法的第一个参数为显示消息内容,第二个参数为窗体标题,第三个参数为窗体添加的按键,此窗体添加一个确定按钮。

    显示效果如图:

                                                                图3-3 使用说明功能

    • 刷新图像

    点击“刷新图像”后,执行以下程序:

    image1 = new Mat(my_imagesource);
    
    image2 = new Mat();
    
    image2 = myOPENCV_run(image1, image2);//运行

    主要通过myOPENCV_run()方法将打开的图像进行处理,此方法为自定义方法,用于执行OpenCVSharp图像处理功能,在第四节详细说明。

    • 图像显示

    点击“图像显示”后,执行以下程序:

    pictureBox1.Image = image2.ToBitmap();

    MAT类的ToBitmap()方法,作用是将一个MAT图转换为正常可以显示的图片,传给PictureBox进行显示。

    • 通知消息显示

    通知消息使用TextBox控件,通知消息需要能够翻阅,即每次通知消息都是接着已有的通知信息进行添加。程序如下:

    textBox1.AppendText("\r\n图片刷新完成!");
    
    textBox1.SelectionStart = this.textBox1.TextLength;
    
    textBox1.ScrollToCaret();

    TextBox类的AppendText()方法用于添加文字信息,SelectionStart用来将光标移至最后,使用ScrollToCaret()方法使TextBox始终保持显示最新一行的文字。

    • 功能选择列表

    点击左侧列表进行功能选择,首先弹出对应功能的参数设置界面,设计第二个窗体用于设置参数。如下图所示:

                                                                                图3-4 设置参数界面

    每项功能都对应有四个参数,定义一个数组用于存放这些参数,数组的行下标就是对应的枚举过的参数名。数组定义如下:

    public static int[,] myOPENCV_value = new int[60 , 4]; //用于存放各方法中的参数

    当点击确定时,数组的参数被修改为设定值,同时此窗体,将选择的元素添加进图像处理列表。

    • 图像处理步骤列表

    图像处理需要按使用者选择的功能顺序进行执行,是一个有序的操作。重新定义一个数组专门用来存放使用者选择出来的功能参数,与功能列表定义的数组不同的是,前者要多一列用来存放功能对应的序号,其他均相同。这样的作用是,可以对数组存放序号的列进行依次检索,从而能够按使用者选择的顺序进行执行图像处理功能。此数组定义如下:

    public  int[,] myOPENCV_runlist = new int[20, 5];//运行步骤列表,与myOPENCV_value不同的是,运行步骤限定为20步,列的第一个元素存放运行功能序号

    点击图像处理步骤列表的元素,同样弹出参数设置窗口。这时将窗体的删除按钮等显现,实现对已经选择功能的删除功能。删除或中间插入其他功能都需要对列表元素进行添加或删除,与此同时也要对数组的行元素进行删除或插入。使用循环即可完成上述步骤。

     

    至此已大致介绍完实现此软件界面使用的逻辑和方法,下面介绍录入应用程序的部分OpenCVSharp图像处理功能实现。

     

     

    4 OpenCVSharp功能实现

    初始设想能够实现60种以上的基本图像处理功能,由于设计开发的时间有限,个人的能力水平也有待提高,因此只添加了较为基础的27种功能。

    功能名称与OpenCVSharp中对应方法如下表:

                                                                              表4-1 录入的OpenCVSharp功能名称表

    功能      

    OpenCVSharp中对应方法(函数)名称

    颜色空间转换

    CvtColor

    方框滤波

    BoxFilter

    均值滤波

    Blur

    高斯滤波

    GaussianBlur

    中值滤波

    MedianBlur

    双边滤波

    BilateralFilter

    膨胀

    Dilate

    腐蚀

    Erode

    高级形态学变换

    MorphologyEx

    漫水填充

    FloodFill

    尺寸放大

    PyrUp

    尺寸缩小

    PyrDown

    尺寸调整

    Resize

    固定阈值化

    Threshold

    边缘检测CANNY

    Canny

    边缘检测SOBEL

    Sobel

    边缘检测LAPLACIAN

    Laplacian

    边缘检测SCHARR

    Scharr

    图像快速增强

    ConvertScaleAbs

    图像融合

    AddWeighted

    霍夫标准变换

    HoughLines

    霍夫累计概率变换

    HoughLinesP

    霍夫圆变换

    HoughCircles

    重映射

    Remap

    仿射变换

    WarpAffine

    直方图均衡化

    EqualizeHist

    人脸识别

    DetectFace

     

    上表功能均单独进行了实现,通过检索图像处理步骤数组myOPENCV_runlist时,依次判断其每一行的第一个元素,其中存放的为对应功能的序号(序号为已经枚举化的功能名称)。通过依次识别出的序号,一步一步执行对应的图像处理功能,这一步骤由一个for循环加一个大型的switch-case实现,部分代码如下:

    for (int i = 0 ; i< listBox2.Items.Count ; i++)
    
    {
    
        switch((myOPENCV)myOPENCV_runlist[i,0])
    
               {
    
                 case myOPENCV.cvt_color: // myOPENCV为一个自定义枚举类型

    执行对应图像处理方法时,将数组保存的参数带入,即可实现功能的参数使用。


     

    5 打包与运行

     

    在VS2017中使用Microsoft Visual Studio Installer Project生成一个安装包工程,在工程中对使用到的库文件、图片、数据等进行添加。如下图所示:

                                                                                               图5-1 安装包工程

    在项目属性中设置安装文件名称、快捷方式、文件夹等。进行完上述步骤后即可生成一个安装包文件。由于添加了使用到的所有库文件,因此其他Windows用户安装完后,大部分也可以正常使用。

    安装后虽然能够正常使用,但并不符合“小巧便捷”的最初设想。因此使用Enigma Virtual Box打包软件将安装后的程序目录进行再次打包,生成一个可以直接执行无需安装的exe文件。如下图所示:

     

                                                                                     图5-2 可直接执行的exe文件

     

    至此设计基本完成,下面对软件进行简单测试:

    1. 点击“打开图片”按钮,选择一张图片后即可在图像显示区域显示选择的图片。
    2. 左侧列表点击选择“人脸识别”,弹出参数设置界面,直接点击“确定”即可添加“人脸识别”功能至右侧列表。
    3. 点击“刷新图片”按钮,即可观察是否成功识别出图像中的人脸。
    4. 观察下方通知栏显示的通知消息,与操作步骤一一对应。

    效果图如下:

     

                                                                                        图5-3 测试人脸识别

     

    需要注意的是,部分功能对输入的图像有严格要求,例如“直方图均衡化”需要输入一个单通道的图像,这时需要先进行“颜色空间转换”,将图像转换为灰度图后再进行下一步操作。若不按要求添加功能,多数会导致程序出错。

     


    6 总结

     

    至此project已经暂时完成,其实还有很多的设想都没来得及实现,比如如何在程序出错时不会崩溃、如何优化参数设置界面、如何添加更多更有用的图像处理功能。

    展开全文
  • 常见医疗扫描图像处理步骤

    万次阅读 多人点赞 2017-06-09 15:02:13
    常见医疗扫描图像处理步骤一 下载必要包skimage需要更新到最新0.13版本,否则会报错,ImportError: cannot import name label。sudo pip install scikit-image -U -i https://pypi.tuna.tsinghua.edu.cn/simple二 ...

    常见医疗扫描图像处理步骤


    一 下载必要包

    skimage需要更新到最新0.13版本,否则会报错,ImportError: cannot import name label。

    sudo pip install scikit-image  -U -i  https://pypi.tuna.tsinghua.edu.cn/simple

    二 数据格式

    2.1 dicom

    当前医疗竞赛官方数据集格式 data-science-bowl-2017。数据列表如下:
    这里写图片描述
    后缀为 .dcm。
    每个病人的一次扫描CT(scan)可能有几十到一百多个dcm数据文件(slices)。可以使用 python的dicom包读取,读取示例代码如下:

    dicom.read_file('/data/lung_competition/stage1/7050f8141e92fa42fd9c471a8b2f50ce/498d16aa2222d76cae1da144ddc59a13.dcm')

    一般使用其pixl_array数据

    slices = [dicom.read_file(os.path.join(folder_name,filename)) for filename in os.listdir(folder_name)]
    slices = np.stack([s.pixel_array for s in slices])

    2.2 mhd格式

    mhd格式是另外一种数据格式,来源于(LUNA2016)[https://luna16.grand-challenge.org/data/]。每个病人一个mhd文件和一个同名的raw文件。如下:

    这里写图片描述

    一个mhd通常有几百兆,对应的raw文件只有1kb。mhd文件需要借助python的SimpleITK包来处理。SimpleITK 示例代码如下:

    import SimpleITK as sitk
    itk_img = sitk.ReadImage(img_file) 
    img_array = sitk.GetArrayFromImage(itk_img) # indexes are z,y,x (notice the ordering)
    num_z, height, width = img_array.shape        #heightXwidth constitute the transverse plane
    origin = np.array(itk_img.GetOrigin())      # x,y,z  Origin in world coordinates (mm)
    spacing = np.array(itk_img.GetSpacing())    # spacing of voxels in world coor. (mm)

    需要注意的是,SimpleITK的img_array的数组不是直接的像素值,而是相对于CT扫描中原点位置的差值,需要做进一步转换。转换步骤参考 SimpleITK图像转换

    2.3 查看CT扫描文件软件

    一个开源免费的查看软件 mango
    这里写图片描述

    三 dicom格式数据处理过程

    3.1 处理思路

    首先,需要明白的是医学扫描图像(scan)其实是三维图像,使用代码读取之后开源查看不同的切面的切片(slices),可以从不同轴切割

    这里写图片描述

    如下图展示了一个病人CT扫描图中,其中部分切片slices

    这里写图片描述

    其次,CT扫描图是包含了所有组织的,如果直接去看,看不到任何有用信息。需要做一些预处理,预处理中一个重要的概念是放射剂量,衡量单位为HU(Hounsfield Unit),下表是不同放射剂量对应的组织器官

    这里写图片描述

    Hounsfield Unit = pixel_value * rescale_slope + rescale_intercept

    一般情况rescale slope = 1, intercept = -1024。
    灰度值是pixel value经过重重LUT转换得到的用来进行显示的值,而这个转换过程是不可逆的,也就是说,灰度值无法转换为ct值。只能根据窗宽窗位得到一个大概的范围。 pixel value经过modality lut得到Hu,但是怀疑pixelvalue的读取出了问题。dicom文件中存在(0028,0106)(0028,0107)两个tag,分别是最大最小pixel value,可以用来检验你读取的pixel value 矩阵是否正确。
    LUT全称look up table,实际上就是一张像素灰度值的映射表,它将实际采样到的像素灰度值经过一定的变换如阈值、反转、二值化、对比度调整、线性变换等,变成了另外一 个与之对应的灰度值,这样可以起到突出图像的有用信息,增强图像的光对比度的作用。
    首先去除超过 -2000的pixl_array,CT扫描边界之外的像素值固定为-2000(dicom和mhd都是这个值)。第一步是设定这些值为0,当前对应为空气(值为0)

    slices[slices == -2000] = 0

    上表中肺部组织的HU数值为-500,但通常是大于这个值,比如-320、-400。挑选出这些区域,然后做其他变换抽取出肺部像素点。抽取出这些特征,最后将其存储为ndarray的npy格式,供给卷积神经网络。

    3.2 先载入必要的包

    # -*- coding:utf-8 -*-
    '''
    this script is used for basic process of lung 2017 in Data Science Bowl
    '''
    
    import glob
    import os
    import pandas as pd
    import SimpleITK as sitk
    
    import numpy as np # linear algebra
    import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
    import skimage, os
    from skimage.morphology import ball, disk, dilation, binary_erosion, remove_small_objects, erosion, closing, reconstruction, binary_closing
    from skimage.measure import label,regionprops, perimeter
    from skimage.morphology import binary_dilation, binary_opening
    from skimage.filters import roberts, sobel
    from skimage import measure, feature
    from skimage.segmentation import clear_border
    from skimage import data
    from scipy import ndimage as ndi
    import matplotlib
    #matplotlib.use('Agg')
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d.art3d import Poly3DCollection
    import dicom
    import scipy.misc
    import numpy as np

    DICOM是医学图像中标准文件,这些文件包含了诸多的
    元数据信息(比如像素尺寸,每个维度的一像素代表真实世界里的长度)。如下代码是载入一个扫描面,包含了多个切片(slices),我们仅简化的将其存储为python列表。数据集中每个目录都是一个扫描面集(一个病人)。有个元数据域丢失,即Z轴方向上的像素尺寸,也即切片的厚度 。所幸,我们可以用其他值推测出来,并加入到元数据中。

    # Load the scans in given folder path
    def load_scan(path):
        slices = [dicom.read_file(path + '/' + s) for s in os.listdir(path)]
        slices.sort(key = lambda x: int(x.ImagePositionPatient[2]))
        try:
            slice_thickness = np.abs(slices[0].ImagePositionPatient[2] - slices[1].ImagePositionPatient[2])
        except:
            slice_thickness = np.abs(slices[0].SliceLocation - slices[1].SliceLocation)
    
        for s in slices:
            s.SliceThickness = slice_thickness
    
        return slices

    3.3 像素转换为HU单元

    有些扫描面有圆柱形扫描边界,但是输出图像是正方形。边界之外的像素值固定为-2000,。第一步是设定这些值为0,当前对应为空气(值为0)。然后回到HU单元,乘以rescale比率并加上intercept(存储在扫描面的元数据中)。

    def get_pixels_hu(slices):
        image = np.stack([s.pixel_array for s in slices])
        # Convert to int16 (from sometimes int16), 
        # should be possible as values should always be low enough (<32k)
        image = image.astype(np.int16)
        # Set outside-of-scan pixels to 0
        # The intercept is usually -1024, so air is approximately 0
        image[image == -2000] = 0
    
    
    # Convert to Hounsfield units (HU)
        for slice_number in range(len(slices)):
    
            intercept = slices[slice_number].RescaleIntercept
            slope = slices[slice_number].RescaleSlope
    
            if slope != 1:
                image[slice_number] = slope * image[slice_number].astype(np.float64)
                image[slice_number] = image[slice_number].astype(np.int16)
    
            image[slice_number] += np.int16(intercept)
    
        return np.array(image, dtype=np.int16)

    可以查看病人的扫描HU值分布情况

    first_patient = load_scan(INPUT_FOLDER + patients[0])
    first_patient_pixels = get_pixels_hu(first_patient)
    plt.hist(first_patient_pixels.flatten(), bins=80, color='c')
    plt.xlabel("Hounsfield Units (HU)")
    plt.ylabel("Frequency")
    plt.show()

    这里写图片描述

    3.4重新采样

    不同扫描面的像素尺寸、粗细粒度是不同的。这不利于我们进行CNN任务,我们可以使用同构采样。
    一个扫描面的像素区间可能是[2.5,0.5,0.5],即切片之间的距离为2.5mm。可能另外一个扫描面的范围是[1.5,0.725,0.725]。这可能不利于自动分析。
    常见的处理方法是从全数据集中以固定的同构分辨率重新采样。如果我们选择,将所有的东西采样为1mmx1mmx1mm像素,我们可以使用3D卷积网络

    def resample(image, scan, new_spacing=[1,1,1]):
        # Determine current pixel spacing
        spacing = map(float, ([scan[0].SliceThickness] + scan[0].PixelSpacing))
        spacing = np.array(list(spacing))
        resize_factor = spacing / new_spacing
        new_real_shape = image.shape * resize_factor
        new_shape = np.round(new_real_shape)
        real_resize_factor = new_shape / image.shape
        new_spacing = spacing / real_resize_factor
    
        image = scipy.ndimage.interpolation.zoom(image, real_resize_factor, mode='nearest')
    
        return image, new_spacing

    现在重新取样病人的像素,将其映射到一个同构分辨率 1mm x1mm x1mm。

    pix_resampled, spacing = resample(first_patient_pixels, first_patient, [1,1,1])

    输出肺部扫描的3D图像方法

    def plot_3d(image, threshold=-300):
    
        # Position the scan upright, 
        # so the head of the patient would be at the top facing the camera
        p = image.transpose(2,1,0)
    
        verts, faces = measure.marching_cubes(p, threshold)
        fig = plt.figure(figsize=(10, 10))
        ax = fig.add_subplot(111, projection='3d')
        # Fancy indexing: `verts[faces]` to generate a collection of triangles
        mesh = Poly3DCollection(verts[faces], alpha=0.1)
        face_color = [0.5, 0.5, 1]
        mesh.set_facecolor(face_color)
        ax.add_collection3d(mesh)
        ax.set_xlim(0, p.shape[0])
        ax.set_ylim(0, p.shape[1])
        ax.set_zlim(0, p.shape[2])
        plt.show()

    打印函数有个阈值参数,来打印特定的结构,比如tissue或者骨头。400是一个仅仅打印骨头的阈值(HU对照表)

    plot_3d(pix_resampled, 400)

    这里写图片描述

    3.5 输出一个病人scans中所有切面slices

    def plot_ct_scan(scan):
        '''
                plot a few more images of the slices
        :param scan:
        :return:
        '''
        f, plots = plt.subplots(int(scan.shape[0] / 20) + 1, 4, figsize=(50, 50))
        for i in range(0, scan.shape[0], 5):
            plots[int(i / 20), int((i % 20) / 5)].axis('off')
            plots[int(i / 20), int((i % 20) / 5)].imshow(scan[i], cmap=plt.cm.bone)

    此方法的效果示例如下:

    这里写图片描述

    3.6 定义分割出CT切面里面肺部组织的函数

    def get_segmented_lungs(im, plot=False):
    
        '''
        This funtion segments the lungs from the given 2D slice.
        '''
        if plot == True:
            f, plots = plt.subplots(8, 1, figsize=(5, 40))
        '''
        Step 1: Convert into a binary image.
        '''
        binary = im < 604
        if plot == True:
            plots[0].axis('off')
            plots[0].set_title('binary image')
            plots[0].imshow(binary, cmap=plt.cm.bone)
    
        '''
        Step 2: Remove the blobs connected to the border of the image.
        '''
        cleared = clear_border(binary)
        if plot == True:
            plots[1].axis('off')
            plots[1].set_title('after clear border')
            plots[1].imshow(cleared, cmap=plt.cm.bone)
    
        '''
        Step 3: Label the image.
        '''
        label_image = label(cleared)
        if plot == True:
            plots[2].axis('off')
            plots[2].set_title('found all connective graph')
            plots[2].imshow(label_image, cmap=plt.cm.bone)
        '''
        Step 4: Keep the labels with 2 largest areas.
        '''
        areas = [r.area for r in regionprops(label_image)]
        areas.sort()
        if len(areas) > 2:
            for region in regionprops(label_image):
                if region.area < areas[-2]:
                    for coordinates in region.coords:
                           label_image[coordinates[0], coordinates[1]] = 0
        binary = label_image > 0
        if plot == True:
            plots[3].axis('off')
            plots[3].set_title(' Keep the labels with 2 largest areas')
            plots[3].imshow(binary, cmap=plt.cm.bone)
        '''
        Step 5: Erosion operation with a disk of radius 2. This operation is
        seperate the lung nodules attached to the blood vessels.
        '''
        selem = disk(2)
        binary = binary_erosion(binary, selem)
        if plot == True:
            plots[4].axis('off')
            plots[4].set_title('seperate the lung nodules attached to the blood vessels')
            plots[4].imshow(binary, cmap=plt.cm.bone)
        '''
        Step 6: Closure operation with a disk of radius 10. This operation is
        to keep nodules attached to the lung wall.
        '''
        selem = disk(10)
        binary = binary_closing(binary, selem)
        if plot == True:
            plots[5].axis('off')
            plots[5].set_title('keep nodules attached to the lung wall')
            plots[5].imshow(binary, cmap=plt.cm.bone)
        '''
        Step 7: Fill in the small holes inside the binary mask of lungs.
        '''
        edges = roberts(binary)
        binary = ndi.binary_fill_holes(edges)
        if plot == True:
            plots[6].axis('off')
            plots[6].set_title('Fill in the small holes inside the binary mask of lungs')
            plots[6].imshow(binary, cmap=plt.cm.bone)
        '''
        Step 8: Superimpose the binary mask on the input image.
        '''
        get_high_vals = binary == 0
        im[get_high_vals] = 0
        if plot == True:
            plots[7].axis('off')
            plots[7].set_title('Superimpose the binary mask on the input image')
            plots[7].imshow(im, cmap=plt.cm.bone)
    
        return im

    此方法每个步骤对图像做不同的处理,效果如下:

    这里写图片描述

    3.7 肺部图像分割

    为了减少有问题的空间,我们可以分割肺部图像(有时候是附近的组织)。这包含一些步骤,包括区域增长和形态运算,此时,我们只分析相连组件。
    步骤如下:

    • 阈值图像(-320HU是个极佳的阈值,但是此方法中不是必要)
    • 处理相连的组件,以决定当前患者的空气的标签,以1填充这些二值图像
    • 可选:当前扫描的每个轴上的切片,选定最大固态连接的组织(当前患者的肉体和空气),并且其他的为0。以掩码的方式填充肺部结构。
    • 只保留最大的气袋(人类躯体内到处都有气袋)
    def largest_label_volume(im, bg=-1):
        vals, counts = np.unique(im, return_counts=True)
        counts = counts[vals != bg]
        vals = vals[vals != bg]
        if len(counts) > 0:
            return vals[np.argmax(counts)]
        else:
            return None
    def segment_lung_mask(image, fill_lung_structures=True):
    
        # not actually binary, but 1 and 2. 
        # 0 is treated as background, which we do not want
        binary_image = np.array(image > -320, dtype=np.int8)+1
        labels = measure.label(binary_image)
    
        # Pick the pixel in the very corner to determine which label is air.
        #   Improvement: Pick multiple background labels from around the patient
        #   More resistant to "trays" on which the patient lays cutting the air 
        #   around the person in half
        background_label = labels[0,0,0]
    
        #Fill the air around the person
        binary_image[background_label == labels] = 2
    
    
        # Method of filling the lung structures (that is superior to something like 
        # morphological closing)
        if fill_lung_structures:
            # For every slice we determine the largest solid structure
            for i, axial_slice in enumerate(binary_image):
                axial_slice = axial_slice - 1
                labeling = measure.label(axial_slice)
                l_max = largest_label_volume(labeling, bg=0)
    
                if l_max is not None: #This slice contains some lung
                    binary_image[i][labeling != l_max] = 1
    
        binary_image -= 1 #Make the image actual binary
        binary_image = 1-binary_image # Invert it, lungs are now 1
    
        # Remove other air pockets insided body
        labels = measure.label(binary_image, background=0)
        l_max = largest_label_volume(labels, bg=0)
        if l_max is not None: # There are air pockets
            binary_image[labels != l_max] = 0
    
        return binary_image

    查看切割效果

    segmented_lungs = segment_lung_mask(pix_resampled, False)
    segmented_lungs_fill = segment_lung_mask(pix_resampled, True)
    plot_3d(segmented_lungs, 0)

    这里写图片描述

    我们可以将肺内的结构也包含进来(结节是固体),不仅仅只是肺部内的空气

    plot_3d(segmented_lungs_fill, 0)

    这里写图片描述

    使用掩码时,要注意首先进行形态扩充(python的skimage的skimage.morphology)操作(即使用圆形kernel,结节是球体),参考 python形态操作。这会在所有方向(维度)上扩充掩码。仅仅肺部的空气+结构将不会包含所有结节,事实上有可能遗漏黏在肺部一侧的结节(这会经常出现,所以建议最好是扩充掩码)。

    3.8 数据预处理

    归一化处理
    当前的值范围是[-1024,2000]。任意大于400的值都是我们所感兴趣的,因为它们都是不同反射密度下的骨头。LUNA16竞赛中常用来做归一化处理的阈值集是-1000和400.以下代码

    #归一化
    MIN_BOUND = -1000.0
    MAX_BOUND = 400.0
    
    def normalize(image):
        image = (image - MIN_BOUND) / (MAX_BOUND - MIN_BOUND)
        image[image>1] = 1.
        image[image<0] = 0.
        return image

    0值中心化
    简单来说就是所有像素值减去均值。LUNA16竞赛中的均值大约是0.25.
    不要对每一张图像做零值中心化(此处像是在kernel中完成的)CT扫描器返回的是校准后的精确HU计量。不会出现普通图像中会出现某些图像低对比度和明亮度的情况

    PIXEL_MEAN = 0.25
    
    def zero_center(image):
        image = image - PIXEL_MEAN
        return image
    

    3.9 存储每个病人scan的所有slice肺部特征

    下述代码为main函数中整体过程

     lung_head_dir = '/data/lung_competition/stage1/'
        img_save_head = '/data/lung_competition/roi_images/'
        patient_scans_list = [x for x in os.listdir(lung_head_dir) if os.path.isdir(os.path.join(lung_head_dir,x))]
        #patient_labels_file = '/data/lung_competition/stage1_labels.csv'
        #patient_labels = pd.read_csv(patient_labels_file)
        selem = ball(2)
        #print(patient_scans_list)
        for scan in patient_scans_list:
            scan_files = os.path.join(lung_head_dir,scan)
            ct_scan = read_ct_scan(scan_files)
            save_npy_path = os.path.join(img_save_head, scan)
            if os.path.exists(save_npy_path):
                os.mkdir(save_npy_path)

    存储病人scan的所有slice肺部特征的关键代码为

    segmented_ct_scan = segment_lung_from_ct_scan(ct_scan)
    save_npy = save_npy_path+'.npy'
    np.save(save_npy,segmented_ct_scan)
    print('file %s saved ..'%save_npy)
    plot_ct_scan(segmented_ct_scan)

    四 mhd格式数据处理过程

    4.1 处理思路

    mhd的数据只是格式与dicom不一样,其实质包含的都是病人扫描。处理MHD需要借助SimpleIKT这个包,处理思路详情可以参考Data Science Bowl2017的toturail Data Science Bowl 2017。需要注意的是MHD格式的数据没有HU值,它的值域范围与dicom很不同。
    我们以LUNA2016年的数据处理流程为例。参考代码为 LUNA2016数据切割

    4.2 载入必要的包

    import SimpleITK as sitk
    import numpy as np
    import csv
    from glob import glob
    import pandas as pd
    file_list=glob(luna_subset_path+"*.mhd")
    #####################
    #
    # Helper function to get rows in data frame associated 
    # with each file
    def get_filename(case):
        global file_list
        for f in file_list:
            if case in f:
                return(f)
    #
    # The locations of the nodes
    df_node = pd.read_csv(luna_path+"annotations.csv")
    df_node["file"] = df_node["seriesuid"].apply(get_filename)
    df_node = df_node.dropna()
    #####
    #
    # Looping over the image files
    #
    fcount = 0
    for img_file in file_list:
        print "Getting mask for image file %s" % img_file.replace(luna_subset_path,"")
        mini_df = df_node[df_node["file"]==img_file] #get all nodules associate with file
        if len(mini_df)>0:       # some files may not have a nodule--skipping those 
            biggest_node = np.argsort(mini_df["diameter_mm"].values)[-1]   # just using the biggest node
            node_x = mini_df["coordX"].values[biggest_node]
            node_y = mini_df["coordY"].values[biggest_node]
            node_z = mini_df["coordZ"].values[biggest_node]
            diam = mini_df["diameter_mm"].values[biggest_node]

    4.3 LUNA16的MHD格式数据的值

    一直在寻找MHD格式数据的处理方法,对于dicom格式的CT有很多论文根据其HU值域可以轻易地分割肺、骨头、血液等,但是对于MHD没有这样的参考。从LUNA16论坛得到的解释是,LUNA16的MHD数据已经转换为HU值了,不需要再使用slope和intercept来做rescale变换了。此论坛主题下,有人提出MHD格式没有提供pixel spacing(mm) 和 slice thickness(mm) ,而标准文件annotation.csv文件中结节的半径和坐标都是mm单位,最后确认的是MHD格式文件中只保留了体素尺寸以及坐标原点位置,没有保存slice thickness。如此来说,dicom才是原始数据格式。

    4.4 坐标体系变换

    MHD值得坐标体系是体素,以mm为单位。结节的位置是CT scanner坐标轴里面相对原点的mm值,需要将其转换到真实坐标轴位置,可以使用SimpleITK包中的 GetOrigin() GetSpacing()。图像数据是以512x512数组的形式给出的。
    坐标变换如

    这里写图片描述

    相应的代码处理如下:

    k_img = sitk.ReadImage(img_file) 
    img_array = sitk.GetArrayFromImage(itk_img) # indexes are z,y,x (notice the ordering)
    center = np.array([node_x,node_y,node_z])   # nodule center
    origin = np.array(itk_img.GetOrigin())      # x,y,z  Origin in world coordinates (mm)
    spacing = np.array(itk_img.GetSpacing())    # spacing of voxels in world coor. (mm)
    v_center =np.rint((center-origin)/spacing)  # nodule center in voxel space (still x,y,z ordering)
    

    在LUNA16的标注CSV文件中标注了结节中心的X,Y,Z轴坐标,但是实际取值的时候取的是Z轴最后三层的数组(img_array)。
    下述代码只提取了包含结节的最后三个slice的数据

    i=0
    for i_z in range(int(v_center[2])-1,int(v_center[2])+2):
        mask = make_mask(center,diam,i_z*spacing[2]+origin[2],width,height,spacing,origin)
        masks[i] = mask
        imgs[i] = matrix2int16(img_array[i_z])
        i+=1
    np.save(output_path+"images_%d.npy" % (fcount) ,imgs)
    np.save(output_path+"masks_%d.npy" % (fcount) ,masks)

    4.5 查看结节

    以下代码用于查看原始CT和结mask

    import matplotlib.pyplot as plt
    imgs = np.load(output_path+'images_0.npy')
    masks = np.load(output_path+'masks_0.npy')
    for i in range(len(imgs)):
        print "image %d" % i
        fig,ax = plt.subplots(2,2,figsize=[8,8])
        ax[0,0].imshow(imgs[i],cmap='gray')
        ax[0,1].imshow(masks[i],cmap='gray')
        ax[1,0].imshow(imgs[i]*masks[i],cmap='gray')
        plt.show()
        raw_input("hit enter to cont : ")

    这里写图片描述

    4.6 包含结节位置信息的mhd格式数据特征

    参考一个开源代码实现 UNET训练肺组织结节分割

    展开全文
  • pixelmator Mac版是一款轻量级修图软件,相比Photoshop的庞大pixelmator mac特别版更加的小巧精致,不会占用您很大的空间!别看Pixelmator for Mac小...点击下载Pixelmator for Mac(强大的图像处理软件) PixelMat...
  • 五款开源图像处理软件

    千次阅读 2014-08-23 11:54:46
    开放源码社区一直因为缺少以用户为中心的应用软件而饱受诟病。从一个每天都使用开源桌面和服务环境的用户角度来看,我也支持很多开源应用不如商业解决方案华丽... 我们这里就将介绍五种开源 的图形处理 应用软件,它
  • 使用QT5+Opencv完成简单的图像处理及视频处理软件一、写在前面二、成品展示三、图像处理1.灰度化2.均值滤波3.边缘检测4.伽马变换5.亮度调节(槽函数)6.二值化(可变)(槽函数)7.对比度(函数调用)8.饱和度调整...
  • 32款图片处理软件介绍

    千次阅读 2009-03-04 16:08:00
    32款图片处理软件介绍 色友们大概没有人不知道Photoshop大名的,要想得到好的照片后期处理是必不可少的。但是Photoshop也不是万能的,况且它的资源占用也非常的大,那么有没有其他的选择呢,答案是肯定的。下面我们...
  • 即使没有计算机图形学基础知识的读者也完全不用担心您是否适合阅读此文,本文的性质属于科普文章,将为您揭开诸如Photoshop、Fireworks、GIMP等软件图像处理操作的神秘面纱。之前您也许对这些处理技术感到惊奇和...
  • 实现了一些常见图像处理方法  例如 中值均值滤波 傅里叶变换 腐蚀膨胀 添加椒盐高斯噪声等 代码开源 传送门  https://github.com/menyangyang/DIPSoftware.git csdn代码下载: ...
  • 几种常见图像处理的方法

    万次阅读 2012-03-21 17:09:52
    本章所涉及的方法有:灰度化...这里我们处理的是bmp格式的图像,bmp格式的文件有3个文件头,第一个文件头大小为14个字节,主要是对整个文件的信息的存储。 typedef struct tagBITMAPFILEHEADER { WORD bfType; DWORD
  • 今天给大家推荐一款好用而且开源的图像处理软件:imageJ ImageJ是公共领域的开源软件。 ImageJ用户拥有被Richard Stallman在1986年定义的四种基本自由: 1、 出于任何目的,自由运行程序。 2、 学习程序如何工作的...
  • 介绍图像基于卷积计算三种双立方插值函数,分别是三角线性分布、Bell钟型分布、B样条曲线分布 通过它们实现图像双立方插值放大。
  • Gwyddion使用教程Gwyddion简介Gwyddion user guide下载地址本次教程用的AFM扫描图像下载地址AFM/STM校准样品Gwyddion使用step1step2step3step4step5step6step7step8你没见过的CD磁道到底长啥样一张图总结 ...
  • 这个功能基本上很多软件都有,比如美图秀秀,女生们的最爱。 美肤的原理,简单来说,其实就是图像平滑操作,不过在这个平滑的过程中最好不能把轮廓给模糊掉。美图秀秀美肤操作的技术没公开,我这里就只谈谈采用双边...
  • 文章目录图像识别在测试中的应用图形脚本语言`sikuli`图像识别优缺点使用OpenCV图像识别来进行自动化测试选择做测试如何测试人工智能软件人工智能的测试分为以下几个部分:测试内容AI测试-智能音箱--自然语言处理,...
  • 常见的开源软件

    2008-03-27 18:14:00
    常见的开源软件 应用领域 软件名称 服务器端软件
  • 常见GIS工具软件介绍

    千次阅读 2019-02-28 16:31:21
    导读:本章介绍了比较常用的一些地理信息系统软件,具体包括三家美国GIS开发商ESRI,Intergraph和MapInfo的软件产品,以及三个国产软件:MapGIS,GeoStar和Citystar。 介绍的内容来自于各个公司的宣传材料以及WWW上...
  • 声会影X3配套图片处理软件:Corel Paint Shop Pro Photo X3 功能极为强大,可以和PS相媲美。个人认为,在某些方面,甚至超越PS,尤其在抠图等方面。所以推荐大家使用,希望大家喜欢,给您增加一个处理照片的好帮手!。...
  • 图像处理_DICOM医学图像处理

    千次阅读 2017-05-16 10:17:18
    matlab处理图像入门实验
  • 【QT】QT从零入门教程(一):图像处理自编软件

    万次阅读 多人点赞 2018-02-06 13:35:19
    此前接触过OpenCV,学C++也有一段时间了,正好想从零入门学QT,于是思路打开,就做一个图像处理方向的软件。   这次QT自学,一改以往先看书看视频的习惯,在构思了软件的大致界面和大体功能后,直接上手。不得不...
  • 机器视觉就是用机器代替人眼来做测量和判断。传送给专用的图像处理软件,根据像素分布和亮度、颜色等信息,转变成数字化信号;图像处理软件对这些信号进行各种运算来抽取目标的特征,...
  • 机器视觉处理软件:用来完成输入图像数据的处理,通过一定的运算得出结果,这个输出的结果可能是PASS/FAIL信号、坐标位置、字符串等。 常见的机器视觉软件以C/C++图像库,ActiveX控件,图形式编程环境等形式出现,...
  • 本文是讲述《数字图像处理》系列文章,继上篇讲述BMP格式图片和显示后,该篇讲述如何对单文档进行分割.主要是采用CSplitterWnd静态分割窗口显示图片等相关知识.本文主要结合自己的课程及常用图片软件讲解. 一. ...
  • Python图像处理PIL各模块详细介绍

    万次阅读 多人点赞 2018-01-21 22:01:16
    Image模块是在Python PIL图像处理常见的模块,对图像进行基础操作的功能基本都包含于此模块内。如open、save、conver、show…等功能。 open类 Image.open(file) ⇒ image Image.open(file, mode) ⇒ image...
  • 图像调色处理软件—“Image 2 LUT ”

    千次阅读 2019-06-02 16:56:02
    Image 2 LUT Pro Mac界面设计精良,使用户体验非常简单。...加载图片也非常直观。可以将它们拖放到界面中,使用剪贴板或使用应用程序的浏览按钮。一旦加载了源图像和目标图像,就会自动进行颜色和亮度匹配。然后...
  • 软件测试总结——常见的面试问题(一)

    万次阅读 多人点赞 2019-10-12 18:40:58
    1.软件测试级别? 单元测试:单元测试是...(测试内容:模块接口测试、局部数据结构测试、路径测试、错误处理测试、边界测试) 集成测试:(集成测试也称联合测试、组装测试,将程序模块采用适当的集成策略组装起...
  • 常见的十大恶意软件类型

    千次阅读 2020-09-16 17:17:12
    对于IT安全专家和用户而言,许多不同类型的恶意软件会让他们的生活和工作变得非常难处理。因此有必要了解不同类型的恶意软件。 什么是恶意软件? 恶意软件(俗称“流氓软件”)是指在未明确提示用户或未经用户许可的...
  • 软件开发常见的开发方向

    千次阅读 2019-05-11 16:01:58
    做为一个过来人,简单介绍一些常见的开发方向。 1.桌面程序:Java、C++、C#、VB、C均可。 现在大家办公使用的还是桌面程序占多数,不管是OA,ERP等等,都是通过PC来操作,桌面程序开发是一个重要的方向。只要PC还在...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 128,691
精华内容 51,476
关键字:

常见的图像处理软件