【问题标题】:How to change pixel values of an RGB image in MATLAB?如何在 MATLAB 中更改 RGB 图像的像素值?
【发布时间】:2018-08-31 11:41:57
【问题描述】:

所以我需要做的是应用像

这样的操作
(x(i,j)-min(x)) / max(x(i,j)-min(x))

它基本上将每个像素值转换为介于 0 和 1 之间的值。

首先,我意识到 Matlab 使用 imread 将我们的图像(行 * 列 * 颜色)保存在 3D 矩阵中,

Image = imread('image.jpg')

所以,对图像进行简单的最大操作并没有给我像素的最大值,我不太确定它返回什么(另一个多维数组?)。所以我尝试使用类似的东西

max_pixel = max(max(max(Image)))

我认为它工作得很好。同样,我使用了 min 三次。我的逻辑是我得到了所有 3 个颜色平面的最小像素值。

执行上述缩放操作后,我得到的图像似乎只有 0 或 1 个值,中间没有任何值,这似乎不正确。它与整数/浮点数舍入有关吗?

image = imread('cat.jpg')
maxI = max(max(max(image)))
minI = min(min(min(image)))
new_image = ((I-minI)./max(I-minI))

这给出了只有 1 和 0 的输出,这似乎不正确。

我正在尝试的另一种方法是像 here 那样分别处理所有颜色平面。但这是正确的做法吗?

我也可以循环遍历所有像素,但我认为这需要时间。对此非常陌生,任何帮助都会很棒。

【问题讨论】:

  • 没有示例就不清楚,但似乎您想使用dim 参数到max/min,如文档中所述。另外我认为你的第一个方程中分数的底部应该是(max(x)-min(x)),取(x-min(x))的最大值不会标准化0到1之间的数据。跨度>
  • @wolfie x(i,j)-min(x) 将使最小像素的值为 0,而所有其他像素将具有一些值,例如其中的最大值为 y,现在除以 max( x(i,j)-min(x)) 表示除以 y,因此像素的最大值变为 1。不是吗?我应该提供什么样的例子?你是说代码吗?非常感谢。
  • 您的图像是如何生成的?如果它已经是 RGB,那么它不是“数据矩阵”,它是某物的颜色表示。这意味着它要么是 0-255、0-1,要么可能是错误生成的。
  • @AnderBiguri 所以我使用 imread 读取图像..它给出的输出值范围为0-255size(image) 也给出了375 500 3,这意味着我认为它是 RGB。当我使用red = image(:,:,1) 然后size(red) 我得到375 500

标签: matlab image-processing


【解决方案1】:

如果您不确定 matlab 函数返回什么或为什么,您应该始终首先执行以下操作之一:

在命令窗口中键入 help >functionName<doc >functionName<,在您的情况下为:doc max。这将向您展示该特定功能的基本必知信息,例如需要放入什么以及将输出什么。

对于max 函数,这会产生以下结果:

M = max(A) 返回数组的最大元素。

如果 A 是向量,则 max(A) 返回 A 的最大值。

如果 A 是一个矩阵,那么 max(A) 是一个包含最大值的行向量 每列的值。

如果 A 是一个多维数组,则 max(A) 沿第一个 大小不等于 1 的数组维度,将元素视为 向量。该维度的大小变为 1,而所有维度的大小 其他尺寸保持不变。如果 A 是一个空数组,其第一个 维度的长度为零,然后 max(A) 返回一个空数组,其中 和A一样大

换句话说,如果您在矩阵上使用max(),它将输出一个向量,其中包含每列的最大值(第一个非单维)。如果您在大小为m x n x 3 的矩阵A 上使用max(),它将产生一个大小为1 x n x 3 的最大值矩阵。所以这回答了你的问题:

我不太确定它返回什么(另一个多维数组?)

继续:

我认为它工作得很好。同样,我使用了 min 三次。我的逻辑是我得到了所有 3 个颜色平面的最小像素值。

