对图像数据进行二值化 [英] Binarize image data

查看:428
本文介绍了对图像数据进行二值化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have 10 greyscale brain MRI scans from BrainWeb. They are stored as a 4d numpy array, brains, with shape (10, 181, 217, 181). Each of the 10 brains is made up of 181 slices along the z-plane (going through the top of the head to the neck) where each slice is 181 pixels by 217 pixels in the x (ear to ear) and y (eyes to back of head) planes respectively.

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

All of the brains are type dtype('float64'). The maximum pixel intensity across all brains is ~1328 and the minimum is ~0. For example, for the first brain, I calculate this by brains[0].max() giving 1328.338086605072 and brains[0].min() giving 0.0003886114541273855. Below is a plot of a slice of a brain[0]:

我想通过将像素强度从[0, 1328]调整为{0, 1} ,对所有这些大脑图像进行二值化处理. 我的方法正确吗?

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

I do this by first normalising the pixel intensities to [0, 1]:

normalized_brains = brains/1328 

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

And then by using the binomial distribution to binarize each pixel:

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

绘制的结果看起来正确:

The plotted result looks correct:

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

A 0 pixel intensity represents black (background) and 1 pixel intensity represents white (brain).

我通过实施另一种方法来规范化

I experimented by implementing another method to normalise an image from this post but it gave me just a black image. This is because np.finfo(np.float64) is 1.7976931348623157e+308, so the normalization step

normalized_brains = brains/1.7976931348623157e+308

只返回了一个零数组,在二值化步骤中,它也导致了一个零数组.

just returned an array of zeros which in the binarizition step also led to an array of zeros.

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

推荐答案

您将图像转换为二进制图像的方法基本上等于随机抖动,这是一种在二进制介质上产生灰度值幻觉的不良方法.老式印刷品是一种二元介质,他们已经微调了几个世纪以来在印刷中代表灰度值照片的方法.此过程称为 halftoning ,并且部分地取决于纸上墨水的性质,不必处理二进制图像.

Your method of converting the image to a binary image basically amounts to random dithering, which is a poor method of creating the illusion of grey values on a binary medium. Old-fashioned print is a binary medium, they have fine-tuned the methods to represent grey-value photographs in print over centuries. This process is called halftoning, and is shaped in part by properties of ink on paper, that we do not have to deal with in binary images.

那么人们在印刷品之外想出了什么方法呢?有序抖动(主要是 Bayer矩阵)和博客文章,其中显示了如何在MATLAB中实现所有这些方法年前.

So what methods have people come up with outside of print? Ordered dithering (mostly Bayer matrix), and error diffusion dithering. Read more about dithering on Wikipedia. I wrote a blog post showing how to implement all of these methods in MATLAB some years ago.

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

I would recommend you use error diffusion dithering for your particular application. Here is some code in MATLAB (taken from my blog post liked above) for the Floyd-Steinberg algorithm, I hope that you can translate this to Python:

img = imread('https://i.stack.imgur.com/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)

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

Resampling the image before applying the dithering greatly improves the results:

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

注意,以上过程期望输入在[0,255]范围内.很容易适应不同的范围,例如[0,1328]或[0,1],但也很容易将图像缩放到[0,255]范围.

NOTE that the above process expects the input to be in the range [0,255]. It is easy to adapt to a different range, say [0,1328] or [0,1], but it is also easy to scale your images to the [0,255] range.

这篇关于对图像数据进行二值化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