opencv 分水岭算法watershed

opencv watershed

demo: http://download.csdn.net/detail/keen_zuxwang/9852585

分水岭算法
1、一种基于拓扑理论的数学形态学的图像分割方法。分水岭算法容易导致图像的过度分割。opencv中,使用预定义的一组标记来引导对图像的分割,防止过度切割。
2、一种图像区域分割法,它会把跟临近像素间的相似性作为重要的参考依据,从而将在空间位置上相近并且灰度值相近的像素点互相连接起来构成一个封闭的轮廓,封闭性是分水岭算法的一个重要特征。

//! segments the image using watershed algorithm
CV_EXPORTS_W void watershed( InputArray image, InputOutputArray markers );

功能:标识出不同区域间的值被置为-1(边界), 没有标记清楚的区域被置为0,其他每个区域的值保持不变
image
输入图像,须为CV_8UC3类型
markers
声明为CV_32S类型(32位单通道),既作为输入,也作为输出保存函数调用的结果。

watershed函数
1、watershed第二个参数markers必须包含了种子点信息,它应该包含不同区域的轮廓,每个轮廓有一个自己唯一的编号,轮廓的定位可以通过Opencv中findContours方法实现,这个是执行分水岭之前的要求。
2、分水岭算法会根据markers传入的轮廓作为种子(注水点),对图像上其他的像素点根据分水岭算法规则进行判断,并对每个像素点的区域归属进行划定,直到处理完图像上所有像素点。而区域与区域之间的分界处的值被置为“-1”,以做区分。

JNI:

JNIEXPORT jlong JNICALL Java_com_example_grabcut_MainActivity_doWatershed(JNIEnv *env, jclass clz, jlong imageGray)
{
      Mat img0 = Mat(*(Mat*)imageGray);
    Mat img(img0.size(),CV_8UC3); //输入图像须为CV_8UC3类型
      cvtColor(img0, img, CV_BGRA2BGR);

    Mat gray;
    cvtColor(img, gray, CV_BGR2GRAY);//1、转换为灰度图

    equalizeHist(gray, gray);    //2、直方图均衡化  CV_EXPORTS_W void equalizeHist( InputArray src, OutputArray dst );
    blur(gray, gray, Size(5,5)); //3、均值滤波

    Mat binary;
    adaptiveThreshold(gray, binary, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY_INV, 5, 10);//4、将灰度图转换为二值图
    Mat markers(gray.size(), CV_32S, Scalar::all(0));

    vector< vector<Point> > contours;
    vector<Vec4i> hierarchy;
    findContours(binary, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_NONE); //5、findContour()函数找出图像的轮廓

    int idx = 0;
    int compIdx = 0;
    for( ; idx >= 0; idx = hierarchy[idx][0],compIdx++){
        //Scalar color(rand()&255, rand()&255, rand()&255);
        //drawContours(markers, contours, idx, color, CV_FILLED, 8, hierarchy); 
        drawContours(markers, contours, idx, Scalar::all(compIdx+1), CV_FILLED, 8, hierarchy);//6、markers上绘制contours
    }

    Mat marks0;
    convertScaleAbs(markers,marks0);

    //调用分水岭算法分割图像
    watershed(img, markers); //7、img须为CV_8UC3类型,markers须为CV_32S类型

    Mat marks1;
    convertScaleAbs(markers,marks1);

    //Mat marker;
    //markers.convertTo(marker, CV_8U);
    //marks1.convertTo(marker,CV_8U);//CV_8UC3 输出测试使用

    Mat fillMat = Mat::zeros(gray.size(),CV_8UC3); // 8、填充绘制
    for(int i=0;i<markers.rows;i++)  {
        for(int j=0;j<markers.cols;j++)  {
            int index=markers.at<int>(i,j);
            if(markers.at<int>(i,j)==-1)  {
                fillMat.at<Vec3b>(i,j)= Vec3b(255,255,255);
            }else  {
                fillMat.at<Vec3b>(i,j)= RandomColor(index);
            }
        }
    }

    //Mat mix;
    //addWeighted(img,0.5,fillMat,0.5,0,mix); //输出测试使用

    Mat *hist = new Mat(fillMat); // 9、回传Java端显示
    return (jlong) hist;
}

这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值