C ++ Open CV нарисуйте один цвет для одинаковой формы контура - PullRequest
0 голосов
/ 10 декабря 2018

У меня есть этот код, где я использую Image Moments.Я хочу нарисовать один раз цвет для формы контура.Теперь, если у меня пять треугольников, все они рисуют разными цветами.Все, что я хочу сделать - это способ разделить фигуры друг на друга, нарисовав их одинаковым цветом.

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);
}

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Я бы посоветовал вам создать скалярный вектор, содержащий цвета для каждой фигуры, которую вы хотите. 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 точек.Подробное объяснение этой функции дано по этой ссылке .Таким образом, мы сможем определить форму контура по общему количеству точек, которые он содержит.

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);
}

А вотрезультат: enter image description here

0 голосов
/ 10 декабря 2018
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);
}
...