【问题标题】:C++ Open CV draw one color for the same shape of contourC ++ Opencv为相同形状的轮廓绘制一种颜色
【发布时间】:2019-05-11 07:23:13
【问题描述】:

我在使用图像时刻的地方有这段代码。我想为每个轮廓形状绘制一次颜色。现在,如果我有五个三角形,所有这些都是用不同的颜色绘制的。我想做的只是一种将形状彼此分开的方法,用相同的颜色绘制它们。

vector<vector<Point> > contours;
vector<Vec4i> hierarchy;

findContours(src, contours, hierarchy,
    CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);

vector<Moments> mu(contours.size());
vector<Point2f> mc(contours.size());
for (int i = 0; i < contours.size(); i++)
{
    mu[i] = moments(Mat(contours[i]), false);
    mc[i] = Point2f(mu[i].m10 / mu[i].m00, mu[i].m01 / mu[i].m00);
}

for (int i = 0; i < contours.size(); i++)
{
    Scalar color(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
    drawContours(dst, contours, i, color, CV_16U, 8, hierarchy);
}

【问题讨论】:

  • @ParamjitSinghRana:请不要将美式拼写改为英式(也不要将英式拼写为美式)。 “颜色”拼写正确。
  • 好的,先生,谢谢您的耐心。

标签: c++ opencv image-processing opencv-contour opencv-drawcontour


【解决方案1】:
for (int i = 0; i < contours.size(); i++)
{
    Scalar color(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
    drawContours(dst, contours, i, color, CV_16U, 8, hierarchy);
}

在上面的代码中Scalar color(.....) 定义了每个轮廓的颜色。目前这是在 for 循环中,因此它为每个轮廓创建一种新颜色。

Scalar color(.....) 移出 for 循环,您将只为轮廓分配一种颜色。

Scalar color(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));

for (int i = 0; i < contours.size(); i++)
{
    drawContours(dst, contours, i, color, CV_16U, 8, hierarchy);
}

【讨论】:

  • 谢谢。但我想为每种形状都有一种颜色。例如,为同一个三角形指定红色,为圆形指定另一种颜色等。我想尝试检测完全相同的轮廓并为它们指定一种颜色。
  • 嗯,就像 Yapws97 的回答一样,在前面创建一个调色板。您可以代替使用 rng 找到另一种方法来创建不会每次都更改的颜色数组。接下来,您需要在每个轮廓上运行一些代码以确定它是什么形状。轮廓只是一个点数组,它不知道它是什么形状。您可以尝试使用此示例代码进行形状检测。 stackoverflow.com/questions/15277323/opencv-shape-detection 知道轮廓是什么形状后,就可以指定颜色了。
【解决方案2】:

我建议您创建一个标量向量,其中包含您想要的每种形状的颜色。 total_shape 对应于您要着色的形状的一侧。例如,如果您想为包含八边形的形状着色,则 total_shape = 8 + 1。将颜色存储到矢量 shape_colors

std::vector<Scalar> shape_colors;
for (int i = 0; i < total_shape; i++)
{
    Scalar color(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
    shape_colors.push_back(color);
}

然后,当您想为轮廓着色时,请检查每个轮廓有多少点。根据点号,从 shape_color 中选择颜色,瞧,相同形状的相同配色方案。

但是,根据形状的角度,轮廓结果可能会返回太多点。我们需要使用approxPolyDP 将轮廓简化为尽可能简单的形式。这意味着我们希望一个矩形只包含 4 个点,一个三角形 3 个和一个五边形 5 个点。这个函数的详细解释由这个link给出。这样,我们就可以通过它所包含的点的总数来确定轮廓的形状。

for (int i = 0; i < contours.size(); i++)
{
    cv::Mat approx;
    approxPolyDP(contours[i], approx, 30, true);

    int n = approx.checkVector(2);
    drawContours(dst, contours, i, shape_colors[n],25);
}

这是完整的代码:

void process()
{
    cv::Mat src;
    cv::Mat dst;
    cv::RNG rng;

    std::string image_path = "Picture1.png";
    src = cv::imread(image_path,0);
    dst = cv::imread(image_path);
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;

    cv::threshold(src, src, 120, 255, cv::THRESH_BINARY);

    findContours(src, contours, hierarchy,
        CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);


    int total_shape = 10;
    std::vector<Scalar> shape_colors;
    for (int i = 0; i < total_shape; i++)
    {
        Scalar color(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
        shape_colors.push_back(color);
    }

    for (int i = 0; i < contours.size(); i++)
    {
        cv::Mat approx;
        approxPolyDP(contours[i], approx, 30, true);

        int n = approx.checkVector(2);
        drawContours(dst, contours, i, shape_colors[n],25);
    }

    cv::imshow("dst", dst);
    cv::waitKey(0);
}

结果如下:

【讨论】:

  • 谢谢。但是输出是一样的。我是这个领域的新手,可能我不知道如何完全按照你上面所说的那样去做。我的意思是total_shape。
猜你喜欢
  • 1970-01-01
  • 2021-02-01
  • 1970-01-01
  • 2012-11-06
  • 1970-01-01
  • 2017-02-07
  • 2013-09-18
  • 1970-01-01
  • 2012-05-27
相关资源
最近更新 更多