我从BrainWeb进行了10次灰度脑部MRI扫描。它们存储为4d numpy数组brains
,形状为(10, 181, 217, 181)
。 10个大脑中的每一个都由沿着z平面的181个切片(穿过头部顶部到颈部)组成,其中每个切片在x(耳朵到耳朵)和y(眼睛到z)中是181像素乘217像素。后面的飞机分别是飞机。
所有大脑都是dtype('float64')
型。所有大脑的最大像素强度为~1328
,最小值为~0
。例如,对于第一个大脑,我通过brains[0].max()
计算得出1328.338086605072
和brains[0].min()
给出0.0003886114541273855
。下面是brain[0]
:
我想通过重新调整从[0, 1328]
到{0, 1}
的像素强度来对所有这些大脑图像进行二值化。 我的方法是否正确?
我首先将像素强度标准化为[0, 1]
:
normalized_brains = brains/1328
然后使用二项分布对每个像素进行二值化:
binarized_brains = np.random.binomial(1, (normalized_brains))
绘制的结果看起来是正确的:
0像素强度表示黑色(背景),1像素强度表示白色(脑)。
我通过实现另一种方法来实现this post来规范化图像,但它只给了我一个黑色图像。这是因为np.finfo(np.float64)
是1.7976931348623157e+308
,因此标准化步骤
normalized_brains = brains/1.7976931348623157e+308
刚刚返回了一个零数组,在二进制化步骤中也导致了一个零数组。
我是否使用正确的方法对图像进行二值化?
答案 0 :(得分:1)
您是否尝试过图像阈值?
这是common way二值化图像,而不是尝试应用随机二项分布。你可以尝试类似的东西:
binarized_brains = (brains > threshold_value).astype(int)
根据图像值是否小于或大于您选择的阈值返回0和1的数组。
您必须尝试使用阈值来为图像找到最佳阈值,但不需要先对其进行标准化。
如果效果不佳,您还可以尝试使用skimage filters包中提供的阈值选项。
答案 1 :(得分:1)
将图像转换为二进制图像的方法基本上等于随机抖动,这是在二进制介质上创建灰度值错觉的不良方法。老式印刷品是一种二元媒介,他们对几百年来印刷中的灰色值照片进行了精细调整。此过程称为halftoning,部分由纸上墨水的属性决定,我们不必在二进制图像中处理。
那么人们在印刷品之外提出了哪些方法呢?有序抖动(主要是Bayer matrix)和error diffusion dithering。阅读更多关于维基百科上的抖动的信息。几年前我写了blog post showing how to implement all of these methods in MATLAB。
我建议您为特定应用使用误差扩散抖动。以下是MATLAB中的一些代码(取自上面我喜欢的博客文章)中的Floyd-Steinberg算法,我希望你能将它翻译成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)
在应用抖动之前重新采样图像可以大大改善结果:
img = imresize(img,4);
% (repeat code above)
imshow(out)
注意以上过程要求输入在[0,255]范围内。它很容易适应不同的范围,比如[0,1328]或[0,1],但也很容易将图像缩放到[0,255]范围。
答案 2 :(得分:0)
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)