Ruby 应用于医学领域:处理医学图片

来源:开源中国社区 作者:oschina
  

Ruby 应用于医药领域

               Ruby 应用于医药领域:处理医学图片

first aid long shadow icon, vector symbol 
 

急救的长阴影图标,矢量版

作为医疗影像图片分析的研究员,我知道这些图片的重要性。图片所揭示的身体信息,不管是内部的(例如MRI)还是外部的(例如皮血管检查),都是极其有价值的。有时候图片上能清晰的看到一个肿瘤,这让我很惊讶。有时候图片还需要一些处理,不过最终这些医学图片都会成为医疗信息的有价值来源。

显然,肿瘤并非唯一的通过医学图片能看到的东西。其他问题,例如骨折,也可以通过图片来诊断。医学图片分析已经成为医学很重要的部分,每年都会有很多会议和杂志与此相关。

这个系列里,我关注的是如何把 Ruby 编程应用到医学领域。这篇文章要介绍的是如何用 Ruby 来显示和处理一个医学图片。

下面我们就开始。

软件
 

Tk

在开始之前,我们有必要简单介绍一下Tk,这是本文所需要的一个基本工具。

Tk 是一个免费的开源的跨平台组件库,主要用来构建图形界面,它支持不同的编程语言,也包括 Ruby。换句话说,它为我们提供了构建桌面程序的图形用户界面(GUI)的组件,包括文本、按钮、标签等等。Tk 是 Ruby 的标准库的一部分。

ImageMagick
 

ImageMagick 是一个库,也包含了一系列的命令行工具,可以让你处理不同格式的图片。

RMagick

RMagick 是 Ruby 的 ImageMagick 封装。RMagick 把 ImageMagick 提供的各种功能抽象出来,可以在 Ruby 程序中进行调用。

环境设置

现在已经简单对基本的概念做了介绍,接下来我们需要设置环境。我们需要安装刚才说的那些库:Tk、ImageMagick 和 RMagick。

安装 Tk
 

我用的是 Mac OS X,所以安装过程是基于这个操作系统的。不过别担心,如果你用的是其他操作系统,你可以参考这里来了解如何安装 Tk。

在 Mac OS X 下,ActiveTcl 是获取 Tk 的最简单的方式。ActiveTcl 包含了 Tcl、Tk 和其他一些库。你可以直接从这里下载。下载后安照下面的步骤进行安装。

安装 ImageMagick

安装 ImageMagick 很简单。不同的发行版及操作系统的帮助参考这里。我一般使用 Homebrew 来安装 ImageMigick。你可以在终端执行下面的命令来安装 Homebrew(不包括 $ 字符):

$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

现在要安装 ImageMagick,只需要简单的在终端执行(不包括 $ 字符):

$ brew install imagemagick

    安装 RMagick
 

    安装 RMagick,你需要在终端执行下面的命令(假定你已经安装了 Ruby ):

1
$ gem install rmagick

    显示一个医学图片

    我们可使用 Ruby 将图片做出以下的视图效果:

brain

    接着,把这个图片以 brain.jpg 格式保存在硬盘上。
 

    首先要做的是读取这个图片。可以使用 TkPhotoImage 类来读取图片:

1
2
3
require 'tk'
img = TkPhotoImage.new
img.file = 'brain.jpg'

    Tk 中组件是有层级关系的,也就是说一个组件可以包含在另一个组件里。在 Tk 中主组件是 rootwidget,且可以用TkRoot 类来创建该组件。可以把 TkRoot 看做主窗口。可用 Ruby 按以下操作来创建主窗口:

1
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 时可能会遇到的一些问题。

    Gif 的问题

    你可能会问,我们为什么需要先安装 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 命令行工具来做这个转换,所以这一步并非很重要。

    无法加载文件 — tk (LoadError)
 

    这是运行这个程序时可能出现的错误之一,是在 require 'tk' 这一行产生的:

