首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >二值化图像数据

二值化图像数据
EN

Stack Overflow用户
提问于 2018-03-10 14:17:08
回答 3查看 4.8K关注 0票数 3

我做了10次来自BrainWeb的灰阶脑部核磁共振扫描。它们以4d numpy数组brains的形式存储,其形状为(10, 181, 217, 181)。这10个大脑中的每一个都是由181片沿z平面(穿过头顶到颈部)组成,在x(耳对耳)和y(从头到后)平面上,每一层分别是181像素乘217像素。

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

我想通过将像素强度从[0, 1328] 重标到 {0, 1}.来对所有这些脑图像进行二值化。是我的方法对吗?

为此,我首先将像素强度标准化为[0, 1]

代码语言:javascript
复制
normalized_brains = brains/1328 

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

代码语言:javascript
复制
binarized_brains = np.random.binomial(1, (normalized_brains))

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

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

我尝试了另一种方法来规范来自这个职位的图像,但它只给了我一个黑色的图像。这是因为np.finfo(np.float64)1.7976931348623157e+308,所以规范化步骤

代码语言:javascript
复制
normalized_brains = brains/1.7976931348623157e+308

刚刚返回了一个零数组,在二进制化步骤中,这也导致了一个零数组。

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-03-11 05:08:04

将图像转换为二值图像的方法基本上相当于随机抖动,这是在二进制介质上创建灰色值错觉的糟糕方法。老式印刷术是一种二元媒介,它们经过几个世纪的精细调整,在印刷品中表现出灰色价值的照片。这一过程被称为半调,部分是由纸张上油墨的性质形成的,我们不需要在二值图像中处理。

那么,人们想出了什么方法在印刷之外呢?有序抖动(主要为拜耳矩阵)和误差扩散抖动。在维基百科上阅读更多关于抖动的信息。几年前我写了一个博客文章展示了如何在MATLAB中实现所有这些方法。

我建议您在特定的应用程序中使用错误扩散抖动。下面是MATLAB中为算法编写的一些代码(摘自我上面喜欢的博客文章),我希望您可以将其翻译成Python:

代码语言:javascript
复制
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)

在应用抖动之前对图像进行重新采样大大提高了结果:

代码语言:javascript
复制
img = imresize(img,4);
% (repeat code above)
imshow(out)

注意到,上面的进程期望输入在0,255范围内。很容易适应不同的范围,比如0,1328或0,1,但也很容易将图像缩放到0,255范围。

票数 2
EN

Stack Overflow用户

发布于 2018-03-10 16:11:58

你试过图像的阈值了吗?

这是一个用于图像二值化的共同方式,而不是试图应用随机的二项分布。你可以尝试这样的方法:

代码语言:javascript
复制
binarized_brains = (brains > threshold_value).astype(int)

它根据图像值是否小于或大于所选阈值返回0和1s数组。

您将不得不试验阈值为您的图像找到最佳的阈值,但它不需要首先规范化。

如果这不能很好地工作,您也可以尝试使用skimage滤波器包中可用的阈值选项。

票数 1
EN

Stack Overflow用户

发布于 2018-10-24 11:04:21

代码语言:javascript
复制
IT is easy in OpenCV. as mentioned a very common way is defining a threshold, But your result looks like you are allocating random values to your intensities instead of thresholding it. 

import cv2
im = cv2.imread('brain.png', cv2.CV_LOAD_IMAGE_GRAYSCALE)
(th, brain_bw) = cv2.threshold(imy, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
th = (DEFINE HERE)
im_bin = cv2.threshold(im, th, 255, cv
cv2.imwrite('binBrain.png', brain_bw)

binBrain

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49210078

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档