I’ve updated my PHP DICOM class to be easier to use on Windows. It should now automatically detect which operating system it is running on and act accordingly.
In this tutorial I’m going to post some example code and walk you through converting a DICOM multi-frame image (CINE Loop) into an mp4 video file. I chose MP4 because it works well with Apple and Microsoft products.
You’ll need ffmpeg installed with the ability to do x264. The ffmpeg site has many guides on how to do this. I used this guide for CentOS 6 for this tutorial.
Once you’ve got the prerequisites out of the way, run the commands below to download and run a copy of the example files.
wget http://www.deanvaughan.org/projects/multi-frame-to-mp4.tar.gz tar zxvf multi-frame-to-mp4.tar.gz cd Mutli-Frame_to_MP4/ ./dcm2mp4.php sample.dcm
Your freshly created MP4 file is ./video_temp/sample.dcm.mp4, a copy is playing below:
Now take a look at dcm2mp4.php, it should be commented well enough to make it easy to understand what it is doing.
This article will cover writing a storage server that is able to receive images, store them on your hard drive, create thumbnails of the images, parse out important header information, and store that header information in a database.
These articles will be focused on Linux, though I may amend them in the future to cover Windows. They will assume that you have some knowledge of PHP, mySQL, and the Linux command line.
You will need my PHP DICOM class installed. You will also need mySQL installed and have access to add users and databases.
One of the things I dislike about programming books is that they’ll spend pages upon pages showing snippets of code and explaining everything line by line. I’m not going to use that approach, I’m going to walk you through getting the example code running on your computer, testing it, and explaining how it works in a high level fashion. I tried to write the code plainly, simply, and use verbose comments through out explaining what is going on.
Lets get the sample code up and running!
wget http://www.deanvaughan.org/projects/PACS_Tutorial.tar.gz tar xvf PACS_Tutorial.tar.gz cd PACS_Tutorial/part1 chmod 755 import.php store_server.php send_test_image.php chmod -R 777 received_images temp
Download all of the sample code and set permissions.
mysql -uroot -p < db.sql
We need to create a database and user for our PACS. The file db.sql will create a user, ‘pacs’, with password ‘pacspassword’, and grant it all privileges to a new database called ‘pacs’. It will then create two tables, studies and images.
If at all possible, don’t change any of this, it’ll make the tutorial a lot less of a headache. If you do change it, open up import.php, and look for mysql_connect. Change the values there as needed.
With that command we’ve launched our storage server on port 1104. Notice that the script didn’t launch in the background? Don’t worry, I’ll cover that later on.
If you don’t want your server running on port 1104, edit store_server.php and its easy enough to change.
The storage server as is doesn’t care about AE titles, its promiscuous and will accept images from anyone.
Since our storage server is using our terminal, leave it running and open a new terminal for the next steps.
store_server.php is going to be receiving your images, after an image is received it will run another script, import.php. import.php will be responsible for moving the image to a safe place on the hard drive, parsing the image’s header information, placing that information into a database, and creating a JPEG thumbnail of the image for later use.
You can test to see if all of this works by sending an image to your computer’s IP address using port 1104. You can make something up for the AE title.
If you don’t have a way to send yourself images, I’ve included a small script that will send your new server one image.
That will send dean.dcm from class_dicom.php’s examples over to your new server.
Once you have sent an image you can switch back to your terminal running store_server.php and see the log entries regarding the image transmission. Among many things the log will show you where the image was saved.
mysql -uroot -p < view_db.sql
Let’s take a look at the database. If all went well the command above should show you the contents of the database; information about the images sent to the server.
There are two tables.
The first table is studies. This table contains information obtained from the image pertaining to the study. Each study can have many images, in example, a chest study could have both a PA and lateral view; one study, two images.
The second table is images. This table contains information specific to an image.
You’ll see there isn’t a field for storing the file name of the image, this is because the file name is easily inferred from database information.
Take a look at this snippet from import.php:
$store_dir = "./received_images/$sent_from_ae/" . $img['year'] . "/" . $img['month'] . "/" . $img['day'] . "/" . $img['study_uid'];
The image is stored in a directory based on the AE title it came from, the appointment date, and the study uid. The image itself uses the SOP instance plus ‘.dcm’ for its file name. Since all of this information is in the database, we can find the file. Later tutorials will go into more detail on this.
Right now, the storage server is stuck running in its own terminal window, if you close the window the storage server stops running, not cool. You’ll want to get it running in the background and you’ll want it to start at boot.
This gets tricky as different flavors of Linux, and even different versions of those flavors, handle this differently. I’ll discuss the three most common approaches. If you have not done so already, control-c in the storage_server.php terminal to stop it.
CentOS 5.6+, Fedora, Red Hat, Ubuntu:
You should have a /etc/init directory. You can place script in this directory that init will use to start/stop and keep running your programs.
start on runlevel  stop on runlevel [!$RUNLEVEL] respawn console output exec /home/dean/PACS_Tutorial/part1/store_server.php
Create /init/store_server.conf and add all of that. Be sure to change the path to store_server.php to match your own setup.
‘initctl start store_server’ to start your server
If you don’t have a /etc/init directory, you can always fall back to editing the inittab itself.
Edit /etc/inittab and add this line to the bottom of the file. Be sure to change the path so it points to your copy of store_server.php. Once you’re back at the command line, type ‘init q’. This will reload the inittab and start up store_server.php.
All else fails:
nohup will start store_server.php in the background for you. It will not restart the process if it crashes as the methods above will.
Now you have a multi-threaded DICOM storage server capable of receiving thousands of studies worth of images everyday. The information it receives is placed into a database for easy access by other programs.
Stay tuned for part two where in I’ll show you how to write a user interface to your PACS.
I develop primarily on Linux and wrote class_dicom.php with Linux in mind. This tutorial will be geared towards CentOS or Fedora as that is what I use on a day to day basis. I’ll try to include notes for Ubuntu/Debian when possible.
I’m going to assume you have at minimum, Linux installed on a PC and you can access the command line as root.
1. Let’s get your environment ready
We’re going to install all of the needed development tools, a web server, and MySQL. A web server and MySQL is not needed by class_dicom.php, but since most folks are going to want to use PHP from a web server, we might as well get it installed.
yum -y groupinstall "Web Server" 'Development Tools' "MySQL Database" yum -y install wget php php-gd ImageMagick libjpeg zlib libpng libtiff libxml2 libpng-devel zlib-devel libjpeg-devel libtiff-devel libxml-devel libxml2-devel libwrap-devel libpng10-devel php-mysql
sudo apt-get install lamp-server^ sudo apt-get install build-essential wget ImageMagick libjpeg zlib libpng libtiff libxml2 libpng-devel zlib-devel libjpeg-devel libtiff-devel libxml-devel libxml2-devel libwrap-devel libpng10-devel
All of the above will probably take a while to finish out. Note that the ^ in the Ubuntu command is not a typo and needs to be present.
2. Build and install DCMTK
DCMTK is what class_dicom.php uses to actually work with DICOM files. Among many other things, it is a collect of command line tools for working with DICOM files.
The process of building and installing is essentially the same between versions of Linux.
wget ftp://dicom.offis.de/pub/dicom/offis/software/dcmtk/dcmtk360/dcmtk-3.6.0.tar.gz tar zxvf dcmtk-3.6.0.tar.gz cd dcmtk-3.6.0 ./configure;make;make install
Depending on your computer, the DCMTK can take a long time to build.
3. Install class_dicom.php
Download a copy:
wget --no-check-certificate http://github.com/vedicveko/class_dicom.php/zipball/master unzip master mv vedicveko-class_dicom.php* class_dicom_php
and…. you’re done.
Lets make sure it works!
cd class_dicom_php/examples ./get_tags.php dean.dcm
You should see a header dump of dean.dcm printed to the screen.