在Matlab中绘制反色图像?

6
我正在Matlab中在图片上绘图。有时,由于底层图像的颜色与相同位置的图像的颜色过于接近,我看不到正在绘制的内容。我可以始终更改绘图的颜色(例如从“rx”更改为“bx”),但这很麻烦。是否可能绘制底层图像的反色,以便叠加始终可见?
4个回答

3

我认为根据背景图像自动反转绘图颜色是不可能的。您可能可以将绘图光栅化,并与图像结合(异或?)。

这里有另一种解决方案。如果您可以使用封闭标记,例如圆形、正方形、三角形,您可以设置不同的MarkerEdgeColor和MarkerFaceColor,以便标记在不同的颜色下可见。

h = plot(1:5,'o');
set(h,'MarkerEdgeColor','b')
set(h,'MarkerFaceColor','r')

2

这是可能的。

假设你知道你的图像是什么样子的,你可以做以下操作:

  1. 读取你绘制的坐标处的颜色

  2. 反转该颜色

  3. 使用scatter(散点图)

    %# 加载RGB彩色图像 - 这可能不是最好的例子,因为它整个很暗。 X = double(imread('ngc6543a.jpg'))/255; %# 由于它是相当暗的图像,所以反转其中一半 X(:,1:floor(size(X,2)/2),:) = 1-X(:,1:floor(size(X,2)/2),:);

    %# 创建一些绘图数据 plotX = rand(50,1) * size(X,1); plotY = rand(50,1) * size(X,2);

    %# 读取RGB分量(它必须能够更有效地完成,但我现在没有想到 %# 它 plotColors = zeros(length(plotX),3); for c = 1:3 plotColors(:,c) = interp2(X(:,:,c),plotY,plotX); end

    %# 反转 plotColors = 1-plotColors; %# 如果你想要非常不同的颜色,并避免灰色是灰色的反义词的问题,你可以使用 %# plotColors = round(1-plotColors); %# 这给你选择wrgbcmyk,任何一个与图像颜色最远的

    %# 绘图 figure,imshow(X) hold on scatter(plotY,plotX,[],plotColors)

编辑:现在已经测试过了,应该可以工作。

编辑2:反转原始图像的一半使它更清晰易懂。

编辑3:结合gnovice的建议进行了修改。

编辑4:修复了AB指出的错误。


1
一个小缺点是,当颜色接近[0.5 0.5 0.5]时,反转不会给出非常明显的颜色。也许更好的选择是根据哪个颜色与像素颜色最不相似(即RGB值的总差异最大)来选择白色或黑色。 - gnovice
1
好主意。我猜想,可以使用四舍五入的倒数,而不是使用倒数(这是OP所要求的)。 - Jonas

1

我不知道有什么自动化的方法可以根据它们后面的像素颜色来改变你绘制的点的颜色。请记住,你不必只使用八种预定义的颜色规范(例如'red'代表红色或'blue'代表蓝色)。你可以为你绘制的点选择一个在底层图像中不常见的RGB颜色规范。例如:

h = plot(0,0,'Marker','x','Color',[1 0.4 0.6]);  %# Plot a pink x

您可以通过编写一些简单的代码来以编程方式找到最不常见的颜色,该代码会选择图像中最少使用的颜色值。以下是一个示例:

rawData = imread('peppers.png');  %# Read a sample RGB image
imData = reshape(rawData,[],3);   %# Reshape the image data
N = hist(double(imData),0:255);   %# Create a histogram for the RGB values
[minValue,minIndex] = min(N);     %# Find the least used RGB values
plotColor = (minIndex-1)./255;    %# The color for the plotted points
image(rawData);                   %# Plot the image
hold on;
hp = plot(500.*rand(1,20),350.*rand(1,20),...  %# Plot some random points
          'Marker','o','LineStyle','none',...
          'MarkerFaceColor',plotColor,'MarkerEdgeColor',plotColor);

以上代码首先将图像数据重塑为一个M乘3的矩阵,其中M是图像像素的数量,三列分别包含红色、绿色和蓝色值。使用HIST对每一列进行值的分组,然后找到每一列中最小频率的值(即最低频率的值)。这三个值成为绘图颜色的RGB三元组。当图像与此颜色的随机点叠加时,它会产生以下绘图:

alt text

请注意,在这种情况下,上述代码选择了明亮的蓝色作为绘图点的颜色,这恰好是图像中没有出现过的颜色,因此给人良好的对比度。

想象一下,这在几乎任何自然场景的GIF上都会失败 :-) - AVB
@AB:诚然,我所使用的算法是相当简单的示例,因此可能有一些图像难以应用这种方法。但总体而言,它应该会选择一个很少使用的颜色,从而最小化点最终落在匹配像素上的可能性。 - gnovice
2
我喜欢这个想法。不过,我会只使用16个箱子来找到最少使用的“颜色区域”。然后,您可以将箱子的中心作为绘图颜色,或在该区域内进行另一次搜索。 - Jonas
@Jonas:有趣的想法。这个代码可能有很多变化。我只是提出了一个简单的算法思路作为思考的食物。 - gnovice

0

如果您需要绘制散点图,这非常简单且看起来相当不错:

%# load rgb color image
X = double(imread('ngc6543a.jpg'))/255;
%# since it's quite a dark image, invert half of it
X(:,1:floor(size(X,2)/2),:) = 1-X(:,1:floor(size(X,2)/2),:);

%# create some plot data
plotX = rand(50,1) * size(X,1);
plotY = rand(50,1) * size(X,2);

%# plot
figure,imshow(X)
hold on
scatter(plotY,plotX,'xw');
scatter(plotY,plotX,'ok');

如果您需要更复杂的内容,请在评论区留言。

这并没有回答问题,所以我会清楚地写出来,避免被踩。 - Hannes Ovrén
@kigurai:在你威胁别人之前,你有尝试阅读代码甚至运行它吗? - AVB
是的,我可以看到它将数据绘制为白色十字和黑色环,这意味着它在大多数图像上可能会非常明显。然而,问题特别是关于在图像上绘制背景的反色,这与您建议的方式完全不同。并不是说你的回答是一个坏主意(尽管两个散点图显然会导致更长的执行时间),只是它没有回答直接的问题。 - Hannes Ovrén
另外,如果你复制粘贴来自其他解决方案的代码,你可能需要提到你基于什么来解决问题。 - Jonas
@kigurai:如果你读了其他答案和评论,你会发现“逆”(1)是不明确的,(2)可能不符合发布者的意图。我正在尝试解决真正的问题。你正在尝试解决所述的问题。两者都是同样有效的。 - AVB
@Jonas:谢谢!复制粘贴太明显了,我没想到要提。顺便说一下,你的代码有一个bug——你只翻转了红色通道;我已经改正了。 - AVB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接