fo-dicomを使ってDICOMファイルから画像を抽出する(②作成編)

Icon.NET

前回はプロジェクトに参照を追加するところまでを書きました。

fo-dicomを使ってDICOMファイルから画像を抽出する(①準備編)
.net(C#)とfo-dicomを使って簡単なビューワアプリを作成する解説記事

今回は、実際にDICOMの画像をJPEGファイルに落すコードを書いてみたいと思います。

また、当然のことですが、

不具合が発生しても当方では責任を負えませんので、参考程度にお願いします

広告

フォーム

コンソールアプリにしてもよいのですが、画面からファイルを選択したいので、以下のような画面にします。

Form application

コード

コード全体

Form1.csの中は以下のようになっています。

using System;
using System.Drawing;
using System.Windows.Forms;
using Dicom;
using Dicom.Imaging;

namespace testDICOM
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 選択(DICOM入力)ボタン処理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnInput_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                ofd.Multiselect = false;ofd.Multiselect = false;
                if (ofd.ShowDialog() != DialogResult.Cancel)
                {
                    this.txtInput.Text = ofd.FileName;
                }
            }
        }

        /// <summary>
        /// 選択(JPG出力)ボタン処理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOutput_Click(object sender, EventArgs e)
        {
            using (SaveFileDialog sfd = new SaveFileDialog())
            {
                sfd.Filter = "JPEG|*.jpg";
                if (sfd.ShowDialog() != DialogResult.Cancel)
                {
                    this.txtOutput.Text = sfd.FileName;
                }
            }
        }

        /// <summary>
        /// 保存ボタン処理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                this.Cursor = Cursors.WaitCursor;

                DicomImage dicom = new DicomImage(txtInput.Text);

                //動画は処理しない
                if (dicom.NumberOfFrames != 1)
                {
                    MessageBox.Show("動画は変換不可(枚数:" + dicom.NumberOfFrames.ToString() + ")");
                    return;
                }

                using (var bitmap = dicom.RenderImage().As<Bitmap>())
                {
                    bitmap.Save(this.txtOutput.Text, System.Drawing.Imaging.ImageFormat.Jpeg);
                }

                MessageBox.Show("完了");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }
    }
}

追加した箇所は、

using Dicom;
using Dicom.Imaging;

後は各ボタンのクリックイベントの中です。

イベントを追加するにはフォームデザイナ上にあるButtonコントロールをダブルクリックします(デフォルトでClickイベントが作成される)。

DICOM読込

DicomImageクラスはDicom.Imaging名前空間の中に存在します。

DicomImage dicom = new DicomImage(txtInput.Text);

動画はスキップ

動画に関しては今回は割愛します。
ちなみに、エコーのような動画の場合、DICOMファイルの中には静止画が複数枚存在しますので、それら全てを取り出し動画形式に変換する、というコードが必要です。
.net Frameworkの機能だけで動画は作成できないので、別途ライブラリを用意する必要があります。

以下のプロパティで画像の枚数を取得できます。複数枚あれば動画、ということですね。

dicom.NumberOfFrames

JPGに落す

using (var bitmap = dicom.RenderImage().As())
{
bitmap.Save(this.txtOutput.Text, System.Drawing.Imaging.ImageFormat.Jpeg);
}

これで出来ます。

プラットフォームターゲットを変更

環境が64bit環境だと、プラットフォームターゲットをx64にしないと、JPG保存時に以下のエラーが出てしまいます。

Decoding dataset with transfer syntax: JPEG Lossless, Non-Hierarchical, First-Order Prediction (Process 14 [Selection Value 1]): Default Transfer Syntax for Lossless JPEG Image Compression is not supported.

これを回避するには、
①プロジェクトのプロパティ → 「ビルド」の中、
「プラットフォームターゲット」を「x64」に変更

Visual Studio Setting

構成マネージャーで、プラットフォームを「Any CPU」から「x64」に変更します。

Visual Studio Setting

これでプログラムは完成です。後はDICOMファイルを用意して変換してみましょう。

DICOMファイルを用意する

通常、DICOM画像のように機密性の高い情報はネットに接続された環境に置かないのが普通です。

ググれば色々出てきますが、以下でサンプルDICOMファイルが公開されています。

日本画像医療システム工業会(JIRA) – 標準DICOM画像セット
(http://www.jira-net.or.jp/dicom/dicom_data_01_02.html)

DICOMの和訳も公開されてるそうなので、参考資料としては覚えておくと良さそうです。

以上です。

タイトルとURLをコピーしました