我知道这个thread关于同时将黑色转换为白色和白色转换为黑色。 我想只将黑色转换为白色。 我知道thread这就是我要问的问题,但我不明白出了什么问题。
照片
代码
rgbImage = imread('ecg.png');
grayImage = rgb2gray(rgbImage); % for non-indexed images
level = graythresh(grayImage); % threshold for converting image to binary,
binaryImage = im2bw(grayImage, level);
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
% Make the black parts pure red.
redChannel(~binaryImage) = 255;
greenChannel(~binaryImage) = 0;
blueChannel(~binaryImage) = 0;
% Now recombine to form the output image.
rgbImageOut = cat(3, redChannel, greenChannel, blueChannel);
imshow(rgbImageOut);
哪个给出了
红色通道中似乎出现了问题。 黑色只是RGB中的(0,0,0),因此它的去除应该意味着将每个(0,0,0)像素变为白色(255,255,255)。 用
做这个想法redChannel(~binaryImage) = 255;
greenChannel(~binaryImage) = 255;
blueChannel(~binaryImage) = 255;
给出
所以我一定在Matlab中误解了一些东西。蓝色不应该有任何黑色。所以这最后一张图片很奇怪。
如何才能将黑色变成白色? 我想保持心电图的蓝色。
答案 0 :(得分:7)
如果我理解正确,您需要在移除文本和轴的同时提取蓝色ECG图。最好的方法是检查图像的HSV colour space。 HSV色彩空间非常适合辨别色彩,就像人类一样。我们可以清楚地看到图像中有两种不同的颜色。
我们可以使用rgb2hsv
将图像转换为HSV,我们可以分别检查这些组件。色调分量表示像素的主色,饱和度表示像素中的纯度或白光多少,并且该值表示像素的强度或强度。
尝试将每个频道可视化:
im = imread('http://i.stack.imgur.com/cFOSp.png'); %// Read in your image
hsv = rgb2hsv(im);
figure;
subplot(1,3,1); imshow(hsv(:,:,1)); title('Hue');
subplot(1,3,2); imshow(hsv(:,:,2)); title('Saturation');
subplot(1,3,3); imshow(hsv(:,:,3)); title('Value');
嗯......好吧,色调和饱和度根本不能帮助我们。它告诉我们主要的颜色和饱和度是相同的......但是它们与众不同的是值。如果你看一下右边的图像,我们可以通过颜色本身的强度来区分它们。所以它告诉我们的是"黑色"像素实际上是蓝色的,但几乎没有相关的强度。
我们实际上可以利用这个优势。任何值超过某个值的像素都是我们想要保留的值。
尝试设置阈值......类似0.75
。 MATLAB的HSV值动态范围来自[0-1]
,因此:
mask = hsv(:,:,3) > 0.75;
当我们对值组件进行阈值处理时,这就是我们得到的结果:
显然有一点量化噪音......特别是在轴和字体周围。我接下来要做的是执行形态侵蚀,这样我就可以消除每个数字和轴周围的量化噪声。我要把面具做得有点大,以确保我消除这种噪音。使用图像处理工具箱:
se = strel('square', 5);
mask_erode = imerode(mask, se);
我们得到了这个:
很好,所以我现在要做的就是制作原始图像的副本,然后将黑色的任何像素从我导出的面具(上图)设置为白色最后的形象。所有其他像素应保持完整。这样,我们就可以删除图像中显示的任何文本和轴:
im_final = im;
mask_final = repmat(mask_erode, [1 1 3]);
im_final(~mask_final) = 255;
我需要在第三维中复制蒙版,因为这是一个彩色图像,我需要在相同的空间位置同时将每个通道设置为255.
当我这样做时,这就是我得到的:
现在您已经注意到图中存在间隙....由于量化噪声,这是预期的。我们可以通过将此图像转换为灰度并对图像进行阈值处理,然后通过形态膨胀将边缘填充在一起来做更进一步的操作。这是安全的,因为我们已经消除了轴和文本。然后我们可以使用它作为掩码来索引原始图像以获得我们的最终图形。
这样的事情:
im2 = rgb2gray(im_final);
thresh = im2 < 200;
se = strel('line', 10, 90);
im_dilate = imdilate(thresh, se);
mask2 = repmat(im_dilate, [1 1 3]);
im_final_final = 255*ones(size(im), class(im));
im_final_final(mask2) = im(mask2);
我将我们在没有文本和轴的情况下获得的上一个图像进行阈值处理后将其转换为灰度,然后使用90度的线结构元素执行扩张以连接这些线最初断开连接。这个阈值化的图像将包含我们最终需要从原始图像中采样的像素,以便我们可以获得所需的图形数据。
然后我拿这个面具,复制它,制作一个完全白色的图像,然后从原始图像中取样,并将原始图像中我们想要的位置放在白色图像中。
这是我们的最终形象:
非常好!我不得不做所有的图像处理,因为你的图像开始时基本上都有量化噪声,因此完全获得图形会有点困难。 Ander Biguri在他的回答中更详细地解释了颜色量化噪声,因此请查看他的帖子了解更多细节。
但是,作为定性测量,我们可以从原始图像中减去此图像并查看剩余的图像:
imshow(rgb2gray(abs(double(im) - double(im_final_final))));
我们得到:
所以看起来轴和文本被删除很好,但是图中有一些痕迹我们没有从原始图像中捕获并且这是有意义的。这一切都与您想要选择的正确阈值有关,以便获取图形数据。在图表的开头附近有一些麻烦点,这可能是由于我所做的形态处理。你提供的这个图像对于量化噪声非常棘手,因此很难获得完美的结果。此外,遗憾的是,这些阈值都是启发式的,因此请使用阈值,直到获得与您同意的内容为止。
祝你好运!