python - 二值化图像数据

标签 python numpy image-processing computer-vision voxel

我有来自 BrainWeb 的 10 个灰度大脑 MRI 扫描.它们存储为 4d numpy 数组,brains , 形状 (10, 181, 217, 181) . 10 个大脑中的每一个都由 181 个沿 z 平面(从头顶到颈部)的切片组成,其中每个切片在 x(耳朵到耳朵)和 y(眼睛到眼睛)中的大小为 181 x 217 像素脑后)平面分别。

所有的大脑都是类型 dtype('float64') .所有大脑的最大像素强度为 ~1328最小值是 ~0 .例如,对于第一个大脑,我计算为 brains[0].max()给予 1328.338086605072brains[0].min()给予 0.0003886114541273855 .下面是 brain[0] 的切片图:

enter image description here

我想通过重新调整来自 [0, 1328] 的像素强度来将所有这些大脑图像二值化。至 {0, 1} 我的方法正确吗?

我首先将像素强度归一化为 [0, 1] :

normalized_brains = brains/1328 

然后使用二项分布对每个像素进行二值化:

binarized_brains = np.random.binomial(1, (normalized_brains))

绘制的结果看起来是正确的:

enter image description here

0 像素强度代表黑色(背景),1 像素强度代表白色(大脑)。

我通过实现另一种方法对来自 this post 的图像进行标准化进行了实验但它只给了我一个黑色图像。这是因为 np.finfo(np.float64)1.7976931348623157e+308 , 所以归一化步骤

normalized_brains = brains/1.7976931348623157e+308

只是返回了一个零数组,在二值化步骤中也产生了一个零数组。

我是否使用正确的方法对图像进行二值化?

最佳答案

您将图像转换为二进制图像的方法基本上相当于随机抖动,这是在二进制介质上创建灰度值幻觉的糟糕方法。老式打印品是一种二元媒体,几个世纪以来,他们已经微调了在打印品中表示灰度照片的方法。这个过程称为 halftoning ,并且部分由纸上墨水的属性决定,我们不必在二值图像中处理。

那么人们想出了哪些非打印方法?有序抖动(主要是 Bayer matrix )和 error diffusion dithering .在维基百科上阅读更多关于抖动的内容。我写了一个blog post showing how to implement all of these methods in MATLAB几年前。

我建议您为您的特定应用程序使用误差扩散抖动。这是 MATLAB 中的一些代码(摘 self 上面喜欢的博客文章),用于 Floyd-Steinberg 算法,我希望您可以将其转换为 Python:

img = imread('/image/d5E9i.png');
img = img(:,:,1);

out = double(img);
sz = size(out);
for ii=1:sz(1)
   for jj=1:sz(2)
      old = out(ii,jj);
      %new = 255*(old >= 128); % Original Floyd-Steinberg
      new = 255*(old >= 128+(rand-0.5)*100); % Simple improvement
      out(ii,jj) = new;
      err = new-old;
         if jj<sz(2)
            % right
            out(ii  ,jj+1) = out(ii  ,jj+1)-err*(7/16);
         end
      if ii<sz(1)
         if jj<sz(2)
            % right-down
            out(ii+1,jj+1) = out(ii+1,jj+1)-err*(1/16);
         end
            % down
            out(ii+1,jj  ) = out(ii+1,jj  )-err*(5/16);
         if jj>1
            % left-down
            out(ii+1,jj-1) = out(ii+1,jj-1)-err*(3/16);
         end
      end
   end
end

imshow(out)

enter image description here

在应用抖动之前对图像重新采样可以大大改善结果:

img = imresize(img,4);
% (repeat code above)
imshow(out)

enter image description here

注意上述过程要求输入在 [0,255] 范围内。很容易适应不同的范围,比如 [0,1328] 或 [0,1],但也很容易将图像缩放到 [0,255] 范围。

关于python - 二值化图像数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49210078/

相关文章:

python - 需要帮助找到一种使用集合返回偶尔出现一次的列表并仍保持顺序的方法吗?

python - 用numpy计算矩阵乘积

image-processing - 如何使用带有 FFMPEG 的图像创建图像?

python - Ansible:条件寄存器检查

python - 在 python 中生成图形的高内存消耗

python - 获得列表元素之间差异的更好解决方案

python - 在 numpy 中实现标准化过滤器的好方法

python - 需要返回协方差的 Python 多项式拟合函数

python - 使用python3将numpy整数类型插入到sqlite中

python - 不同字体大小的文本区域周围的边界框