This commit is contained in:
2023-09-19 20:54:19 +08:00
commit 31770491ed
34 changed files with 563 additions and 0 deletions

BIN
Q1/.DS_Store vendored Normal file

Binary file not shown.

97
Q1/code.py Normal file
View File

@ -0,0 +1,97 @@
# code.py
# This is an image preprocessing code for HandBoneXRay data, please adopt env.yaml to
# create conda env to run this script
#
# author : deng
# date : 20230919
# platform: MacBook Pro 14 2021
import os
from shutil import rmtree
import cv2
import pydicom
import numpy as np
import matplotlib.pyplot as plt
if __name__ == '__main__':
xray_dir = 'HandBoneXRay/'
result_dir = 'results'
plot = False
# Create result dir to save processed images
if os.path.isdir(result_dir):
rmtree(result_dir)
os.makedirs(result_dir)
# Get xray dicom paths
dicom_paths = [os.path.join(xray_dir, file_name)
for file_name in os.listdir(xray_dir)
if file_name.endswith('dcm')]
for dicom_path in dicom_paths:
print(f'Start to process {dicom_path}')
# Read image
ds = pydicom.dcmread(dicom_path)
pixel_array = ds.pixel_array
orig_pixel_array = pixel_array.copy()
if plot:
plt.title('Raw image')
plt.imshow(pixel_array, cmap='gray')
plt.show()
# Thresholding
pixel_array[pixel_array < 1] = 0
pixel_array[pixel_array >= 1] = 1
pixel_array = pixel_array.astype(np.uint8)
if plot:
plt.title('Thresholding')
plt.imshow(pixel_array, cmap='gray')
plt.show()
# Calculate rotation angle by minAreaRect method
contours, _ = cv2.findContours(pixel_array, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contour_w_max_area = max(contours, key = cv2.contourArea)
rect = cv2.minAreaRect(contour_w_max_area)
angle = rect[2]
if angle > 45:
angle -= 90
# Rotate image
h, w = orig_pixel_array.shape[:2]
center = rect[0]
matrix = cv2.getRotationMatrix2D(center, angle, 1.0)
rotated = cv2.warpAffine(orig_pixel_array, matrix, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_CONSTANT)
if plot:
plt.title('Rotated image')
plt.imshow(rotated, cmap='gray')
plt.show()
# Crop edge
xs, ys = np.nonzero(rotated)
x_min,x_max = xs.min(), xs.max()
y_min, y_max = ys.min(), ys.max()
cropped = rotated[x_min:x_max+1, y_min:y_max+1]
cropped = cropped.astype(np.uint16)
if plot:
plt.title('Cropped image')
plt.imshow(cropped, cmap='gray')
plt.show()
# Save it
save_path = os.path.join(result_dir, os.path.basename(dicom_path))
ds.PixelData = cropped
ds.Rows = cropped.shape[0]
ds.Columns = cropped.shape[1]
pydicom.filewriter.dcmwrite(save_path, ds)
if plot:
ds = pydicom.dcmread(save_path)
pixel_array = ds.pixel_array
plt.title('Saved image')
plt.imshow(pixel_array, cmap='gray')
plt.show()
print('done.')

134
Q1/env.yaml Normal file
View File

@ -0,0 +1,134 @@
name: Q1
channels:
- conda-forge
dependencies:
- aom=3.5.0
- brotli=1.1.0
- brotli-bin=1.1.0
- bzip2=1.0.8
- c-ares=1.19.1
- ca-certificates=2023.7.22
- cairo=1.16.0
- certifi=2023.7.22
- contourpy=1.1.1
- cycler=0.11.0
- dav1d=1.2.1
- expat=2.5.0
- ffmpeg=6.0.0
- font-ttf-dejavu-sans-mono=2.37
- font-ttf-inconsolata=3.000
- font-ttf-source-code-pro=2.038
- font-ttf-ubuntu=0.83
- fontconfig=2.14.2
- fonts-conda-ecosystem=1
- fonts-conda-forge=1
- fonttools=4.42.1
- freetype=2.12.1
- fribidi=1.0.10
- gettext=0.21.1
- gmp=6.2.1
- gnutls=3.7.8
- graphite2=1.3.13
- harfbuzz=8.2.0
- hdf5=1.14.2
- icu=73.2
- jasper=4.0.0
- kiwisolver=1.4.5
- krb5=1.21.2
- lame=3.100
- lcms2=2.15
- lerc=4.0.0
- libabseil=20230802.1
- libaec=1.0.6
- libass=0.17.1
- libblas=3.9.0
- libbrotlicommon=1.1.0
- libbrotlidec=1.1.0
- libbrotlienc=1.1.0
- libcblas=3.9.0
- libcurl=8.3.0
- libcxx=16.0.6
- libdeflate=1.19
- libedit=3.1.20191231
- libev=4.33
- libexpat=2.5.0
- libffi=3.4.2
- libgfortran=5.0.0
- libgfortran5=13.2.0
- libglib=2.78.0
- libiconv=1.17
- libidn2=2.3.4
- libjpeg-turbo=2.1.5.1
- liblapack=3.9.0
- liblapacke=3.9.0
- libnghttp2=1.52.0
- libopenblas=0.3.24
- libopencv=4.8.0
- libopenvino=2023.0.2
- libopenvino-arm-cpu-plugin=2023.0.2
- libopenvino-auto-batch-plugin=2023.0.2
- libopenvino-auto-plugin=2023.0.2
- libopenvino-hetero-plugin=2023.0.2
- libopenvino-ir-frontend=2023.0.2
- libopenvino-onnx-frontend=2023.0.2
- libopenvino-paddle-frontend=2023.0.2
- libopenvino-pytorch-frontend=2023.0.2
- libopenvino-tensorflow-frontend=2023.0.2
- libopenvino-tensorflow-lite-frontend=2023.0.2
- libopus=1.3.1
- libpng=1.6.39
- libprotobuf=4.23.4
- libsqlite=3.43.0
- libssh2=1.11.0
- libtasn1=4.19.0
- libtiff=4.6.0
- libunistring=0.9.10
- libvpx=1.13.0
- libwebp-base=1.3.2
- libxcb=1.15
- libxml2=2.11.5
- libzlib=1.2.13
- llvm-openmp=16.0.6
- matplotlib=3.8.0
- matplotlib-base=3.8.0
- munkres=1.1.4
- ncurses=6.4
- nettle=3.8.1
- numpy=1.26.0
- opencv=4.8.0
- openh264=2.3.1
- openjpeg=2.5.0
- openssl=3.1.2
- p11-kit=0.24.1
- packaging=23.1
- pcre2=10.40
- pillow=10.0.1
- pip=23.2.1
- pixman=0.40.0
- pthread-stubs=0.4
- pugixml=1.13
- py-opencv=4.8.0
- pydicom=2.4.3
- pyparsing=3.1.1
- python=3.10.12
- python-dateutil=2.8.2
- python_abi=3.10
- readline=8.2
- setuptools=68.2.2
- six=1.16.0
- snappy=1.1.10
- svt-av1=1.7.0
- tbb=2021.10.0
- tk=8.6.12
- tornado=6.3.3
- tzdata=2023c
- unicodedata2=15.0.0
- wheel=0.41.2
- x264=1!164.3095
- x265=3.5
- xorg-libxau=1.0.11
- xorg-libxdmcp=1.1.3
- xz=5.2.6
- zlib=1.2.13
- zstd=1.5.5
prefix: /Users/xiao_deng/miniforge3/envs/Q1