1
2
cannot load such file -- tk (LoadError)
通常你用RVM时会报这个错。对于我们的程序,这个问题可以这样解决:首先确定Tcl已经安装(参考前面安装Tk的部分),然后在终端运行下面的命令(这会把Tk升级到2.2.3,在Mac OS X下这个版本的Ruby可以支持Tk):
1
rvm reinstall 2.2.3 --enable-shared --enable-pthread --with-tk --with-tcl

    无法加载文件 — RMagick (LoadError)

    这是 require 'RMagick' 这一行可能报的错误:

1
cannot load such file -- RMagick (LoadError)

    要解决这个问题,只需要运行:

1
$ gem install rmagick

    解决完这些问题后,程序的输出就像下面这样(刚开始窗口会比较小,可以将其放大成下面这样):

output

Ruby 应用于医学:Base 64 编码与解码
 

假设你需要在网络上传输这个图片,例如通过 email 发送。估你会奇怪为什么接收方收到的图片文件有些奇怪的字符。这可能是你的文件是以二进制格式去发送的,但是这类媒体的网络传输的数据格式却是按文本设计的。

不过别担心,Base 64 编码就是一个用来解决这个问题的工具接下来我将会向你展示用 Ruby 编写的Base 64 来对医学图片进行编码和解码是多么简单。

什么是 Base 64?

Base 64 是一种编码方式,可以把8比特的二进制数据编码成7比特的格式。采用这种方式只需使用 A-Z、a-z、0-9、+和/,= 字符便可补全数据。通过这种编码方式,3个8比特字节可以编码成4个7比特字节的数据。

为什么要使用 Base 64?

Base 64对于二进制数据的显示很重要,可以让二进制的数据通过某种方式表现地与普通文本一样。这可以让数据在一些情况下更可靠,比如存入数据库、作为邮件发送,或者作为文本格式使用,例如用于XML。当需要把数据按 ASCII 字符串格式展示的时候,我们一般会使用 Base 64。

Base64 编码
 

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解码的步骤基本上就是前一小节所说的步骤相反的顺序:

  • 字符串的每个字符转换成对应的Base64编码的十进制数。

  • 十进制数转换成对应的二进制数。

  • 每个二进制字节的前两位被截掉,剩下的6个比特拼接起来,成为一个大的二进制串。

  • 上面这个大的二进制串按照8比特切分成不同的字节。

  • 8比特的数字转换成十进制数。

  • 十进制数转换成对应的ASCII码。

编码图片

理论说的不少了,我们来看看Ruby的代码。本文第一部分我会使用之前的那个大脑的图片。在Ruby里使用Base64编码,首先需要包含base64模块,这是标准库的一部分:

1
require base64

要对图片进行编码,只需要调用函数encode64(bin)。Ruby的文档中对这个函数的说明:

>> 返回参数binBase64编码后的结果。这个方法遵循RFC 2045。每60个编码后的字符会添加一个回车。

下面是对图片进行Base64编码的代码:

1
2
3
4
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)

如果你想查看编码后的结果,可以加上这一行:

1
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 。

作者的其他文章
 

总结

Ruby 是被设计成讨编程者欢心的语言。它提供了很多工具来辅助我们的日常工作。这篇文章及其这个系列的目标是教授一些基本的 Ruby 知识,尽管在一定范围内关于 Ruby 的讨论还很少。最后,希望今天你能从这篇文章中学到一些东西,比如学到怎么使用 TK,怎么使用编码和解码图片。
 

希望你的大脑图片能大点哦。:)

本文转自:开源中国社区 [http://www.oschina.net]
本文标题:Ruby 应用于医学领域:处理医学图片
本文地址:
http://www.oschina.net/translate/ruby-on-medicine-working-with-medical-images
参与翻译:
zicode, 无若, crossmix

英文原文:Ruby on Medicine: Working with Medical Images


时间:2016-01-27 08:41 来源:开源中国社区 作者:oschina 原文链接

好文,顶一下
(0)
0%
文章真差,踩一下
(0)
0%
------分隔线----------------------------


把开源带在你的身边-精美linux小纪念品
无觅相关文章插件,快速提升流量