Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merging Latest Development Branch #7

Merged
merged 80 commits into from
Aug 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
be239dd
bumping sub-minor version to .1 (from .0) to indicate devel
rg2 Feb 7, 2021
bdd3704
updates to basic DICOM field IO
rg2 Feb 7, 2021
db39635
adding additional check to see if patient orientation fields are present
rg2 Feb 7, 2021
35319b9
adding reading of patient name to basic dicom fields
rg2 Feb 7, 2021
c483a56
adding more flexibility for naming convert dicom series
rg2 Feb 7, 2021
d3ea0ce
adding some routines to detect and skip secondary and derived dicoms
rg2 Feb 7, 2021
c98cfdb
adding options for excluding secondary or derived scans
rg2 Feb 7, 2021
b78858a
including DICOM fields that are relevant for radiographs
rg2 Feb 10, 2021
a8b7820
ability to limit dicom organization to specified modalities
rg2 Feb 12, 2021
99aac69
adding command line interface to DICOM converter tool to limit by
rg2 Feb 12, 2021
7cb32de
adding reader routines for .rad projection file format
rg2 Feb 12, 2021
e90e8b6
adding tool to convert .rad projection files to HDF5 projection data
rg2 Feb 12, 2021
01bbafe
updating copyright year
rg2 Feb 12, 2021
8810d12
removing unused return code
rg2 Feb 13, 2021
671d20c
adding imager pixel spacing to dicom fields
rg2 Feb 13, 2021
c047adf
initial version of a utility for converting 2D X-ray radiographs into
rg2 Feb 13, 2021
20f5b14
adding a flag to not do log conversion of projection image intensities
rg2 Feb 13, 2021
4eefaf6
adding option to force even dims when downsampling camera model
rg2 Feb 14, 2021
6e52272
adding option to force even dims when downsampling proj data
rg2 Feb 14, 2021
f7f6333
removing extraneous whitespace
rg2 Feb 14, 2021
72cd9c1
when downsampling proj data - force even dims - this is needed by ffmpeg
rg2 Feb 14, 2021
159f297
adding imager pixel spacing to DICOM fields print routine
rg2 Feb 15, 2021
445fe22
adding some routines to create a video file from a list of image paths,
rg2 Feb 20, 2021
b2c93f4
adding exe that will create a video from a directory of image files
rg2 Feb 20, 2021
7963c49
adding ability to specify total length of video to be written from
rg2 Feb 20, 2021
6a114e4
throw an exception when no frames are provided to create video
rg2 Feb 20, 2021
3242563
adding support for the movie length argument
rg2 Feb 20, 2021
d41b917
setting spacing of the itk image object when reading .rad projections
rg2 Mar 6, 2021
0e17305
adding a comment about datasets associated with .rad/.raw
rg2 Mar 6, 2021
9f7e74b
adding support for reading .sta/.raw volumes
rg2 Mar 6, 2021
11e6eea
adding tool for converting .sta volumes into an ITK supported format
rg2 Mar 6, 2021
810a0d7
adding study, series, acquisition and content times to the fields read
rg2 Mar 6, 2021
3f3b54b
adding remaining fields from the CIOS fusion struct to the DICOM basic
rg2 Mar 13, 2021
52ae64b
adding support for printing xreg DICOM struct in report dicom app.
rg2 Mar 13, 2021
9f8e795
moving routines for creating exhaustive list of possible 3 sample and 4
rg2 Mar 13, 2021
38da6f9
improving the error reporting when parsing a .rad file
rg2 Mar 14, 2021
1beaa8f
adding binomial coefficient routine
rg2 Mar 14, 2021
f69edf1
adding routine to sample random combinations of elements
rg2 Mar 14, 2021
69aeacb
adding RANSAC-based 2D circle fit routine
rg2 Mar 14, 2021
9875777
reading FOV dims, manufacturer and institution info from DICOM when
rg2 Mar 20, 2021
57cc2fd
fixing typo w/ short flag to print xreg dicom fields
rg2 Mar 20, 2021
64c7d0b
adding functionality to radiograph converter
rg2 Mar 20, 2021
871f852
adding support for multi-frame DICOM radiographs
rg2 Mar 20, 2021
60ac03e
adding support for reading 3D (and ND) volumes from DICOM file
rg2 Mar 22, 2021
3a03873
moving logic for populating proj data from DICOM file into its own
rg2 Mar 22, 2021
310f9b2
adding a placeholder for storing source dicom metadata in a proj data…
rg2 Mar 28, 2021
b18b5d4
adding 2D image and landmark processing for DICOM FOV flags
rg2 Mar 28, 2021
c4675c7
adding tool for remapping directory of DICOM images
rg2 Mar 28, 2021
eb04bb8
adding help message to remap dicom dir tool
rg2 Mar 28, 2021
810d582
including flag to toggle FOV-based image/landmark processing in convert
rg2 Mar 29, 2021
cede93b
adding video writer using Apple AVFoundation (falls back to this on Mac
rg2 Apr 19, 2021
dcfdb2f
adding note about video writing when ffmpeg is not available on Mac
rg2 Apr 19, 2021
fe42502
adding a proper help description for convert dicom radiograph to proj
rg2 Apr 19, 2021
28f042e
adding an optional flag to the projection data that indicates whether
rg2 May 8, 2021
f784eb8
setting value indicating that .rad/.raw spacings are explicit in
rg2 May 8, 2021
77fcd13
adding ability to handle FCSV conversion to pixel indices using a
rg2 May 8, 2021
1dc1733
adding flag for specifying pixel spacing used in FCSV
rg2 May 8, 2021
c3634d3
writing optional indicator regarding derivation/guess of pixel spacings
rg2 May 8, 2021
502da4d
updating copyright years
rg2 May 8, 2021
e655dc9
updating the download link for boost in the build scripts
rg2 Jun 6, 2021
806736f
fixing an issue with terminals that return zero dimensions.
rg2 Jun 6, 2021
778ad18
fixing bug where disabling the border would be ignored when downsampling
rg2 Jul 11, 2021
519b607
refactoring reading 2D proj data from DICOM into its own set of .h/.cpp
rg2 Jul 24, 2021
99ce41b
defaulting geom est. to true in DICOM convert params struct
rg2 Jul 26, 2021
d21e205
adding option to extract NIFTI files from proj. data with "identity"
rg2 Jul 26, 2021
814625f
changing dicom radiograph conversion program to guess geometry by def…
rg2 Jul 26, 2021
2c92b99
adding some options to handle very rare cases when add FCSV files are
rg2 Jul 26, 2021
5871b7c
adding functions for setting an HDF5 long-valued attribute
rg2 Jul 27, 2021
00f7411
adding routine for writing DICOM fields struct to HDF5
rg2 Jul 27, 2021
954c45f
adding reading of DICOM fields struct from HDF5
rg2 Jul 31, 2021
bb88702
bug fix when writing empty string to HDF5
rg2 Jul 31, 2021
639f37d
writing/reading DICOM fields into/from proj data HDF5
rg2 Jul 31, 2021
2d80f56
removing the CIOS fusion metadata pointer from proj data
rg2 Jul 31, 2021
3acc356
removing unused types and functions for processing CIOS Fusion data
rg2 Jul 31, 2021
6bca79b
Commenting out the deployment target for MacOS 10.14
rg2 Aug 1, 2021
cfe994c
updates to the dockerfile for xreg deps
rg2 Aug 1, 2021
f6894ee
adding text file with example docker commands that may be copied and
rg2 Aug 1, 2021
1e13874
updating docker readme to link to text file of example commands
rg2 Aug 1, 2021
39a31cc
Minor changes to windows build script
rg2 Aug 1, 2021
77f4098
Merge branch 'devel' of github.com:rg2/xreg into devel
rg2 Aug 1, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MIT License
#
# Copyright (c) 2020 Robert Grupp
# Copyright (c) 2020-2021 Robert Grupp
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
Expand All @@ -22,13 +22,13 @@

cmake_minimum_required(VERSION 3.13.0 FATAL_ERROR)

if (APPLE)
# Target MacOS 10.14, Mojave
set (CMAKE_OSX_DEPLOYMENT_TARGET "10.14" CACHE STRING "MacOS Deployment Target")
endif ()
#if (APPLE)
# # Target MacOS 10.14, Mojave
# set (CMAKE_OSX_DEPLOYMENT_TARGET "10.14" CACHE STRING "MacOS Deployment Target")
#endif ()

# Version format is YYYY.MM.DD for a release and YYYY.MM.DD.1 for devel after the release
project(xreg VERSION 2020.12.13.0)
project(xreg VERSION 2020.12.13.1)

set (CMAKE_CXX_STANDARD "11" CACHE STRING "C++ Standard (needs at least 11)")
mark_as_advanced(CMAKE_CXX_STANDARD)
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ The [docker](docker) directory demonstrates how Docker may be used to build the
* Highly recomended for GPU acceleration: OpenCL (1.x)
* Only needed at runtime on Windows and Linux and is typically provided with your graphics drivers or CUDA SDK
* Included with MacOS
* Optional: [ffmpeg](https://ffmpeg.org) is used for writing videos when it is found in the system path. The OpenCV video writer is used if ffmpeg is not available.
* Optional: [ffmpeg](https://ffmpeg.org) is used for writing videos when it is found in the system path. When ffmpeg is not found, the following fallbacks are used:
* MacOS: a video writer using AVFoundation,
* Windows, Linux, something else: a writer using OpenCV.

## Testing
Functional testing is available in the form of a [python script](tests/wiki_cmds.py) that runs the commands found on the [wiki walkthrough](https://github.com/rg2/xreg/wiki#walkthrough).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ int main(int argc, char* argv[])
"Do NOT convert RAS to LPS (or LPS to RAS) for the 3D landmarks; "
"RAS to LPS conversion negates the first and second components.")
<< false;

po.add("no-log-remap", ProgOpts::kNO_SHORT_FLAG, ProgOpts::kSTORE_TRUE, "no-log-remap",
"Do NOT perform log remapping of the projection intensities during pre-processing.")
<< false;

po.add_backend_flags();

Expand Down Expand Up @@ -130,6 +134,8 @@ int main(int argc, char* argv[])

const unsigned char pelvis_label = static_cast<unsigned char>(po.get("pelvis-label").as_uint32());

const bool no_log_remap = po.get("no-log-remap");

//////////////////////////////////////////////////////////////////////////////
// Read in input intensity volume

Expand Down Expand Up @@ -167,6 +173,7 @@ int main(int argc, char* argv[])
PrintLandmarkMap(lands_3d, vout);

ProjPreProc proj_preproc;
proj_preproc.params.no_log_remap = no_log_remap;

{
vout << "reading projection data..." << std::endl;
Expand Down
7 changes: 6 additions & 1 deletion apps/image_io/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MIT License
#
# Copyright (c) 2020 Robert Grupp
# Copyright (c) 2020-2021 Robert Grupp
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -28,4 +28,9 @@ add_subdirectory(extract_nii_from_proj_data)
add_subdirectory(add_lands_to_proj_data)
add_subdirectory(draw_xray_scene)
add_subdirectory(regi2d3d_replay)
add_subdirectory(convert_rad_raw_to_proj_data)
add_subdirectory(convert_sta_raw_to_itk)
add_subdirectory(convert_radiograph_dicom_to_proj_data)
add_subdirectory(make_video_from_image_dir)
add_subdirectory(remap_dicom_dir)

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2020 Robert Grupp
* Copyright (c) 2020-2021 Robert Grupp
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -55,6 +55,18 @@ int main(int argc, char* argv[])
po.add("no-pat-rot-up", ProgOpts::kNO_SHORT_FLAG, ProgOpts::kSTORE_TRUE, "no-pat-rot-up",
"Ignore any flags for rotating the image to achieve patient \"up\" orientation.")
<< false;

po.add("fcsv-spacing", ProgOpts::kNO_SHORT_FLAG, ProgOpts::kSTORE_DOUBLE, "fcsv-spacing",
"Default (isotopic) pixel spacing to assume when parsing FCSV landmarks when no 2D pixel "
"spacing is provided by the 2D image metadata.")
<< 1.0;

po.add("use-pd-spacing", ProgOpts::kNO_SHORT_FLAG, ProgOpts::kSTORE_TRUE, "use-pd-spacing",
"Always use the pixel spacings encoded in the projection data file when interpreting "
"FCSV files, even when the pixel spacings were not explicitly provided by the source "
"image format. This is useful when an FCSV file was created using a NIFTI file which "
"was extracted from a projection data file with estimated spacings.")
<< false;

try
{
Expand All @@ -78,6 +90,10 @@ int main(int argc, char* argv[])

const bool ignore_pat_rot_up = po.get("no-pat-rot-up");

const double default_fcsv_spacing = po.get("fcsv-spacing");

const bool use_pd_spacing = po.get("use-pd-spacing");

vout << "opening proj data for reading/writing..." << std::endl;
H5::H5File h5(po.pos_args()[0], H5F_ACC_RDWR);

Expand Down Expand Up @@ -123,6 +139,27 @@ int main(int argc, char* argv[])
CoordScalar spacing_for_phys_to_ind_x = cur_cam.det_col_spacing;
CoordScalar spacing_for_phys_to_ind_y = cur_cam.det_row_spacing;

// The following conditional addresses the UNCOMMON problem listed below:
// Suppose that our source data does not have explicit metadata listing pixel spacings,
// so the conversion to projection data HDF5 format used some additional information to
// estimate the pixel spacings. Now, also suppose that 3D Slicer is not able to read in
// the source data - this has happened with certain DICOMs from TCIA with RF modality.
// In order to annotate landmarks, a NIFTI (.nii.gz) file is extracted from the projection
// HDF5 file and then loaded into 3D Slicer for landmark annotation. This NIFTI file has
// the estimated pixel spacings embedded, and therefore the FCSV annotations are physical
// points calculated using these spacings. When the contents of the FCSV are then loaded
// back into the HDF5 projection data (e.g. using THIS TOOL), the current behavior is to use
// a user-provided spacing when the original source data did not have explicit pixel spacings
// provided. Although this is the most common case and default desired behavior, for the
// previously identified scenario we need to use the estimated pixel spacings present in the
// HDF5 file.
if (!use_pd_spacing && cur_proj_meta.det_spacings_from_orig_meta &&
!*cur_proj_meta.det_spacings_from_orig_meta)
{
spacing_for_phys_to_ind_x = default_fcsv_spacing;
spacing_for_phys_to_ind_y = default_fcsv_spacing;
}

bool need_to_rot = false;

const bool check_rot_field = !ignore_pat_rot_up && cur_proj_meta.rot_to_pat_up;
Expand Down
30 changes: 30 additions & 0 deletions apps/image_io/convert_rad_raw_to_proj_data/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# MIT License
#
# Copyright (c) 2021 Robert Grupp
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

set(EXE_NAME "${XREG_EXE_PREFIX}convert-rad-raw-to-proj-data")

add_executable(${EXE_NAME} xreg_convert_rad_raw_to_proj_data_main.cpp)

target_link_libraries(${EXE_NAME} PUBLIC ${XREG_EXE_LIBS_TO_LINK})

install(TARGETS ${EXE_NAME})

Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* MIT License
*
* Copyright (c) 2021 Robert Grupp
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

#include "xregProgOptUtils.h"
#include "xregH5ProjDataIO.h"
#include "xregRadRawProj.h"

using namespace xreg;

int main(int argc, char* argv[])
{
constexpr int kEXIT_VAL_SUCCESS = 0;
constexpr int kEXIT_VAL_BAD_USE = 1;

ProgOpts po;

xregPROG_OPTS_SET_COMPILE_DATE(po);

po.set_help("Converts a collection of 2D projection images from .rad/.raw format "
"into an HDF5 projection data file for use by xReg. "
"This may be used to convert projections from the Ljubljana 2D/3D datasets "
"located at: http://lit.fe.uni-lj.si/tools.php?lang=eng.");
po.set_arg_usage("<Output Proj. Data File> <.rad path #1> [<.rad path #2> [... <.rad path #N>]]");
po.set_min_num_pos_args(2);

try
{
po.parse(argc, argv);
}
catch (const ProgOpts::Exception& e)
{
std::cerr << "Error parsing command line arguments: " << e.what() << std::endl;
po.print_usage(std::cerr);
return kEXIT_VAL_BAD_USE;
}

if (po.help_set())
{
po.print_usage(std::cout);
po.print_help(std::cout);
return kEXIT_VAL_SUCCESS;
}

std::ostream& vout = po.vout();

const std::string& dst_pd_path = po.pos_args()[0];

const size_type num_rad_files = po.pos_args().size() - 1;

vout << "number of .rad files to read: " << num_rad_files << std::endl;

ProjDataF32List pd;
pd.reserve(num_rad_files);

for (size_type i = 0; i < num_rad_files; ++i)
{
const std::string& cur_rad_path = po.pos_args()[i+1];

vout << "reading .rad file #" << (i + 1) << ": " << cur_rad_path << std::endl;

pd.push_back(ReadRawProjAsProjData(cur_rad_path));
}

vout << "saving to proj data HDF5..." << std::endl;
WriteProjDataH5ToDisk(pd, dst_pd_path);

vout << "exiting..." << std::endl;
return kEXIT_VAL_SUCCESS;
}

30 changes: 30 additions & 0 deletions apps/image_io/convert_radiograph_dicom_to_proj_data/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# MIT License
#
# Copyright (c) 2021 Robert Grupp
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

set(EXE_NAME "${XREG_EXE_PREFIX}convert-radiograph-dcm-to-proj-data")

add_executable(${EXE_NAME} xreg_convert_radiograph_dcm_to_proj_data_main.cpp)

target_link_libraries(${EXE_NAME} PUBLIC ${XREG_EXE_LIBS_TO_LINK})

install(TARGETS ${EXE_NAME})

Loading