【问题标题】:Python opencv and dicom filesPython opencv 和 dicom 文件
【发布时间】:2017-03-31 10:27:01
【问题描述】:

在尝试将 opencv 与 dicom 单色文件一起使用时,我只看到了一个解决方案:首先将 RGB 中像素值在 -2000(黑色)到 2000(白色)之间的单色 dicom 文件转换为 0

您知道如何使流程自动化和加速吗?或者只是一个好主意? 代码是:

    # import the necessary packages
from imutils import contours
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
import scipy
from skimage import measure
import numpy as np # numeric library needed
import pandas as pd #for dataframe
import argparse # simple argparser
import imutils
import cv2  # for opencv image recognising tool
import dicom
from tkinter import Tk
from tkinter.filedialog import askopenfilename
import pdb

#filename = askopenfilename() # show an "Open" dialog box and return the path to the selected file
#filename ="../inputs/12e0e2036f61c8a52ee4471bf813c36a/7e74cdbac4c6db70bade75225258119d.dcm"
dicom_file = dicom.read_file(filename) ## original dicom File
#### a dicom monochrome file has pixel value between approx -2000 and +2000, opencv doesn't work with it#####
#### in a first step we transform those pixel values in (R,G,B)
### to have gray in RGB, simply give the same values for R,G, and B, 
####(0,0,0) will be black, (255,255,255) will be white,

## the threeshold to be automized with a proper quartile function of the pixel distribution
black_threeshold=0###pixel value below 0 will be black,
white_threeshold=1400###pixel value above 1400 will be white
wt=white_threeshold
bt=black_threeshold

###### function to transform a dicom to RGB for the use of opencv, 
##to be strongly improved, as it takes to much time to run,
## and the linear process should be replaced with an adapted weighted arctan function.
def DicomtoRGB(dicomfile,bt,wt):
    """Create new image(numpy array) filled with certain color in RGB"""
    # Create black blank image
    image = np.zeros((dicomfile.Rows, dicomfile.Columns, 3), np.uint8)
    #loops on image height and width
    i=0
    j=0
    while i<dicomfile.Rows:
        j=0
        while j<dicomfile.Columns:
            color = yaxpb(dicom_file.pixel_array[i][j],bt,wt) #linear transformation to be adapted
            image[i][j] = (color,color,color)## same R,G, B value to obtain greyscale
            j=j+1
        i=i+1
    return image
##linear transformation : from [bt < pxvalue < wt] linear to [0<pyvalue<255]: loss of information... 
def yaxpb(pxvalue,bt,wt):
    if pxvalue < bt:
        y=0
    elif pxvalue > wt:
        y=255
    else:
        y=pxvalue*255/(wt-bt)-255*bt/(wt-bt)
    return y



image=DicomtoRGB(dicom_file,bt=0,wt=1400)
>>image
array([[[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        ..., 
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]],

       [[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        ..., 
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]],

       [[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        ..., 
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]],

       ..., 
       [[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        ..., 
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]],

       [[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        ..., 
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]],

       [[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        ..., 
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]]], dtype=uint8)

## loading the RGB in a proper opencv format
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
## look at the gray file
cv2.imshow("gray", gray)
cv2.waitKey(0)
cv2.destroyWindow("gray")

【问题讨论】:

  • 你能修复你的代码缩进吗?

标签: python numpy opencv medical-imaging


【解决方案1】:

我认为您的问题与此有关:

...双重for循环需要时间来执行。

您可以使用 opencv 中的 remap 功能: 见this example

【讨论】:

    【解决方案2】:

    EDIT2 - 现在执行正确的转换


    我们可以使用numpy 对您的整个代码进行矢量化处理。这是一个例子:

    import numpy as np
    
    def dicom_to_rgb(img,bt,wt):
    
        # enforce boundary conditions
        img = np.clip(img,bt,wt)
    
        # linear transformation
        # multiplicative
        img = np.multiply(img,-255/(wt-bt)).astype(np.int)
        # additive
        img += 255
    
        # stack thrice on the last axis for R G B
        rgb_img = np.stack([img]*3,axis=-1)
    
        return rgb_img
    
    
        pixels = 512
        img = np.random.randint(-2000,2000,pixels**2).reshape(pixels,pixels)
        bt = 0
        wt = 1400
    
        rgb = dicom_to_rgb(img,bt,wt)
    

    或者根据您的意见:

    dicom_file = dicom.read_file(filename)
    img = np.array(dicom_file.pixel_array)
    
    rgb = dicom_to_rgb(img,wt,bt)
    

    【讨论】:

    • 谢谢,我试过你的代码,但它没有给我正确的图片:
    • 我在原始答案中混淆了wtbt。希望这可以解释不正确的图像。
    • 你好,谢谢,是的,bt 和 wt 是混合的。然后“clipped_img = np.clip(img,wt,bt)”似乎在 img 的所有像素上移动 bt,但我希望在第一点使 bt=0 以下的所有像素为黑色(在 RGB= 0),所有高于 wt=1400 的像素都是白色的(在 RGB=255 中),对于 0 到 1400 之间的像素,使线性近似为 [0;255]。
    • 我不明白。我包括了一些示例输出。你能告诉我应该有什么不同吗?
    • 知道了。我的转型走错了方向。已经修复了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-21
    • 1970-01-01
    • 2020-11-17
    相关资源
    最近更新 更多