Extract the scripts here (so that the script files are directly in the folder with the dicoms)
Open a terminal here
Convert the dicoms to ascii files
If using python, you will need the pydicom module installed
maybe: $ python -m pip install pydicom
or just: $ pip install pydicom
Otherwise if using xmedcon, you'll need that
Linux only $ sudo apt-get install xmedcon
Run $ ./dcm2asc.sh (Linux with xmedcon) or python3 dcm2asc.py
When it finishes, look at the final values:
Ensure the slope and intercept are consistent
Ensure that the slope and intercept are 1 and -1024 respectively
If not, edit the slope and intercept values in asc2png8.py to match
Ensure the values are in HU, if not, these scripts won't work. You will have to use a proper dicom viewer (you can probably still use the sort script mentioned above though).
Convert the ascii files to png
Open asc2png8.py and set the desired window high and low bounds (if not using windowing in the web ct viewer).
These are in HU, but 0 is air, so add 1000
The scripts come set to a window from -1000 to 1000
Go to File > Scan for DICOM files ... (Ctrl + Shift + O)
Navigate to the folder with your dicom (.dcm) files
Apply your desired window (create a custom one with Center Level at 0, and Width at 2000 if using windowing in the web ct viewer)
Scroll through every slice (otherwise, windowing isn't applied to every slice when you export)
Go to File > Export > To a picture file
Select a folder for your destination
As mentioned above, select PNG
Make sure there isn't any meta data set to burn into your images.
If you didn't presort your dicoms, you may have to order them by hand now.
Tile your images
Again, the exact process will depend on what software you use. I am sure there are many options. I will cover 2 free ones here.
Windows Tutorial Video:
Be aware the the gimp solution in this video is very slow, if you have a large slice count (depends on your computer, but probably greater than 150), set this to run overnight.
Linux Tutorial Video:
Steps:
First, know that the end products should be as square as possible eg:
7 x 7 if there are between 43 - 49 slices
7 x 8 if there are between 50 - 56 slices
8 x 8 if there are between 57 - 64 slices
etc.
It doesn't have to be perfect, but load time is shortened if we can chunk the whole image
into the GPU and square collages will help with that.
Software for combining images:
Option 1: Imagemagick
Install Imagemagick (on Ubuntu, just $ sudo apt-get install imagemagick), other platforms might require you to build this from scratch.
Go to the folder with your pngs
Open a terminal there and run: $ montage -mode concatenate -tile 8x *.png out.png
The 8x means: Tile the new image 8 by whatever, so the second dimension will be whatever it needs to be
to fit all of the slices. Change the 8 to be the floor of the square root of your image count.
Input Total Slices:
8x
This plugin was created by Eduardo Hernàndez, I am only hosting it here because Gimp doesn't
have the best repo for plugins.
Find the folder for adding scripts to Gimp.
Open Gimp
Go to: Edit
Click Preferences
Expand the Folders section
Click Scripts (Not Plugins)
This shows you the directories where Gimp looks for scripts
when it starts up, if there is more than 1, choose the one
with your user name in it and go to that folder.
Once you get to your scripts folder (it may be empty) close Gimp.
Extract the plugin you downloaded in step 2 here.
Reopen Gimp (Gimp only looks for new plugins when it starts up)
Make sure the plugin is available, go to:
Filters
Combine
Make sure there is an option: Fuse Layers, but don't use it yet.
If this option isn't here, make sure the plugin was extracted into teh correct folder,
and make sure Gimp was restarted.
Now go to File > Open as Layers (Ctrl + Alt + O)
An open dialog will appear, Navigate to the folder with your pngs
There are sort options at the top, click Name until your images are listed in descending order.
Now import all the images
click an image once
press Ctrl + A to Select All
Click Open
The images should no be listed in the layers outline in ascending order
Tile them with your plugin by again going to:
Filters
Combine
Click: Fuse Layers
A dialog will appear asking you How many Layers on the X axis?
Set this to the floor of the square root of your slice count
Input Total Slices:
- Layers on the X axis
Click OK, this will take a LONG time, some images have taken over an hour.
The feed back isn't helpful in gaging how close the image is to completion.
Gimp will appear to be not responding from time to time, don't panic, this is fine.
If you do feel something has gone wrong, you will have to force close Gimp to stop the script.
But honestly, I have never had the script not finish an image (it just takes forever).
A new image will appear with all the slices in one
Again, this might not be the final image, so lossless formats (like PNG) are preferred.
Final compression
Again, the process depends on your image editing program.
Load the complete collage into an editor (if you went the Gimp route above, you are already here)
You can usually save a little space by makeing sure the image mode is in grayscale.
In Gimp, go to Image > Mode > Grayscale
Typically each slice in my images are 512 x 512 (so the full 8 x 8 example would be 4096 x 4096)
Scale the image to whatever you want, but make sure the final resolution is evenly divisible by the tile resolution
For example, 4096 / 8 = 512 exactly.
If a dimension wasn't evenly divisible (eg 4095 / 8 = 511.875) the viewer will round off a pixel and the image will migrate
slightly as it is scrolled.
Before you scale the image, make sure empty portions of the image are a color similar to your slice's background
Imagemagick makes the empty parts white, when you scale the image the smoothing algorithm will blend this
white into neighboring slices (creating a white border along the bottom of some slices).
Export the image. This is hopefully the final product and you will typically want to use lossy compression. (JPG).
Because these images are low on color you can typically get away with a lot of compression.
If you are using windowing with very narrow widths you will want less compression.
Add your image to the viewer
Windows Tutorial Video:
Linux Tutorial Video:
Steps:
Let's replace the simple trial's image with yours
Go to the build01 folder where you have your index.html
Go to the assets folder and change 3 things:
Edit assets.txt
Find the size of your new image in bytes, let's pretend it was 1,234,756 bytes large.
Maybe right clicking will tell you, otherwise, search the Internet for how.
Open assets.txt and find a line that looks like i:slides/file01.jpg:1489715:image/jpeg
This line contains the file name, size, and mime type (separated by colons):
If your image is a .jpg, you only have to change its file size, so the new line is: i:slides/file01.jpg:1234567:image/jpeg
If your image is a .png, the new line is: i:slides/file01.png:1234567:image/png
Edit slidedim.txt
Open slidedim.txt
This file tells the viewer how to parse your image, more at Viewer Configuration.
The first number is the index for the set of slides (think: a specific trial), no other rows can have this same index. This stays 1
The next number is the file number, we used file01 in assets.txt so we'll keep this 1. Trials can use the same file if
desired, this decreases download and image processing time (currently the reward trial is at index 4, and uses the same image as trial 3.
This gives us a separate place to use click states for the fireworks, while leaving the user's clicks untouched).
The next number is the width, in slides, our image is, let's say this was 8, so change this number.
The next number is the height, in slides, our image is, let's say this was 7, so change this number.
The next number is the total slides, our image is, let's say this was 53, so change this number (Note this would mean we would have some
empty spaces in our image since 7*8 is 56, this is fine though, make sure to enter the actual number of slides 53, and NOT total
possible slices 56).
The next item is a boolean value indicating whether you wish to record clicks on that trial, change this to t and we can now
see clicks show up on our new image.
Lastly, we have the file extension, if the image was jpg, leave it as .jpg, if it was png, change it to .png. Case matters.
Add your actual image
Go into the slides folder
Rename or remove file01.jpg
Paste in your new image
Name it file01.jpg, case probably matters (even if you are using Windows now, your final server will probably be Linux)
You can have a total of 20 images with this naming scheme
The first half of this video also covers adding an image to the CT viewer, however the above tutorials
are profoundly better. The last half covers changing colors/etc of the viewer itself.
Don't spend too much effort here. The viewer, and its loading bar, should be hidden while the user
reads consent / instructions, and fills out demographics info. If everything goes correctly,
the viewer should be finished loading before it has a chance to be seen.
Basic Changes
In the root of the build folder there is a file called styles.css
In this file, there is a section called Loading Bar
There are five groups of values
…outer… is the outline of the loading bar
…inner… is the loading bar itself
…panel is the entire surrounding panel the loading bar and image are in.
…panel > … > img is the format of the image.
waitSpinner is the spinner that appears when the user input blocks while
the viewer loads as well as when the user's data is submitted.
Add whatever values / change whatever colors you want here.
The CT viewer image is specified in html/logo.png You can change this to be whatever you want.
Advanced Changes (if you're familiar with html/JavaScript)
You can completely overwrite the loading screen by implementing two functions (check scripts/viewerEvents.js for skeleton code):
window.viewerCustomLoadingBar(panel) is called when the loading bar is first created.
The parameter panel is the root panel to build everything inside of.
If you do not create an element here with the id viewer-meter-inner-bar you must create the function mentioned below as well.
Otherwise, the viewer tries to advance a loading bar which doesn't exist (and crashes the loader, so no ct viewer will appear ever).
window.viewerLoadingBarAdvance(percent) is called when the loading bar advances.
The parameter percent is a number between 0 and 1 indicating how much data is loaded.