查找图像中的深紫色像素
Finding dark purple pixels in an image
我正在为我的自动化高等研究做研究。我已经完成了显微镜的自动化部分,但我需要 MATLAB 的帮助。此处显示了我想要细分的示例:
我需要从该图像中提取深紫色像素并仅在图中显示。这几乎就像基于颜色的分割,但我只想从整个图像中提取深紫色像素。
在这种情况下我会怎么做?
这里有一些可以帮助您入门的东西。让我们以颜色分割为主题,您只想提取深紫色的像素。在我们开始之前,我想向您指出 HSV colour space。 HSV 颜色 space 非常适合以人类最直观的方式表示颜色。我们倾向于通过主色来描述颜色,然后是颜色的褪色程度或纯度,以及颜色的亮暗程度等属性。主色由 Hue 表示,颜色的褪色程度或纯度由 Saturation 表示,颜色强度由 Value 表示,因此 Hue-Saturation-Value,或者HSV颜色space.
我们可以通过rgb2hsv
对RGB图像进行变换,使其变为HSV。这将 return 一个 3D 矩阵,其色调、饱和度和值作为 3D 矩阵中的 2D 切片,很像 RGB 图像,其中每个切片代表红色、绿色和蓝色通道。让我们看看将图像转换为 HSV 后每个组件的样子:
im = imread('https://www.cdc.gov/dpdx/images/malaria/ovale/Po_gametocyte_thickB.jpg');
hsv = rgb2hsv(im2double(im));
figure;
for idx = 1 : 3
subplot(1,3,idx);
imshow(hsv(:,:,idx));
end
第一行代码从URL中读入一张图片。我将使用 Hoki 向您推荐的那个,因为它是处理起来最简单的一个。为了自我包容,这是原始图像的样子:
完成此操作后,我们将图像转换为 HSV 颜色 space。重要的是将图像转换为 double
精度并将每个分量标准化为 [0,1]
,这由 im2double
执行。接下来,我们生成一个新图形,并将每个组件放置在三列的一行中。第一列代表色调,下一列代表饱和度,最后一列代表值。这是我们看到的数字:
对于第一个图,看起来主色是紫色,无论是浅色还是深色,所以色调在这里对我们没有帮助。如果您查看 HSV 色轮:
(来源:hobbitsandhobos.com)
标准化轮子,使其落在 [0,1]
之间,而不是 0 到 360 度之间。由于颜色 space 的性质,色调实际上表示为度数,但 MATLAB 将其标准化为 [0,1]
。您可以看到紫色落在 [0.6,0.8]
的色调内,这对应于我向您展示的第一个显示图像色调的图形。如果您检查图像周围的像素,它们会在此范围内波动。因此,色调在这里对我们帮助不大。
肯定会帮助我们的是饱和度和价值成分。如果你看一下,深紫色像素的饱和度比背景的其余部分高,这是有道理的,因为深紫色比背景的其余部分具有更纯净的紫色版本。对于数值,可以看到深紫色的亮度比背景暗。
我们可以利用这两个点来分割出图像中的紫色。最简单的做法是设置饱和度和值平面的阈值,以便保留某个范围内的任何值,而丢弃超出范围的值。因此,您可以这样做:
sThresh = hsv(:,:,2) > 0.6 & hsv(:,:,2) < 0.9;
vThresh = hsv(:,:,3) > 0.4 & hsv(:,:,3) < 0.65;
我使用 impixelinfo
并将鼠标悬停在饱和度和值分量上以检查深紫色区域的值。看起来那些深紫色的像素的饱和度值介于 0.6 和 0.9 之间,而值分量的值介于 0.4 和 0.65 之间。上面的代码将创建两个二进制掩码,其中 true
表示像素满足我们的标准,而 false
表示不满足。因为我想将两者结合在一起并且不遗余力,所以让我们对掩码进行逻辑或操作以获得最终结果:
figure;
result = sThresh | vThresh;
imshow(result);
我们也会展示结果。这就是我们得到的:
如您所见,这做得很好,但是我们在最终结果中不希望有红色箭头的残余。为了做一些清理,我们可以使用形态学——特别是一个小 window 的开放过滤器,这样我们就不会影响我们想要的像素。我们可以使用 imopen
to perform our opening operation for us. A morphological opening removes isolated pixels that appear around your image. You use what is called a structuring element 来查看图像的局部邻域。对于基础知识,任何与结构元素中包含的形状一样小的像素区域都将被删除。因为我们想保留其他对象的形状,我们可以尝试使用 5 x 5 磁盘结构元素来清理这些像素:
figure;
se = strel('disk', 2, 0);
final = imopen(result, se);
imshow(final);
这是我们得到的:
不错!我们需要修补一些漏洞,所以让我们用 imfill
:
来填补这些漏洞
figure;
final_noholes = imfill(final, 'holes');
imshow(final_noholes);
这是我们得到的:
好的!所以我们有我们的面具。我们需要做的最后一件事是呈现图像,这样您就可以只显示原始图像中的深紫色,而不会显示其他颜色。这可以通过 bsxfun
:
轻松实现
figure;
out = bsxfun(@times, im, uint8(final_noholes));
imshow(out);
以上操作采用您的蒙版,并将图像中的每个像素乘以该蒙版。我想指出的一件小事是,我们在上一步中找到的掩码需要转换为 uint8
,因为 bsxfun
要求乘法(或您执行的任何操作)需要是同一类型。我们以 3D 形式复制此蒙版,以便您屏蔽掉不需要的 RGB 像素,只保留您要查找的像素。
这就是我们最终得到的:
如您所见,它并不完美,但足以让您入门。这些阈值很重要,但通过一些非常简单的阈值处理,我提取了大部分紫色像素。
为了方便您,这里是我上面写的代码,可以很容易地复制并粘贴到 MATLAB 中,供您使用 运行:
clear all; close all; clc;
im = imread('https://www.cdc.gov/dpdx/images/malaria/ovale/Po_gametocyte_thickB.jpg');
hsv = rgb2hsv(im2double(im));
figure;
for idx = 1 : 3
subplot(1,3,idx);
imshow(hsv(:,:,idx));
end
sThresh = hsv(:,:,2) > 0.6 & hsv(:,:,2) < 0.9;
vThresh = hsv(:,:,3) > 0.4 & hsv(:,:,3) < 0.65;
figure;
result = sThresh | vThresh;
imshow(result);
figure;
se = strel('disk', 2, 0);
final = imopen(result, se);
imshow(final);
figure;
final_noholes = imfill(final, 'holes');
imshow(final_noholes);
figure;
out = bsxfun(@times, im, uint8(final_noholes));
imshow(out);
祝你好运!
试试这个:
function main
clc,clear
A = imread('https://www.cdc.gov/dpdx/images/malaria/ovale/Po_gametocyte_thickB.jpg');
subplot(1,2,1)
imshow(A)
RGB = [230 210 200]; % color you want
e = 40; % color shift
B = pix_in(A,RGB,e);
B = B + 255.*uint8(~B); % choosing white background
subplot(1,2,2)
imshow(B)
end
function B = pix_in(A,RGB,e)
% select specific pixels in image
% A - color image (3D matrix uint8)
% RGB - [R G B] - color to select
% e - color shift/deviation
A = double(A); % for same class operations (RGB - double)
[m, n, ~] = size(A);
RGB = reshape(RGB,1,1,3);
RGB = repmat(RGB,m,n,1); % creating 3D matrix
b = abs(A-RGB) < e; % logical 3D
b = sum(b,3) == 3; % if [R,G,B] of a pixel in range
B = A.*repmat(b,1,1,3); % selecting pixels those in range
B = uint8(B);
end
我正在为我的自动化高等研究做研究。我已经完成了显微镜的自动化部分,但我需要 MATLAB 的帮助。此处显示了我想要细分的示例:
我需要从该图像中提取深紫色像素并仅在图中显示。这几乎就像基于颜色的分割,但我只想从整个图像中提取深紫色像素。
在这种情况下我会怎么做?
这里有一些可以帮助您入门的东西。让我们以颜色分割为主题,您只想提取深紫色的像素。在我们开始之前,我想向您指出 HSV colour space。 HSV 颜色 space 非常适合以人类最直观的方式表示颜色。我们倾向于通过主色来描述颜色,然后是颜色的褪色程度或纯度,以及颜色的亮暗程度等属性。主色由 Hue 表示,颜色的褪色程度或纯度由 Saturation 表示,颜色强度由 Value 表示,因此 Hue-Saturation-Value,或者HSV颜色space.
我们可以通过rgb2hsv
对RGB图像进行变换,使其变为HSV。这将 return 一个 3D 矩阵,其色调、饱和度和值作为 3D 矩阵中的 2D 切片,很像 RGB 图像,其中每个切片代表红色、绿色和蓝色通道。让我们看看将图像转换为 HSV 后每个组件的样子:
im = imread('https://www.cdc.gov/dpdx/images/malaria/ovale/Po_gametocyte_thickB.jpg');
hsv = rgb2hsv(im2double(im));
figure;
for idx = 1 : 3
subplot(1,3,idx);
imshow(hsv(:,:,idx));
end
第一行代码从URL中读入一张图片。我将使用 Hoki 向您推荐的那个,因为它是处理起来最简单的一个。为了自我包容,这是原始图像的样子:
完成此操作后,我们将图像转换为 HSV 颜色 space。重要的是将图像转换为 double
精度并将每个分量标准化为 [0,1]
,这由 im2double
执行。接下来,我们生成一个新图形,并将每个组件放置在三列的一行中。第一列代表色调,下一列代表饱和度,最后一列代表值。这是我们看到的数字:
对于第一个图,看起来主色是紫色,无论是浅色还是深色,所以色调在这里对我们没有帮助。如果您查看 HSV 色轮:
(来源:hobbitsandhobos.com)
标准化轮子,使其落在 [0,1]
之间,而不是 0 到 360 度之间。由于颜色 space 的性质,色调实际上表示为度数,但 MATLAB 将其标准化为 [0,1]
。您可以看到紫色落在 [0.6,0.8]
的色调内,这对应于我向您展示的第一个显示图像色调的图形。如果您检查图像周围的像素,它们会在此范围内波动。因此,色调在这里对我们帮助不大。
肯定会帮助我们的是饱和度和价值成分。如果你看一下,深紫色像素的饱和度比背景的其余部分高,这是有道理的,因为深紫色比背景的其余部分具有更纯净的紫色版本。对于数值,可以看到深紫色的亮度比背景暗。
我们可以利用这两个点来分割出图像中的紫色。最简单的做法是设置饱和度和值平面的阈值,以便保留某个范围内的任何值,而丢弃超出范围的值。因此,您可以这样做:
sThresh = hsv(:,:,2) > 0.6 & hsv(:,:,2) < 0.9;
vThresh = hsv(:,:,3) > 0.4 & hsv(:,:,3) < 0.65;
我使用 impixelinfo
并将鼠标悬停在饱和度和值分量上以检查深紫色区域的值。看起来那些深紫色的像素的饱和度值介于 0.6 和 0.9 之间,而值分量的值介于 0.4 和 0.65 之间。上面的代码将创建两个二进制掩码,其中 true
表示像素满足我们的标准,而 false
表示不满足。因为我想将两者结合在一起并且不遗余力,所以让我们对掩码进行逻辑或操作以获得最终结果:
figure;
result = sThresh | vThresh;
imshow(result);
我们也会展示结果。这就是我们得到的:
如您所见,这做得很好,但是我们在最终结果中不希望有红色箭头的残余。为了做一些清理,我们可以使用形态学——特别是一个小 window 的开放过滤器,这样我们就不会影响我们想要的像素。我们可以使用 imopen
to perform our opening operation for us. A morphological opening removes isolated pixels that appear around your image. You use what is called a structuring element 来查看图像的局部邻域。对于基础知识,任何与结构元素中包含的形状一样小的像素区域都将被删除。因为我们想保留其他对象的形状,我们可以尝试使用 5 x 5 磁盘结构元素来清理这些像素:
figure;
se = strel('disk', 2, 0);
final = imopen(result, se);
imshow(final);
这是我们得到的:
不错!我们需要修补一些漏洞,所以让我们用 imfill
:
figure;
final_noholes = imfill(final, 'holes');
imshow(final_noholes);
这是我们得到的:
好的!所以我们有我们的面具。我们需要做的最后一件事是呈现图像,这样您就可以只显示原始图像中的深紫色,而不会显示其他颜色。这可以通过 bsxfun
:
figure;
out = bsxfun(@times, im, uint8(final_noholes));
imshow(out);
以上操作采用您的蒙版,并将图像中的每个像素乘以该蒙版。我想指出的一件小事是,我们在上一步中找到的掩码需要转换为 uint8
,因为 bsxfun
要求乘法(或您执行的任何操作)需要是同一类型。我们以 3D 形式复制此蒙版,以便您屏蔽掉不需要的 RGB 像素,只保留您要查找的像素。
这就是我们最终得到的:
如您所见,它并不完美,但足以让您入门。这些阈值很重要,但通过一些非常简单的阈值处理,我提取了大部分紫色像素。
为了方便您,这里是我上面写的代码,可以很容易地复制并粘贴到 MATLAB 中,供您使用 运行:
clear all; close all; clc;
im = imread('https://www.cdc.gov/dpdx/images/malaria/ovale/Po_gametocyte_thickB.jpg');
hsv = rgb2hsv(im2double(im));
figure;
for idx = 1 : 3
subplot(1,3,idx);
imshow(hsv(:,:,idx));
end
sThresh = hsv(:,:,2) > 0.6 & hsv(:,:,2) < 0.9;
vThresh = hsv(:,:,3) > 0.4 & hsv(:,:,3) < 0.65;
figure;
result = sThresh | vThresh;
imshow(result);
figure;
se = strel('disk', 2, 0);
final = imopen(result, se);
imshow(final);
figure;
final_noholes = imfill(final, 'holes');
imshow(final_noholes);
figure;
out = bsxfun(@times, im, uint8(final_noholes));
imshow(out);
祝你好运!
试试这个:
function main
clc,clear
A = imread('https://www.cdc.gov/dpdx/images/malaria/ovale/Po_gametocyte_thickB.jpg');
subplot(1,2,1)
imshow(A)
RGB = [230 210 200]; % color you want
e = 40; % color shift
B = pix_in(A,RGB,e);
B = B + 255.*uint8(~B); % choosing white background
subplot(1,2,2)
imshow(B)
end
function B = pix_in(A,RGB,e)
% select specific pixels in image
% A - color image (3D matrix uint8)
% RGB - [R G B] - color to select
% e - color shift/deviation
A = double(A); % for same class operations (RGB - double)
[m, n, ~] = size(A);
RGB = reshape(RGB,1,1,3);
RGB = repmat(RGB,m,n,1); % creating 3D matrix
b = abs(A-RGB) < e; % logical 3D
b = sum(b,3) == 3; % if [R,G,B] of a pixel in range
B = A.*repmat(b,1,1,3); % selecting pixels those in range
B = uint8(B);
end