从RayStation Microsoft SQL数据库中提取DICOM图像

时间:2016-12-12 15:00:19

标签: sql-server dicom

我获得了备份RayStation数据库RS_Patients.bak,并且我正在尝试提取和查看存储在其中的DICOM图像。麻烦是双重的:我不知道2000多个字段中的哪一个(或字段的组合)引用图像本身,即使我知道图像在哪里,我也不知道如何提取它们从数据库转换为.dcm个文件。

通过检查架构,我发现了一些大varbinary字段(BLOB)的字段,我认为它们可能是我正在寻找的字段。为数据库启用了FileStream,并且有一个FS目录。我尝试使用bcp Utility将这些字段下载到文件中,但是没有生成成功的DICOM。

有没有人有这种数据库/图像结构的经验?拉出和查看图像的任何其他建议?你认为图像是由几个字段而不是一个字段组成的吗?我们认为带有DICOM图像标题的图像字段旁边有一些字段:在表格callefd ImageStack中,在名为PixelData的字段旁边,有一些字段称为PixelSize,{ {1}},SlicePosition

另外,如果你能想到另一个地方问这个,我也会很感激。

根据@mcNets建议编辑,bcp命令:

NrPixels

1 个答案:

答案 0 :(得分:1)

一般来说,您无法使用SQL Server结果直接写入图像数据。 bcp.exe也不会帮助你。您需要使用能够理解二进制字符串是原始文件数据的内容,或者,因为这是一个FILESTREAM,所以使用能够为您提供SQL Server上文件路径的内容。我对FILESTREAM的经验有限,但这就是我要做的事。

我无法明确回答要使用哪个字段。这取决于应用程序。如果我们假设DICOM图像存储在FILESTREAM中,那么您可以找到可用的FILESTREAM列:

select t.name TableName
    ,c.name ColumnName 
from sys.tables t 
join sys.columns c 
    on c.object_id = t.object_id
where c.is_filestream = 1

如果我们还假设DICOM图像存储为原始图像文件 - 即,如果它们保存在PACS光盘上,它们将是完整的二进制版本 - 那么您可以运行它来确定路径每个文件由ID:

select TableName_Id
    ,FileData.PathName()
from TableName.ColumnName

FILESTREAM列的PathName()功能的文档是here

如果您想通过传统意义上的SQL Server提取数据,那么我可能会使用PowerShell脚本来执行此操作。这样做的好处是可以让您使用服务器中的任意数据来命名文件。此方法还具有可以在任何二进制或varbinary列上工作的优点。作为缺点,此方法将更慢并使用更多磁盘空间,因为服务器必须读取数据,将其发送到客户端,然后客户端将数据写入磁盘:

$SqlQuery = "select Name, FileData from TableName.ColumnName";
$OutputPath = 'C:\OutputPath';

$SqlServer = 'ServerName';
$SqlDatabase = 'DatabaseName';
$SqlConnectionString = 'Data Source={0};Initial Catalog={1};Integrated Security=SSPI' -f $SqlServer, $SqlDatabase;

$SqlCommand = New-Object -TypeName System.Data.SqlClient.SqlCommand;
$SqlCommand.CommandText = $SqlQuery;

$SqlConnection = New-Object -TypeName System.Data.SqlClient.SqlConnection -ArgumentList $SqlConnectionString;
$SqlCommand.Connection = $SqlConnection;

$SqlConnection.Open();
$SqlDataReader = $SqlCommand.ExecuteReader();

while ($SqlDataReader.Read()) {
    $OutputFileName = Join-Path -Path $OutputPath -ChildPath "$($SqlDataReader['Name']).dcm"
    [System.IO.File]::WriteAllBytes($OutputFileName,$SqlDataReader['FileData']);
}
$SqlConnection.Close();
$SqlConnection.Dispose();

也可以使用FILESTREAM函数返回Win32 API句柄,但我从未这样做过。