知乎预处理概念https://www.zhihu.com/question/417508279/answer/1461278406 预处理是肝脏分割重要的一步,良好的预处理过程可以有效的提高分割的准度。
窗口设置是CT扫描的图像处理功能,有助于突出显示关键的解剖结构/发现,从而使图像解释尽可能容易。单位Hounsfield unites(HU)。其中,HU值越高,对象越密集。
调整窗口宽度:
增大窗口宽度将降低图像的对比度:随着窗口宽度的增加,将需要更大的密度变化来改变代表某个HU单位的灰色阴影。由于更多的结构看起来相似(尽管密度不同),因此会导致对比度下降。
减小窗口宽度将增加 图像的对比度: 随着窗口宽度的减小,密度的较小变化将导致研究图像的颜色发生变化。由于密度接近的结构将具有不同的灰色/白色/黑色阴影,因此将提供更高的对比度。
调整窗位:
增大窗位将降低图像的亮度: 随着窗口级别的增加,图像将变得更暗。这是因为随着级别的增加,将需要更高的HU值才能将密度表示为白色。
减小窗位将增加图像的亮度: 随着窗口级别的降低,图像将变得更亮。这是因为随着水平的降低,需要较低的HU值才能将密度表示为白色
肝脏窗口
视窗设定: (W:160,L:35)
优点:该窗口类似于腹部窗口,但是利用较窄的窗口来增加肝实质中的对比度(以便使肝脏病变的查找更容易)。
示例1:目录:1 导入相应的包 2 读取Dicom图像数据 3 设置CT图像的窗宽和窗位 4 获取Dicom图像的tag信息 5 结果保存及可视化。——Python代码
示例2:目录——链接
1.2.1 3D图像转2D图像--(偏间距--do what?):加调窗/窗位
import numpy as np
import os # 用于遍历文件夹
import nibabel as nib # 用nibabel包打开nii文件
import imageio # 图像io
center = 100 #肝脏的窗宽窗位
width = 140
# def get_pixel_hu(scan):
# img = scan.pixel_array
# img = img.astype(np.int16)
#
# # Convert to Hounsfield units (HU)
# intercept = scan.RescaleIntercept
# slope = scan.RescaleSlope
# if slope != 1:
# img = slope * img.astype(np.float64)
# img = img.astype(np.int16)
#
# img += np.int16(intercept)
# return np.array(img, dtype=np.int16)
def nii_to_image(niifile):
filenames = os.listdir(filepatha) # 指定nii所在的文件夹
for f in filenames:
# 开始读取nii文件
img_path = os.path.join(filepatha, f)
img = nib.load(img_path, ) # 读取nii
img_fdata = img.get_fdata()
# fnamex = f.replace('.nii', ' -x') # 去掉nii的后缀名创建x方向2D图像文件夹
# img_f_pathx = os.path.join(imgfile, fnamex) # 创建nii对应的x方向2D图像的文件夹
# if not os.path.exists(img_f_pathx):
# os.mkdir(img_f_pathx) # 新建文件夹
#
# fnamey = f.replace('.nii', ' -y') # 去掉nii的后缀名创建y方向2D图像文件夹
# img_f_pathy = os.path.join(imgfile, fnamey) # 创建nii对应的y方向2D图像的文件夹
# if not os.path.exists(img_f_pathy):
# os.mkdir(img_f_pathy) # 新建文件夹
fnamez = f.replace('.nii', ' -z') # 去掉nii的后缀名创建z方向2D图像文件夹
img_f_pathz = os.path.join(imgfile, fnamez) # 创建nii对应的z方向2D图像图像的文件夹
if not os.path.exists(img_f_pathz):
os.mkdir(img_f_pathz) # 新建文件夹
# 开始转换为图像
# 可能用到的图像变换
# 旋转操作利用numpy 的rot90(a,b)函数 a为数据 b为旋转90度的多少倍 !正数逆时针 负数顺时针
# 左右翻转 : img_lr = np.fliplr(img) 上下翻转: img_ud = np.flipud(img)
min = (2 * center - width) / 2.0 + 0.5
max = (2 * center + width) / 2.0 + 0.5
dFactor = 255.0 / (max - min)
(x, y, z) = img.shape # 获取图像的3个方向的维度
# for i in range(x): # x方向
# silce = img_fdata[i, :, :] # 选择哪个方向的切片都可以 不要忘了i改到对应方向
# imageio.imwrite(os.path.join(img_f_pathx, '{}.png'.format(i)), silce) # 保存图像
# for i in range(y): # y方向
# silce = np.rot90(img_fdata[:, i, :], 1)
# imageio.imwrite(os.path.join(img_f_pathy, '{}.png'.format(i)), silce) # 保存图像
for i in range(z): # z方向
silce = np.rot90(img_fdata[:, :, i], -1)
imageio.imwrite(os.path.join(img_f_pathz, '{}.jpg'.format(i)), silce) # 保存图像
for i in range(z): # z是图像的序列
silce =np.fliplr(np.rot90(img_fdata[:, :, i],-1)) # 选择哪个方向的切片都可以
silce = silce - min
silce = np.trunc(silce * dFactor)
silce[silce < 0.0] = 0
silce[silce > 255.0] = 255 # 转换为窗位窗位之后的数据
imageio.imwrite(os.path.join(img_f_pathz, '{}.jpg'.format(i)), silce) # 保存图
if __name__ == '__main__':
filepatha = 'D:/CT/NII-1'
imgfile = 'D:/CT/JPG PNG'
nii_to_image(filepatha)
直方图均衡代码----可视
import cv2 # 仅用于读取图像矩阵
import matplotlib.pyplot as plt
import numpy as np
gray_level = 256 # 灰度级
def pixel_probability(img):
"""
计算像素值出现概率
:param img:
:return:
"""
assert isinstance(img, np.ndarray)
prob = np.zeros(shape=(256))
for rv in img:
for cv in rv:
prob[cv] += 1
r, c = img.shape
prob = prob / (r * c)
return prob
def probability_to_histogram(img, prob):
"""
根据像素概率将原始图像直方图均衡化
:param img:
:param prob:
:return: 直方图均衡化后的图像
"""
prob = np.cumsum(prob) # 累计概率
img_map = [int(i * prob[i]) for i in range(256)] # 像素值映射
# 像素值替换
assert isinstance(img, np.ndarray)
r, c = img.shape
for ri in range(r):
for ci in range(c):
img[ri, ci] = img_map[img[ri, ci]]
return img
def plot(y, name):
"""
画直方图,len(y)==gray_level
:param y: 概率值
:param name:
:return:
"""
plt.figure(num=name)
plt.bar([i for i in range(gray_level)], y, width=1)
if __name__ == '__main__':
img = cv2.imread("D:/CT/JPG-1/volume-1 -z/66.jpg", 0) # 读取灰度图
cv2.imshow("D:/CT/JPG-1/volume-1 -z/66.jpg", img)
prob = pixel_probability(img)
plot(prob, "原图直方图")
# 直方图均衡化
img = probability_to_histogram(img, prob)
cv2.imwrite("source_hist.jpg", img) # 保存图像
cv2.imshow("source_hist", img)
prob = pixel_probability(img)
plot(prob, "直方图均衡化结果")
plt.show()
cv2.waitKey(0)
"""图像缩放"""
import cv2
import numpy as np
# 读取图片
src = cv2.imread('source_hist.jpg')
# 图像缩放
result = cv2.resize(src, (300, 300))
print
result.shape
# 显示图像
cv2.imshow("src", src)
cv2.imshow("result", result)
cv2.imwrite("narrow.jpg", result) # 保存图像
# 等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
"""旋转"""
import cv2
import numpy as np
# 读取图片
src = cv2.imread('source_hist.jpg')
# 原图的高、宽 以及通道数
rows, cols, channel = src.shape
# 绕图像的中心旋转
# 参数:旋转中心 旋转度数 scale
M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 60, 1)
# 参数:原始图像 旋转参数 元素图像宽高
rotated = cv2.warpAffine(src, M, (cols, rows))
# 显示图像
cv2.imshow("src", src)
cv2.imshow("rotated", rotated)
cv2.imwrite("rotate.jpg", rotated) # 保存图像
# 等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
"""反转"""
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取图片
img = cv2.imread('source_hist.jpg')
src = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 图像翻转
# 0以X轴为对称轴翻转 >0以Y轴为对称轴翻转 <0X轴Y轴翻转
img1 = cv2.flip(src, 0)
img2 = cv2.flip(src, 1)
img3 = cv2.flip(src, -1)
# 显示图形
titles = ['Source', 'Image1', 'Image2', 'Image3']
images = [src, img1, img2, img3]
for i in range(4):
plt.subplot(2, 2, i + 1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
"""平移"""
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取图片
img = cv2.imread('source_hist.jpg')
image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 图像平移 下、上、右、左平移
M = np.float32([[1, 0, 0], [0, 1, 100]])
img1 = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))
M = np.float32([[1, 0, 0], [0, 1, -100]])
img2 = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))
M = np.float32([[1, 0, 100], [0, 1, 0]])
img3 = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))
M = np.float32([[1, 0, -100], [0, 1, 0]])
img4 = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))
# 显示图形
titles = ['Image1', 'Image2', 'Image3', 'Image4']
images = [img1, img2, img3, img4]
for i in range(4):
plt.subplot(2, 2, i + 1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
cv2.imwrite("move.jpg", img1) # 保存图像
import os
import cv2
import numpy as np
path = 'JPG-2/volume-1 -z'#批量图像数据处理读取路径
all = os.walk(path)
for path, dir, filelist in all:
for filename in filelist:
if filename.endswith('.jpg'):
filepath = os.path.join(path, filename)
img = cv2.imread(filepath)
img = cv2.resize(img, (256, 256))#图像尺寸调整
#图像旋转#
rows, cols, channel = img.shape
# 绕图像的中心旋转
# 参数:旋转中心 旋转度数 scale
M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 60, 1)
# 参数:原始图像 旋转参数 元素图像宽高
img = cv2.warpAffine(img, M, (cols, rows))
#图像旋转#
#直方图均衡#
b = img[:, :, 0]
g = img[:, :, 1]
r = img[:, :, 2]
h_b = cv2.equalizeHist(b)
h_g = cv2.equalizeHist(g)
h_r = cv2.equalizeHist(r)
dst_img = cv2.merge((h_b, h_g, h_r))
dst1 = np.hstack([b, g, r])
dst2 = np.hstack([h_b, h_g, h_r])
dst = np.vstack([dst1, dst2])
img = np.hstack([img, dst_img])
cv2.imwrite(filepath, dst_img)
print(filepath)
NII文件转JPG/PN——网盘/CT
肿瘤和肝脏可以分开可视化
分割代码【代码】