美文网首页
opencv查找轮廓并配色

opencv查找轮廓并配色

作者: 寽虎非虫003 | 来源:发表于2022-11-04 16:06 被阅读0次

记录目的

每次都要重新理解得到的层级树应该怎么处理,很麻烦,所以记一下,方便以后直接用。

查找轮廓

单纯查找轮廓部分的代码,输入图按照opencv要求就行

    vector<vector<Point>> contours; // 轮廓
    // 轮廓嵌套关系,分别表示第i个轮廓的后一个轮廓、前一个轮廓、子轮廓、父轮廓的索引编号
    vector<Vec4i> hierarchy;
    // CV_RETR_TREE 建立等级树,这个要注意判面积
    cv::findContours(thresh, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);

绘制

这是查完之后开始进行绘制着色

// 两层之间的环才需要着色,其余不需要
    RsltMat = Mat::zeros(thresh.size(), CV_8UC3);
    vector<Scalar> colors;
    for (size_t i = 0; i < contours.size(); i++)
    {
        colors.push_back(icvprGetRandomColor());
    }

    if (contours.size())
    {
        int out = 0;
        int idxColor = 0;
        bool bColor(true);
        mergeDrawContours(RsltMat, contours, hierarchy,
                          colors, out, idxColor,
                          bColor);
    }

这是具体的颜色生成和绘制代码,其实外面的颜色生成可以放到内部的递归里面去

/** ***************************************************************************
 * @brief 递归绘制所有轮廓,相邻的两层中判定为内层的不着色
 *
 * @param[in] src 需要绘制的图
 * @param[in] contours 所有轮廓
 * @param[in] hierarchy 所有轮廓之间的层级关系和相邻关系
 * @param[in] colors 所有的颜色
 * @param[in] idxDraw 当前需要绘制的轮廓编号
 * @param[in] idxColor 当前绘制的轮廓的颜色编号
 * @param[in] bColor 是否需要着色
 * @return int
 * ************************************************************************** */
int mergeDrawContours(Mat &src, vector<vector<Point>> &contours,
                      vector<Vec4i> &hierarchy,
                      vector<Scalar> &colors,
                      int &idxDraw,
                      int &idxColor,
                      bool bColor)
{
    int nResult = 0;
    if (idxDraw >= 0)
    {
        if (bColor)
        {
            cv::drawContours(src, contours, idxDraw, colors[idxColor], -1);
        }
        else
        {
            cv::drawContours(src, contours, idxDraw, Scalar(0, 0, 0), -1);
        }

        // 每次着色之后,需要使用下一个颜色。
        if (bColor)
        {
            idxColor++;
        }

#ifdef _DEBUG
        string s = to_string(idxDraw) + " " + to_string(bColor) + " " + to_string(idxColor);
        cv::putText(src, s, contours[idxDraw][0],
                    cv::HersheyFonts::FONT_HERSHEY_PLAIN, 1.f, Scalar(0, 0, 255));
#endif
    }

    int inner = hierarchy[idxDraw][2];
    if (inner >= 0)
    {
        // 内层不填充颜色
        mergeDrawContours(src, contours, hierarchy,
                          colors, inner, idxColor,
                          !bColor);
    }

    int next = hierarchy[idxDraw][0];
    if (next >= 0)
    {
        mergeDrawContours(src, contours, hierarchy,
                          colors, next, idxColor,
                          bColor);
    }

    return nResult;
}

cv::Scalar icvprGetRandomColor()
{
    uchar r = rand() % 256;
    uchar g = rand() % 256;
    uchar b = rand() % 256;
    return cv::Scalar(b, g, r);
}

效果

效果图
原图

相关文章

网友评论

      本文标题:opencv查找轮廓并配色

      本文链接:https://www.haomeiwen.com/subject/mkqutdtx.html