Ruby 应用于医药领域
Ruby 应用于医药领域:处理医学图片
Ruby 应用于医药领域: 计算文件的词频
Ruby 应用于医药领域: 将 DICOM 转换成 JPG
Ruby 应用于医药领域: 处理大型文件
Ruby 应用于医药领域: 搜寻基因序列
Ruby 应用于医药领域: 多文件间的替换
用 Ruby 统计实词
急救的长阴影图标,矢量版
作为医疗影像图片分析的研究员,我知道这些图片的重要性。图片所揭示的身体信息,不管是内部的(例如MRI)还是外部的(例如皮血管检查),都是极其有价值的。有时候图片上能清晰的看到一个肿瘤,这让我很惊讶。有时候图片还需要一些处理,不过最终这些医学图片都会成为医疗信息的有价值来源。
显然,肿瘤并非唯一的通过医学图片能看到的东西。其他问题,例如骨折,也可以通过图片来诊断。医学图片分析已经成为医学很重要的部分,每年都会有很多会议和杂志与此相关。
在 这个系列 里,我关注的是如何把 Ruby 编程应用到医学领域。这篇文章要介绍的是如何用 Ruby 来显示和处理一个医学图片。
下面我们就开始。
在开始之前,我们有必要简单介绍一下 Tk ,这是本文所需要的一个基本工具。
Tk 是一个免费的开源的跨平台组件库,主要用来构建图形界面,它支持不同的编程语言,也包括 Ruby。换句话说,它为我们提供了构建桌面程序的图形用户界面(GUI)的组件,包括文本、按钮、标签等等。Tk 是 Ruby 的标准库的一部分。
ImageMagick 是一个库,也包含了一系列的命令行工具,可以让你处理不同格式的图片。
RMagick 是 Ruby 的 ImageMagick 封装。RMagick 把 ImageMagick 提供的各种功能抽象出来,可以在 Ruby 程序中进行调用。
现在已经简单对基本的概念做了介绍,接下来我们需要设置环境。我们需要安装刚才说的那些库:Tk、ImageMagick 和 RMagick。
我用的是 Mac OS X,所以安装过程是基于这个操作系统的。不过别担心,如果你用的是其他操作系统,你可以参考 这里 来了解如何安装 Tk。
在 Mac OS X 下, ActiveTcl 是获取 Tk 的最简单的方式。ActiveTcl 包含了 Tcl、Tk 和其他一些库。你可以直接从 这里 下载。下载后安照下面的步骤进行安装。
安装 ImageMagick 很简单。不同的发行版及操作系统的帮助参考 这里 。我一般使用 Homebrew 来安装 ImageMigick。你可以在终端执行下面的命令来安装 Homebrew(不包括 $ 字符):
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
现在要安装 ImageMagick,只需要简单的在终端执行(不包括 $ 字符):
$ brew install imagemagick
安装 RMagick,你需要在终端执行下面的命令(假定你已经安装了 Ruby ):
$ gem install rmagick
我们可使用 Ruby 将图片做出以下的视图效果:
接着,把这个图片以 brain.jpg 格式保存在硬盘上。
首先要做的是读取这个图片。可以使用 TkPhotoImage 类来读取图片:
require 'tk' img = TkPhotoImage.new img.file = 'brain.jpg'
Tk 中组件是有层级关系的,也就是说一个组件可以包含在另一个组件里。在 Tk 中主组件是 rootwidget,且可以用 TkRoot 类来创建该组件。可以把 TkRoot 看做主窗口。可用 Ruby 按以下操作来创建主窗口:
root = TkRoot.new(title 'view image')
创建好主窗口之后,我们需要一个组件来显示图片。我们可以用 TkLabel ,它可以让我们创建一个label 来显示我们的图片。可按下面的代码在 root 中创建一个 label:
label = TkLabel.new(root)
接下来在 label 里显示图片:
label.image = img
在进一步添加 Tk 的控制代码之前,我们需要指定 label 的宽度和高度。我们让 label 的宽度和高度与图片保持一致。代码实现如下所示:
label.place(height: img.height, width: img.width)
到此 label 的创建基本上就完成了。为了让 Tk 显示这个组件,我们还需要调用 Tk.mainloop。最后的脚本是这样的:
require 'tk' img = TkPhotoImage.new img.file = 'brain.jpg' root = TkRoot.new {title 'view image'} label = TkLabel.new(root) label.image = img label.place(height: img.height, width: img.width) Tk.mainloop
在告诉你输出结果之前,我想先列出一些你在使用 Tk 时可能会遇到的一些问题。
你可能会问,我们为什么需要先安装 ImageMagick 和 RMagick ?我们的代码里并没有用到它们啊。
你可以参考 这里 ,标准的 Tk 只支持 gif 图片格式,而我们需要处理的是 jpg 的图片格式。这就需要 ImageMagick 和 RMagick 的帮助了。用 RMagick 可以把 jpg 的图片转换成 gif 图片,然后在程序里就可以使用 gif 格式的图片了。
RMagick 是在 Magick 模块里实现的,所以我们需要包含 Magick,如下所示:
require 'RMagick' include Magick
下面把 jpg 转换成 gif:
img = ImageList.new('brain.jpg') img.write('brain.gif')
现在你就可以读取 brain.gif 文件,而不用去读取 brain.jpg 。你也可以用 ImageMagick 命令行工具来做这个转换,所以这一步并非很重要。
这是运行这个程序时可能出现的错误之一,是在 require 'tk' 这一行产生的:
cannot load such file -- tk (LoadError) 通常你用RVM时会报这个错。对于我们的程序,这个问题可以这样解决:首先确定Tcl已经安装(参考前面安装Tk的部分),然后在终端运行下面的命令(这会把Tk升级到2.2.3,在Mac OS X下这个版本的Ruby可以支持Tk):
rvm reinstall 2.2.3 --enable-shared --enable-pthread --with-tk --with-tcl
这是 require 'RMagick' 这一行可能报的错误:
cannot load such file -- RMagick (LoadError)
要解决这个问题,只需要运行:
$ gem install rmagick
解决完这些问题后,程序的输出就像下面这样(刚开始窗口会比较小,可以将其放大成下面这样):
假设你需要在网络上传输这个图片,例如通过 email 发送。估你会奇怪为什么接收方收到的图片文件有些奇怪的字符。这可能是你的文件是以二进制格式去发送的,但是这类媒体的网络传输的数据格式却是按文本设计的。
不过别担心, Base 64 编码就是一个用来解决这个问题的工具 。 接下来我将会向你展示用 Ruby 编写的 Base 64 来对医学图片进行编码和解码是多么简单。
Base 64 是一种编码方式,可以把8比特的二进制数据编码成7比特的格式。采用这种方式只需使用 A-Z、a-z、0-9、+和/,= 字符便可补全数据。通过这种编码方式,3个8比特字节可以编码成4个7比特字节的数据。
Base 64对于二进制数据的显示很重要,可以让二进制的数据通过某种方式表现地与普通文本一样。这可以让数据在一些情况下更可靠,比如存入数据库、作为邮件发送,或者作为文本格式使用,例如用于XML。当需要把数据按 ASCII 字符串格式展示的时候,我们一般会使用 Base 64。
Base64 编码可以把二进制数据转换成仅限于 64 个字符集的字符序列。在第一节我们介绍过,可用的字符集是 A-Z,a-z,0-9,+, 和 / (算一下是不是真的只有64个字符)。这个字符集也被称为 MIME Base64,是一种通用的字符集。A-Z,a-z,0-9 作为前 62 个字符(此处原文有误),+ 和 / 是最后两个字符。
Base64 编码后的数据比原始数据更长一些,每 3 字节二进制数据会编码成至少 4 字节的 Base64 的数据。有时候你会看到一些奇怪的文本,例如邮件的附件就是最常见的情形,下面的例子那样。这时你看到的就是 Base64 编码的数据!(注意到最后面的 =,可以断定这就是 Base64 的编码,因为等号在编码过程中用于补齐):
Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: base642KfZhNiz2YTYp9mFINi52YTZitmD2YUg2YjYsdit2YXYqSDYp9mE2YTZhyDZiNio2LHZg9in2KrZ h9iMDQoNCtij2YjYryDZgdmC2Lcg2KfZhNin2LPYqtmB2LPYp9ixINi52YYg2KfZhNmF2YLYsdix 2KfYqiDYp9mE2K/Ysdin2LPZitipINin2YTYqtmKINiq2YbYtdit2YjZhiDYqNmH2Kcg2YTZhdmG INmK2LHZitivINin2YTYqtmI2LPYuSDZgdmKDQrYt9mE2Kgg2KfZhNi52YTZhSDYp9mE2LTYsdi5 2YrYjCDYudmE2YXYpyDYqNij2YbZiiDYutmK2LEg2YXYqtiu2LXYtSDYqNin2YTYudmE2YUg2KfZ hNi02LHYudmKINmI2KPZgdiq2YLYryDZhNmE2YXZhtmH2Kwg2KfZhNi52YTZhdmKDQrZhNiw2YTZ gy4NCg0K2KzYstin2YPZhSDYp9mE2YTZhyDYrtmK2LHYpyDYudmE2Ykg2YbYtdit2YPZhSDZgdmK INmH2LDYpyDYp9mE2LTYo9mGLg0KDQrYudio2K/Yp9mE2LHYrdmF2YYNCg== --089e0141aa264e929a0514593016 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: base64
Base64 的预处理流程:
需要编码的文本会转换成对应的 ASCII 值 ( 例如 a:97, b:98等等)。ASCII 表可以参考 这里 。
把上一步的十进制数转换成二进制数( 例如 97: 01100001)。
把所有二进制数拼接起来,得到一个大的二进制数的集合。
将这个大的二进制数的集合分成相等长度的部分,每一部分仅包含6个比特。
每一个 6 比特的数据被转换成对应的十进制。
最后把得到的十进制数转换成对应的 Base64 值 ( 例如 4: E)。十进制数和对应的 Base64 字母的对应关系在 这里 。
Base64解码的步骤基本上就是 前一小节所说的步骤相反的顺序:
字符串的每个字符转换成对应的Base64编码的十进制数。
十进制数转换成对应的二进制数。
每个二进制字节的前两位被截掉,剩下的6个比特拼接起来,成为一个大的二进制串。
上面这个大的二进制串按照8比特切分成不同的字节。
8比特的数字转换成十进制数。
十进制数转换成对应的ASCII码。
理论说的不少了,我们来看看Ruby的代码。本文第一部分我会使用之前的那个大脑的图片。在Ruby里使用Base64编码,首先需要包含 base64模块 ,这是标准库的一部分:
require base64
要对图片进行编码,只需要调用函数 encode64(bin) 。Ruby的文档中对这个函数的说明:
>> 返回参数binBase64编码后的结果。这个方法遵循RFC 2045。每60个编码后的字符会添加一个回车。
下面是对图片进行Base64编码的代码:
require 'base64'#open the image file and treat it as a binary file image = File.open('brain.jpg').binmode image_read = image.read image_64_encode = Base64.encode64(image_read)
如果你想查看编码后的结果,可以加上这一行:
puts image_64_encode
对于使用 ruby 的图像解码来说,可以简单地使用 decode64(str) 函数。该函数的 ruby 文档:
让我们把 Base64 编码与解码的 ruby 脚本图片放在一起。Ruby 脚本,它看起来就像以下的:
>>返回 Base64 解码 str 版本。该方法可以通过 RFC 2045 来编译。可以忽视基本字母表以外的字符。
在前面的小节中,你可以对图像编码进行解码,执行以下操作:
Base64.decode64(image_64_encode)
让我们把 Base64 编码与解码的 ruby 脚本图像放在一起。Ruby 脚本 -----它看起来就像以下的:
require 'base64'image = File.open('brain.jpg').binmode image_read = image.read image_64_encode = Base64.encode64(image_read)image_64_decode = Base64.decode64(image_64_encode)#create a writable image and write the decoding resultimage_result = File.open('brain_decode.jpg', 'w')image_result.write(image_64_decode)
打开 brain_decode.jpg 图片,你们要注意我们在第一阶段编码的原始图片 brain.jpg 。
使用 WordPress EditFlow 插件简单编辑工作流 (Easy Editorial Workflows with the WordPress EditFlow Plugin)
整个世界的移动电子健康档案都在增长 (The Growing World of Mobile Electronic Health Records)
Ruby 是被设计成讨编程者欢心的语言。它提供了很多工具来辅助我们的日常工作。这篇文章及其这个系列的目标是教授一些基本的 Ruby 知识,尽管在一定范围内关于 Ruby 的讨论还很少。最后,希望今天你能从这篇文章中学到一些东西,比如学到怎么使用 TK,怎么使用编码和解码图片。
希望你的大脑图片能大点哦。:)