【问题标题】:OpenCV: How to ignore background pixels from colour custersOpenCV:如何忽略色卡的背景像素
【发布时间】:2017-03-02 12:48:22
【问题描述】:

我正在努力寻找礼服的主要颜色。

1) 第一步是去除背景。我使用提到的解决方案 here 做到了这一点。它完美地工作并使背景变黑。

2) 现在,根据第一步的结果,我正在尝试使用提到的解决方案here 找到主色。但我将black(背景)作为主要颜色之一。

如何忽略第 2 步中的背景像素?

【问题讨论】:

  • 如果您认为他们有帮助,请考虑接受最佳答案。

标签: opencv image-processing


【解决方案1】:

根据具体情况,您可以找到感兴趣区域的边界矩形。如果颜色像素的数量远高于边界矩形内的黑色像素数量,则不应检测到黑色作为主色。

在面具的二进制图像上调用findContours(binaryMask)。确保你找到了你正在寻找的轮廓。如果没有,请过滤它们以获得最适合应用程序的一个。然后在轮廓上调用boundingRect(cnt)。然后使用该矩形裁剪图像并运行您的函数。如果这还不够,请尝试minAreaRect(cnt),但裁剪有点棘手:see this answer

如果这不起作用,我可能会选择“愚蠢”的解决方案,将遮罩的颜色更改为 99% 不会出现在连衣裙上的颜色,然后 - 知道它的确切 RGB 值- 从结果中过滤掉。

下次请记得提供您的案例图片,这样答案可能会更准确。

【讨论】:

    【解决方案2】:

    一种简单的方法是简单地将黑色作为主要颜色丢弃。比你真正想要的多抓一个集群,忽略黑色。如果黑色可能真的是主要颜色,请使用不同的背景颜色重复操作并丢弃它;比较结果。这会很慢,但做起来很简单。

    或者,您只能从前景中的像素中采样。从您的前景提取方法中,您应该有一个二进制的黑白前景/背景蒙版。如果您仅从蒙版的白色区域采样,则应仅考虑这些颜色。

    我有一个粗略的 C++ 实现,但几乎可以肯定它不是最有效的。也许这是你可以开始工作的开始?

    Mat src;    //Your source image
    Mat mask;   //Your black & white foreground/background image
    Mat samples(src.rows * src.cols, 3, CV_32F);
    //Set up samples with only foreground pixels
    for (int y = 0; y < src.rows; y++) {
        for (int x = 0; x < src.cols; x++) {
            if (mask.at<uchar>(y, x) == 255) {
                for (int z = 0; z < 3; z++) {
                    samples.at<float>(y + x*src.rows, z) = src.at<Vec3b>(y, x)[z];
                }
            }
        }
    }
    int clusterNo = 3;
    int attempts = 5;
    Mat labels;
    Mat centers;
    kmeans(samples, clusterNo, labels, TermCriteria(), attempts, KMEANS_RANDOM_CENTERS, centers);
    

    您的主色将存储在中心行中,您可以在其中随心所欲地使用它们。

    【讨论】:

      【解决方案3】:

      删除背景。这为您提供了二值图像 - 前景和背景像素。现在进行形态关闭以关闭前景图像中的小孔并通常清理轮廓。最后再次替换像素以获得彩色前景图像。

      【讨论】:

      • 这并不能回答问题 - 他们有前景图像,他们想知道在聚类时如何忽略背景。
      猜你喜欢
      • 2019-09-03
      • 2021-03-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-13
      • 1970-01-01
      • 2011-08-16
      • 2015-02-20
      • 2016-08-09
      相关资源
      最近更新 更多