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