这是正确的。或者,您可以使用max(A(:))min(A(:)),如果您只是在寻找值,则它们是等效的。

在执行上述操作后,我得到了一个似乎只有 0 或 1 个值的图像,中间没有任何值,这似乎不正确。它与整数/浮点数舍入有关吗?

如果您不发布代码的minimal, complete and verifiable example,我们无法知道为什么会发生这种情况。可能是因为您的变量属于某种类型,也可能是因为您的计算有误。

我正在尝试的另一种方法是像这里所做的那样分别处理所有颜色平面。但这是正确的做法吗?

这取决于预期的最终结果。与一次对所有值进行归一化相比,分别对每种颜色(红、绿、蓝)进行归一化会产生不同的结果(无论如何,在 99% 的情况下)。

【讨论】:

  • 嘿,非常感谢。我已经多次阅读帮助部分。即使是现在,我对多维数组的部分也不是很清楚。我将尝试在脚本中编写代码并将其添加到此处,以便我更清楚。
  • 我不怪你,尤其是当你刚刚进入 matlab 时,有时措辞可能有点复杂。我强烈建议使用 Wolfie 提到的可选 dim 参数。它不仅出现在更多的 matlab 函数中(summeanrms 等等),而且非常有用。
  • max(A(:)) 是等效的,因为它产生沙子输出。但它的效率要高得多!
  • 没错,克里斯! :^)
【解决方案2】:

您有一个uint8 RGB 图像。

只需将其转换为双图像

I=imread('https://upload.wikimedia.org/wikipedia/commons/thumb/0/0b/Cat_poster_1.jpg/1920px-Cat_poster_1.jpg')

I=double(I)./255;

或者

I=im2double(I); %does the scaling if needed

Read about image data types


你做错了什么?

如果您想要将 RGB 图像转换为 [0-1] 范围,那么无论您的 MATLAB 代码是否正确,您都在严重处理问题。让我举个例子说明原因:

假设您有一张有 2 种颜色的图像。

深红色 (20,0,0):

中蓝色 (0,0,128)

现在您希望将其更改为 [0-1]。你如何缩放它?您建议的方法是使值 128->120->20/12820->1 (不相关)。然而,当你这样做时,你正在改变颜色!您正在将中等蓝色变为深蓝色(最大 B 通道,)并使 R 方式更加强烈(而不是 20/255、20/128、双亮度!)。这很糟糕,因为这是简单的颜色,但是结合 RGB 值,您甚至可以更改颜色本身,而不仅仅是强度。因此,转换为 [0-1] 范围的唯一正确方法是假设您的最小值和最大值为 [0, 255]。

【讨论】:

  • 我在问题中添加了一些代码。我还尝试在阅读图像后使用I=double(I),然后重复这些步骤,但是new_city = ((I-min_pixel)./max(I-min_pixel)) 行不再运行。它给出了错误Error using - Integers can only be combined with integers of the same class, or scalar doubles.
  • @momo 此处的代码而不是,而不是您尝试不与它一起执行的操作。我向您展示了如何在 0-1 之间标准化图像。您正在尝试做的事情会弄乱颜色(除非您有一个 [0,0,0] 的 RGB 和一个 [255,255,255] 的 RGB,但您不能保证 100%)。
  • 啊.. 我认为 I=im2double(I) 会进行缩放,但我认为 I=double(I) 可能会帮助我解决 0 和 1 问题。我不能使用 im2double ,因为我实际上是在尝试手动计算工作。不过还是非常感谢。
  • 啊!!愚蠢的错误.. 我使用了错误的变量min_pixel 而不是minI。看来I=double(I) 确实有效,值现在从 0 到 1 不等。我会尝试下一部分,看看是否有效。
  • @momo 我解释了为什么你的方法根本上是错误的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-24
  • 1970-01-01
  • 2018-08-05
  • 1970-01-01
相关资源
最近更新 更多