我正在分析医学图像。所有图像都有一个带位置的标记。看起来像这样
此图像中的“TRH RMLO”注释,但在其他图像中可能有所不同。尺寸也各不相同。图像被裁剪,但您看到组织正在右侧开始。 我发现这些标记的存在会扭曲我的分析。
如何删除它们?
我像这样加载python中的图像
import dicom
import numpy as np
img = dicom.read_file(my_image.dcm)
img_array = img.pixel_array
然后图像是一个numpy数组。白色文本总是被大的黑色区域包围(黑色值为零)。标记在每个图像中处于不同的位置。
如何在不伤害组织数据的情况下删除白色文本。
更新
添加了第二张图片
UPDATE2 : 这是两个原始的dicom文件。所有个人信息均已删除。编辑:已删除
答案 0 :(得分:4)
查看您提供的图像的实际像素值,您可以看到标记几乎是(99.99%)纯白色,这不会出现在图像的其他位置,因此您可以使用简单的99.99%阈值将其隔离
我更喜欢命令行中的 ImageMagick ,所以我会这样做:
convert sample.dcm -threshold 99.99% -negate mask.png
convert sample.dcm mask.png -compose darken -composite result.jpg
当然,如果样本图像不具代表性,您可能需要更加努力。我们来看看......
如果简单阈值对您的图像不起作用,我会查看“Hit and Miss Morphology”。基本上,您将图像阈值设置为纯黑色和白色 - 大约90%说,然后您查找特定形状,例如标签上的角标记。因此,如果我们想在黑色背景上查找白色矩形的左上角,我们使用0
表示“此像素必须为黑色”,{{1表示“此像素必须为白色”而1
表示“我们不关心”,我们将使用此模式:
-
希望你能在那里看到一个白色矩形的左上角。在终端中就是这样:
0 0 0 0 0
0 1 1 1 1
0 1 - - -
0 1 - - -
0 1 - - -
现在我们还想查找右上角,左下角和右下角,因此我们需要旋转模式,当您添加{{1}时, ImageMagick 可以轻松完成标志:
convert sample.dcm -threshold 90% \
-morphology HMT '5x5:0,0,0,0,0 0,1,1,1,1 0,1,-,-,- 0,1,-,-,- 0,1,-,-,-' result.png
希望您现在可以看到划分徽标角落的点,因此我们可以要求 ImageMagick 修剪所有无关黑色的图像,然后留下白点然后告诉我们边界框:
>
所以,如果我现在在这些坐标周围画一个红色框,你可以看到标签被检测到的位置 - 当然在实践中我会画一个黑盒子来覆盖它,但我在解释这个想法:
convert sample.dcm -threshold 90% \
-morphology HMT '5x5>:0,0,0,0,0 0,1,1,1,1 0,1,-,-,- 0,1,-,-,- 0,1,-,-,-' result.png
如果您希望脚本自动执行此操作,我会使用类似的内容,将其保存为cconvert sample.dcm -threshold 90% \
-morphology HMT '5x5>:0,0,0,0,0 0,1,1,1,1 0,1,-,-,- 0,1,-,-,- 0,1,-,-,-' -format %@ info:
308x198+1822+427
:
convert sample.dcm -fill "rgba(255,0,0,0.5)" -draw "rectangle 1822,427 2130,625" result.png
然后你会这样做以使其可执行:
HideMarker
然后像这样运行:
#!/bin/bash
input="$1"
output="$2"
# Find corners of overlaid marker using Hit and Miss Morphology, then get crop box
IFS="x+" read w h x1 y1 < <(convert "$input" -threshold 90% -morphology HMT '5x5>:0,0,0,0,0 0,1,1,1,1 0,1,-,-,- 0,1,-,-,- 0,1,-,-,-' -format %@ info:)
# Calculate bottom-right corner from top-left and dimensions
((x1=x1-1))
((y1=y1-1))
((x2=x1+w+1))
((y2=y1+h+1))
convert "$input" -fill black -draw "rectangle $x1,$y1 $x2,$y2" "$output"
答案 1 :(得分:1)
如果这些注释位于DICOM文件中,则可以通过几种方式存储它们(请参阅https://stackoverflow.com/a/4857782/1901261)。只需从文件中删除60xx组属性即可清除当前支持的方法。
对于已弃用的方法(仍然常用),您可以手动清除未使用的高位注释,而不会弄乱其他图像数据。类似的东西:
int position = object.getInt( Tag.OverlayBitPosition, 0 );
if( position == 0 ) return;
int bit = 1 << position;
int[] pixels = object.getInts( Tag.PixelData );
int count = 0;
for( int pix : pixels )
{
int overlay = pix & bit;
pixels[ count++ ] = pix - overlay;
}
object.putInts( Tag.PixelData, VR.OW, pixels );
如果这些确实被刻录到图像数据中,您可能会在此处使用其他建议之一。
答案 2 :(得分:1)
我有另一个想法。这个解决方案是使用python在OpenCV中。这是一个相当的解决方案。
答案 3 :(得分:0)
好处是,这些水印可能是完全黑色的,这使得它更容易(尽管如果根据指定的用途删除它是有疑问的;许可证的东西)。
没有专家,这里有一个想法。它可能是针对这个问题量身定制的一种非常强大的方法的草图,但你必须决定实现的复杂性和安全性。算法复杂度(非常依赖于图像统计)是值得的:
0
二值化
1
2
3
进行一些连通分量计算以获得一些垂直和水平线的对象
现在您可以尝试使用以下知识的不同候选组件(8个实际组件)
4 - 从这些边框计算矩形 - 加宽几个像素(超参数) - 遮挡那个矩形
这是基本方法。
这个工作要少得多,使用更专业的工具并在开幕式中假设事实:
步骤
仅限草图:我的想法是在图像上以某种方式使用类似binary-closing的东西来构建源像素的完全连接组件(同时填充小间隙/孔),这样我们就得到了一个大组件描述医学数据,一个描述水印。然后删除较小的一个。
答案 4 :(得分:0)
标记位于每张图像的不同位置。
我的假设:
=&GT;建议:
使用OCR查找位置(例如,使用Tesseract在本地查找,或使用OCR.space等在线API)。您将获得以JSON返回的单词的边界框:
"TextOverlay" : {
"Lines" : [
{
"Words": [
{
"WordText": "RMLO",
"Left": 106,
"Top": 91,
"Height": 9,
"Width": 11
},
现在你有了坐标,你可以将矩形遮挡。
此解决方案符合Sascha的第二个选项。
答案 5 :(得分:0)
我确信这可以进行优化,但是......你可以创建4个大小为3x3或4x4的补丁,并使用注释文本周围框架的每个角落的像素值的确切内容对它们进行初始化。然后,您可以遍历整个图像(或者仅在黑色区域中进行一些智能初始化)并找到这些修补程序的完全匹配。在组织中你不太可能有相同的规则结构(90度角被0附近包围),所以这可能会给你一个边界框。
答案 6 :(得分:0)
更简单的一个仍然可能!!!。
在(img_array = img.pixel_array)
之后实现以下内容img_array [img_array&gt; X] = Y
其中X是您希望在此之后消除的强度阈值。 Y也是您要考虑的强度值而不是。
例如: img_array [img_array&gt; 4000] = 0
用黑色强度0替换大于4000的白质。