【问题标题】:Most used tones in a picture by checking the HSV color通过检查 HSV 颜色,图片中最常用的色调
【发布时间】:2013-03-17 18:31:21
【问题描述】:

我希望你能帮助我。

我正在 Android 中拍照,生成缩略图,然后使用此缩略图分析像素以获得最常用的色调。

我认为使用 RGB 很难对它们进行分组,所以我将每个像素颜色都变成了 HSV 颜色。如您所见,我使用了 Float3,因此 hsv.x 与 hsv.h 相同,hsv.y 为 hsv.s 并且 hsv.z 等于 hsv.v。

scores 是一个int[] 数组,我在那里存储每个色调的像素数量。这个算法在寻找蓝色调(海蓝宝石、浅蓝色和深蓝色)时效果很好,但很难识别单色(它将它们移到黄色分数)和暖色(它“混淆”了橙色和黄色)。另外,作为最后一个问题,我不知道如何识别棕色(这是我认为我错过的最后一个“大颜色”。算法来了:

for (Float3 hsv: hsvs) {
    if(hsv.y < 0.15)
    {
        if(hsv.z < 0.2)
            scores[BLACK]++;
        else if(hsv.z < 0.6)
            scores[GREY]++;
        else
            scores[WHITE]++;
    }
    else if (hsv.x < 15f || hsv.x > 345f)
        scores[RED]++;
    else if (hsv.x < 40)
        scores[ORANGE]++;
    else if (hsv.x < 70)
        scores[YELLOW]++;
    else if (hsv.x < 120)
        scores[GREEN]++;
    else if (hsv.x < 160)
        scores[AQUAMARINE]++;
    else if (hsv.x < 200)
        scores[LIGHT_BLUE]++;
    else if (hsv.x < 240)
        scores[DARK_BLUE]++;
    else if (hsv.x < 300)
        scores[PURPLE]++;
    else
        scores[PINK]++;
}

您认为我可以通过更改一些数字来改进算法,还是应该从不同的方法开始?

编辑:

让我把你放在上下文中。我的应用程序拍照,抓取一个方形缩略图(出于实际原因)并分析生成的图片。因为它是一个拇指,它会丢失一些细节和尺寸(比如我创建了 200x200 像素的拇指),所以在我的特殊情况下,总会有 40000 像素。我对这张图片所做的是检查最常用的色调。

在大多数情况下,我将它们定义为出现在 3000 像素以上的色调(约占图像的 7.5%)。我没有对它们进行排名,我只是检查了一些以任意颜色命名的复选框(可能是显示给您的颜色加上棕色)。然后,用户选中或取消选中他认为合适的颜色。事实上,正如 Geobits 所指出的,这是一个人类问题,最常用的颜色并不意味着最相关的颜色。这就是为什么这个工具不需要完美,只是为了避免在选择完全不适合包装的颜色时失败。

【问题讨论】:

    标签: java android image-processing hsv


    【解决方案1】:

    如果我这样做,而不是让每个像素落入几个桶中的一个,我会看看每种色调与每种颜色的距离。例如,您可以从每个“目标色调”中获取差异,然后总结所有差异。循环遍历所有像素后总数最低的那个应该是“最常用的”。当然它并不完美,但命名颜色对于计算机来说并非易事。

    例如,要获得“绿色”的总数(我的任意世界中的色调为 120):

    float runningTotalForGreen = 0;
    for(Float3 hsv: hsvs) 
    {
        float diff = (hsv.x - 120) % 180; // mod 180 to normalize cw/ccw on the wheel
        runningTotalForGreen += diff; // lower = closer to green
    }
    

    您可能希望将目标颜色和总数存储在数组中以便于循环,但这是一般的想法。

    编辑:

    我认为这会比“桶”更好的原因是:考虑一张图片,其中大约 35% 的图片是红色的。其他 65% 位于浅蓝色/深蓝色边界的某个位置。因此,假设 34% 属于浅蓝色桶,31% 属于深蓝色。你的方法说它是红色的,因为 35% 大于两者。使用色调差异很可能会返回其中一种蓝色。

    当然,大多数方法都会有 一些 图像失败。关键是找到错误最少的那个。这在很大程度上取决于它是什么类型的图像。我同意您需要对某些颜色(黑色/白色/棕色/等)进行特殊处理。


    这里的主要问题是这是一个人的问题。对于我上面的示例图像,有些人会说浅蓝色。有人会说深蓝色。有些人甚至可能会说红色,这取决于它的生动/对比程度,特别是如果蓝色是背景,前面是红色。除非它基本上是单色的,否则说“这张图片是 x 颜色”是不一致的。

    【讨论】:

    • 这是个好主意。然而,我的也以不同的方式做到这一点。我设置了from 和to 度数,而你定义了middle。问题不在于。问题在于正确的距离和颜色,而不仅仅是取决于色调,还取决于饱和度和值(例如棕色、黑色、白色和灰色)
    • 我同意您的编辑。但是,我无法解释自己。我希望我的编辑能解决这个问题
    • 这是有道理的。在这种情况下,我只会调整你的色调范围。获取一组训练器图像并对其进行调整,直到您在 大多数 上获得最佳结果。特别是对于棕色,您将不得不对确切的值挑剔,不仅仅是色相,还有饱和度和值。棕色真的很棘手,而且可能是最主观的,因为它的范围从几乎橄榄色到几乎红色。
    【解决方案2】:

    不能说这是否是一个好方法。在Color Names 上查看此页面。当您单击色轮中的颜色时,它将为您提供用于定义颜色名称的色调范围。

    【讨论】:

    • 谢谢,我可以用它自定义我的范围。但是,这并没有显示(或者至少我找不到)检测我缺少的颜色(同样是棕色、黑色、白色和灰色)的正确方法
    猜你喜欢
    • 1970-01-01
    • 2019-05-12
    • 2014-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多