【问题标题】:Extract DICOM Image From RayStation Microsoft SQL Database从 RayStation Microsoft SQL 数据库中提取 DICOM 图像
【发布时间】:2016-12-12 15:00:19
【问题描述】:

我获得了一个备份 RayStation 数据库 RS_Patients.bak,我正在尝试提取和查看存储在其中的 DICOM 图像。麻烦有两个方面:我不知道 2,000 多个字段(或字段组合)中的哪一个是指图像本身,即使我知道图像在哪里,我也不知道如何提取他们从数据库到.dcm文件。

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

有人对这种数据库/图像结构有任何经验吗?关于拉出和查看图像的任何其他建议?你认为图像会由几个字段而不是一个字段组成吗?在我们认为的图像字段旁边有一些字段,其中包含 DICOM 图像的标题:在表 callefd ImageStack 中,在一个名为 PixelData 的字段旁边,有一些字段名为 PixelSizeSlicePositionNrPixels等。

另外,如果你能想到其他地方问这个问题,我也将不胜感激。

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

DECLARE @Command Varchar(400)
SET @Command = 'bcp "SELECT TOP 1 PixelData FROM RayStationPatientDB.dbo.ImageStack" queryout "C:\Users\Administrator\Documents\test.dcm" -S WIN-123ABC\MSSQLSERVER01 -T -w'
EXEC xp_cmdshell @Command

【问题讨论】:

标签: sql-server dicom


【解决方案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 句柄,但我从未这样做过。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-27
    • 2011-07-28
    相关资源
    最近更新 更多