【问题标题】:How to extract a portion of an image given a particular color?如何提取给定特定颜色的图像的一部分?
【发布时间】:2016-02-15 00:34:54
【问题描述】:

我有一张图片(如下所示)。我只想提取粉色部分并删除图像的其余部分。我将粉色的 RGB 值存储在一个数组中。有什么方法可以在图像和颜色上使用bitwise_and,以便在 OpenCV 中挑出所需的部分?

【问题讨论】:

  • 能否提供非压缩图片(如png)?请不要将jpeg转换为png,而是直接将图像保存在png中。 jpeg 会导致压缩伪影,从而使这项任务变得不必要地更加困难。
  • 我已将其保存在 png 中。但是我怎样才能得到我想要的结果呢?
  • 请张贴png图片
  • ^完成,颜色不同了
  • 发布了一个答案,如果这是想要的结果,请告诉我。

标签: c++ c image opencv image-segmentation


【解决方案1】:

由于您的绿色颜色不统一,但范围为:

// in BGR color space
Scalar low(182, 204, 168);
Scalar high(187, 207, 172);

// in HSV color space
Scalar low(72, 43, 204);
Scalar high(72, 45, 207);

您可以使用inRange 函数。您可以根据需要分割的颜色调整范围。

通常 HSV 颜色空间更适合基于颜色的分割任务,但在这种情况下,BGR 颜色空间也足够好。

此代码展示了如何获得所需颜色的二进制掩码,以及如何在 BGR 和 HSV 颜色空间中仅复制原始图像的掩码部分。

#include <opencv2/opencv.hpp>
using namespace cv;

int main()
{

    // Load image
    Mat3b img = imread("path_to_image");
    {
        // BGR color space

        // Setup ranges
        Scalar low(182, 204, 168);
        Scalar high(187, 207, 172);

        // Get binary mask
        Mat1b mask;
        inRange(img, low, high, mask);

        // Initialize result image (all black)
        Mat3b res(img.rows, img.cols, Vec3b(0, 0, 0));

        // Copy masked part to result image
        img.copyTo(res, mask);

        imshow("Mask from BGR", mask);
        imshow("Result from BGR", res);
        waitKey();

    }

    {
        // HSV color space

        // Convert to HSV
        Mat3b hsv;
        cvtColor(img, hsv, COLOR_BGR2HSV);

        // Setup ranges
        Scalar low(72, 43, 204);
        Scalar high(72, 45, 207);

        // Initialize result image (all black)
        // Get binary mask
        Mat1b mask;
        inRange(hsv, low, high, mask);

        // Initialize result image (all black)
        Mat3b res(img.rows, img.cols, Vec3b(0, 0, 0));

        // Copy masked part to result image
        img.copyTo(res, mask);

        imshow("Mask from HSV", mask);
        imshow("Result from HSV", res);
        waitKey();
    }

    return 0;
}

掩码示例:

分割图像示例:

【讨论】:

  • 这看起来很棒。这正是我想要的。但对我来说不幸的是,我使用的是 Opencv 2.1 和 C ......所以我不能使用代码。我试图在 C 中使用这个逻辑。:(还有一件事。我已经将段的确切颜色(在这种情况下为绿色)存储在一个数组中。所以我可以为标量高和低给出相同的值吗?跨度>
  • @AbhishekV.Pai 1) 你指定了 C++ 标签,所以这个代码是 C++ 所要求的。 2)你没有指定你有一个过时的 OpenCV 版本,所以我认为它是一些最新版本。您不能提出要求,然后更改标准。此外,您正在使用 C++ 编译器进行编译,而且您自己的答案中的代码也是 C++,所以我不明白您在 C 中是如何使用它的。
  • 对不起,我没有具体说明。但我真的要感谢你的帮助。我将升级我的 Opencv 和 Visual Studio 并在其中运行您的代码。我正在使用 Visual Studio 2009 进行编译,所以我不知道为什么会显示该特定错误。
  • @AbhishekV.Pai 我告诉你这是因为如果你不针对你的问题写一个特定的问题,你将不会得到特定于你的问题的答案。如果您正在获得新的 VisualStudio,请记住,对于 2015,您没有预构建的二进制文件,您需要重新编译 OpenCV。使用 VS2012 或 VS2103(更好)就可以了。
【解决方案2】:

Bitwise_and 不是正确的方法,因为它是按位的。但是在 OpenCv 中当然有一些方法可以完成这个基本任务:

如果您知道确切的值,您可以使用CmpS 方法。如果要查找某个范围内的所有粉红色,请使用InRangeS 方法。可以选择首先更改图像的色彩空间,例如如果你想在 HSV 空间中指定你的范围。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-30
    • 1970-01-01
    • 1970-01-01
    • 2020-11-27
    • 2019-09-17
    • 2018-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多