【问题标题】:Processing how to get the nearest color from a Collection of colors处理如何从颜色集合中获取最接近的颜色
【发布时间】:2020-08-10 03:01:47
【问题描述】:

我有一个 Collection of Integers 的处理颜色(它包含重新缩放为 1x1 以获得“平均”颜色的图像颜色)。
我有这个东西必须检索我最近的数组颜色:

public static int getNearestColor(Collection<Integer> colors, int color) {
    return colors.stream()
        .min(Comparator.comparingInt(i -> Math.abs(i - color)))
        .orElseThrow(() -> new NoSuchElementException("No value present"));
}

但是当我这样做时,它返回的颜色比输入,但数组包含一些比输入最近的颜色,this是我不明白的问题吗?

【问题讨论】:

  • 以编程方式..你想要一个数组中的数字..它等于或最接近颜色参数的数量?对吗?
  • 是的,不,处理中的颜色是整数但奇怪的整数,否则我的功能会起作用
  • 但是您的代码返回的是最小差异,而不是具有最小差异的实际颜色。
  • 哦那我应该写什么才能返回具有最小差异的实际颜色?
  • @JoakimDanielson 抱歉,我不明白它应该如何帮助我?

标签: java arrays colors processing


【解决方案1】:

color() 的 RGB 颜色通道在int 中编码。您可以通过red()green()blue() 提取颜色的红色、绿色和蓝色分量。
将颜色通道视为 3 维向量 (PVector) 并通过 dist() 计算 2 个颜色向量的 Euclidean distance。 “距离”最短的颜色是“最近”的颜色:

在以下函数中,参数c1c2int 类型的颜色:

float ColorDistance(int c1, int c2) {
    return PVector.dist(
        new PVector(red(c1), green(c1), blue(c1)), 
        new PVector(red(c2), green(c2), blue(c2)));
}

通过查找最小浮点“距离” (ColorDistance(i, color)) 在颜色集合中查找“最近”颜色。

【讨论】:

  • @Ayfri 虽然公式 RGB 距离公式干净且正确,但它不太可能在 RGB 颜色空间中找到感知上最接近的颜色。为此,您可能需要转换为略为more complicated 的 Lab。不错的答案 Rabbid76 (+1):干净简洁
【解决方案2】:

java 中的数组没有流方法;也许你的意思是Arrays.stream(colors)IntStream 除了按自然顺序进行比较外,无法进行比较。您可以先映射到差异(abs(i - color)),但现在您已经删除了您正在寻找的信息(原始颜色),所以这也不起作用。让我们把它装箱。这将产生以下代码,这与您的代码完全相同,除了编译和运行。然后,我还将添加一个测试用例,使其成为一个独立的示例:

int[] colors = {1,4,5,9,12};
int target = 6;
int a = Arrays.stream(colors).boxed()
    .min(Comparator.comparingInt(i -> Math.abs(i - target)))
    .orElseThrow(() -> new NoSuchElementException());
System.out.println(a);

而且,哇哦,“5”掉出来了,这正是你想要的。

换句话说,你的代码的意图是好的,如果它没有给出正确的答案,你的输入不是你认为的那样,或者是其他错误,无法从你的粘贴中收集到。

我是否可以建议,如果可以将问题放在一个简单的、自包含的形式中(因为这个问题显然是,请参阅此答案中的代码 sn-p),你这样做吗?通常你会这样回答你自己的问题:)

【讨论】:

  • 因为我很笨,我的函数实际上是从HashMap 中提取values(),为了简化问题,我只是放了int[],但我没有意识到该函数无法使用这个,我很抱歉:(你能修改你的消息吗?我修改了我的。
【解决方案3】:
public static int getNearestColor(int[] colors, int color) {
    int minDiff = IntStream.of(colors)
            .map(val -> Math.abs(val - color))
            .min()
            .getAsInt();

    OptionalInt num = IntStream.of(colors)
            .filter(val-> val==(color + minDiff))
            .findFirst();

    if(num.isPresent()){
        return color + minDiff;
    } else {
        return color - minDiff;
    }
  }

【讨论】:

  • 我已经更改了代码流。但是,这正在返回预期的输出!
  • 我是!我很愚蠢,我的函数实际上是从HashMap 中提取values(),为了简化我刚刚输入int[] 的问题,但我没有意识到该函数不能与此一起使用,我很抱歉:( 可以你修改了你的消息?我修改了我的。
  • 不只是发布代码,您能否解释一下您的代码的作用和工作原理,以便人们从中学习?
猜你喜欢
  • 2021-09-30
  • 1970-01-01
  • 2019-07-02
  • 2019-06-12
  • 2012-07-15
  • 1970-01-01
  • 2014-07-22
  • 2016-11-13
  • 1970-01-01
相关资源
最近更新 更多