Ruby 应用于医药领域 Ruby 应用于医药领域:处理医学图片
急救的长阴影图标,矢量版 作为医疗影像图片分析的研究员,我知道这些图片的重要性。图片所揭示的身体信息,不管是内部的(例如MRI)还是外部的(例如皮血管检查),都是极其有价值的。有时候图片上能清晰的看到一个肿瘤,这让我很惊讶。有时候图片还需要一些处理,不过最终这些医学图片都会成为医疗信息的有价值来源。 显然,肿瘤并非唯一的通过医学图片能看到的东西。其他问题,例如骨折,也可以通过图片来诊断。医学图片分析已经成为医学很重要的部分,每年都会有很多会议和杂志与此相关。 在这个系列里,我关注的是如何把 Ruby 编程应用到医学领域。这篇文章要介绍的是如何用 Ruby 来显示和处理一个医学图片。 下面我们就开始。 软件Tk在开始之前,我们有必要简单介绍一下Tk,这是本文所需要的一个基本工具。 Tk 是一个免费的开源的跨平台组件库,主要用来构建图形界面,它支持不同的编程语言,也包括 Ruby。换句话说,它为我们提供了构建桌面程序的图形用户界面(GUI)的组件,包括文本、按钮、标签等等。Tk 是 Ruby 的标准库的一部分。 ImageMagickImageMagick 是一个库,也包含了一系列的命令行工具,可以让你处理不同格式的图片。 RMagickRMagick 是 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 ):
显示一个医学图片我们可使用 Ruby 将图片做出以下的视图效果: 接着,把这个图片以 brain.jpg 格式保存在硬盘上。 首先要做的是读取这个图片。可以使用 TkPhotoImage 类来读取图片:
Tk 中组件是有层级关系的,也就是说一个组件可以包含在另一个组件里。在 Tk 中主组件是 rootwidget,且可以用TkRoot 类来创建该组件。可以把 TkRoot 看做主窗口。可用 Ruby 按以下操作来创建主窗口:
创建好主窗口之后,我们需要一个组件来显示图片。我们可以用 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' 这一行产生的:
无法加载文件 — RMagick (LoadError)这是 require 'RMagick' 这一行可能报的错误:
要解决这个问题,只需要运行:
解决完这些问题后,程序的输出就像下面这样(刚开始窗口会比较小,可以将其放大成下面这样): 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 的预处理流程:
Base64解码Base64解码的步骤基本上就是前一小节所说的步骤相反的顺序:
编码图片理论说的不少了,我们来看看Ruby的代码。本文第一部分我会使用之前的那个大脑的图片。在Ruby里使用Base64编码,首先需要包含base64模块,这是标准库的一部分:
要对图片进行编码,只需要调用函数encode64(bin)。Ruby的文档中对这个函数的说明: >> 返回参数binBase64编码后的结果。这个方法遵循RFC 2045。每60个编码后的字符会添加一个回车。 下面是对图片进行Base64编码的代码:
如果你想查看编码后的结果,可以加上这一行:
图像解码对于使用 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,怎么使用编码和解码图片。 希望你的大脑图片能大点哦。:) |