首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >基于OpenCV的简易图像分割

基于OpenCV的简易图像分割

作者头像
用户9831583
发布2022-06-16 16:34:49
发布2022-06-16 16:34:49
5950
举报
文章被收录于专栏:码出名企路码出名企路

一. 读取图像

代码语言:javascript
复制
CommandLineParser parser(argc, argv, keys);
    help();
    if (parser.has("help"))
        return 0;
    string filename = parser.get<string>(0);
    gray = imread(filename, 0);
    if(gray.empty())
    {
        printf("Cannot read image file: %s\n", filename.c_str());
        help();
        return -1;
    }

    namedWindow("Distance Map", 1);
    createTrackbar("Brightness Threshold", "Distance Map", &edgeThresh, 255, onTrackbar, 0);

二. 核心算法

代码语言:javascript
复制
static void onTrackbar( int, void* )
{
    static const Scalar colors[] =
    {
        Scalar(0,0,0),
        Scalar(255,0,0),
        Scalar(255,128,0),
        Scalar(255,255,0),
        Scalar(0,255,0),
        Scalar(0,128,255),
        Scalar(0,255,255),
        Scalar(0,0,255),
        Scalar(255,0,255)
    };

    int maskSize = voronoiType >= 0 ? DIST_MASK_5 : maskSize0;
    int distType = voronoiType >= 0 ? DIST_L2 : distType0;

    Mat edge = gray >= edgeThresh, dist, labels, dist8u;

    if( voronoiType < 0 )
        distanceTransform( edge, dist, distType, maskSize );//任意点到最近背景点的距离
    else
        distanceTransform( edge, dist, labels, distType, maskSize, voronoiType );

    if( voronoiType < 0 )
    {
        // begin "painting" the distance transform result
        dist *= 5000;
        pow(dist, 0.5, dist);

        Mat dist32s, dist8u1, dist8u2;

        dist.convertTo(dist32s, CV_32S, 1, 0.5);
        dist32s &= Scalar::all(255);

        dist32s.convertTo(dist8u1, CV_8U, 1, 0);
        dist32s *= -1;

        dist32s += Scalar::all(255);
        dist32s.convertTo(dist8u2, CV_8U);

        Mat planes[] = {dist8u1, dist8u2, dist8u2};
        merge(planes, 3, dist8u);
    }
    else
    {
        dist8u.create(labels.size(), CV_8UC3);
        for( int i = 0; i < labels.rows; i++ )
        {
            const int* ll = (const int*)labels.ptr(i);
            const float* dd = (const float*)dist.ptr(i);
            uchar* d = (uchar*)dist8u.ptr(i);
            for( int j = 0; j < labels.cols; j++ )
            {
                int idx = ll[j] == 0 || dd[j] == 0 ? 0 : (ll[j]-1)%8 + 1;
                float scale = 1.f/(1 + dd[j]*dd[j]*0.0004f);
                int b = cvRound(colors[idx][0]*scale);
                int g = cvRound(colors[idx][1]*scale);
                int r = cvRound(colors[idx][2]*scale);
                d[j*3] = (uchar)b;
                d[j*3+1] = (uchar)g;
                d[j*3+2] = (uchar)r;
            }
        }
    }

    imshow("Distance Map", dist8u );
}

(1)二值化

(2)调用 distanceTransform函数

(3)根据distanceTransform函数计算结果,绘制距离变换图像(图像的值表示距离)

三.键盘控制

代码语言:javascript
复制
for(;;)
    {
        // Call to update the view
        onTrackbar(0, 0);

        char c = (char)waitKey(0);

        if( c == 27 )
            break;

        if( c == 'c' || c == 'C' || c == '1' || c == '2' ||
            c == '3' || c == '5' || c == '0' )
            voronoiType = -1;

        if( c == 'c' || c == 'C' )
            distType0 = DIST_C;
        else if( c == '1' )
            distType0 = DIST_L1;
        else if( c == '2' )
            distType0 = DIST_L2;
        else if( c == '3' )
            maskSize0 = DIST_MASK_3;
        else if( c == '5' )
            maskSize0 = DIST_MASK_5;
        else if( c == '0' )
            maskSize0 = DIST_MASK_PRECISE;
        else if( c == 'v' )
            voronoiType = 0;
        else if( c == 'p' )
            voronoiType = 1;
        else if( c == ' ' )
        {
            if( voronoiType == 0 )
                voronoiType = 1;
            else if( voronoiType == 1 )
            {
                voronoiType = -1;
                maskSize0 = DIST_MASK_3;
                distType0 = DIST_C;
            }
            else if( distType0 == DIST_C )
                distType0 = DIST_L1;
            else if( distType0 == DIST_L1 )
                distType0 = DIST_L2;
            else if( maskSize0 == DIST_MASK_3 )
                maskSize0 = DIST_MASK_5;
            else if( maskSize0 == DIST_MASK_5 )
                maskSize0 = DIST_MASK_PRECISE;
            else if( maskSize0 == DIST_MASK_PRECISE )
                voronoiType = 0;
        }
    }

四. 分割效果


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-02-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码出名企路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档