OpenCV(四十一):图像分割-分水岭法

1.分水岭方法介绍

OpenCV 提供了分水岭算法(Watershed Algorithm)的实现, 使用分水岭算法对图像进行分割,将图像的不同区域分割成互不干扰的区域。分水岭算法模拟了水在图像中的扩散和聚集过程,将标记的边界被看作是阻挡水扩散的高山,通过模拟水的扩散和聚集,最终确定图像的分割边界。

如图所示:水从山低蔓延,而高山阻止水扩散。

2.分水岭法分割图像函数watershed()

void cv::watershed ( InputArray image,

InputOutputArray markers

  • image:输入图像,数据类型为CV_8U的三通道图像
  • markers:输入/输出CV_32S的单通道图像的标记结果,与原图像具有相同的尺寸

示例代码:

基于标记图像中画的线来对原图像进行分割。

复制代码
void  watershed_f(Mat mat,Mat mat2){//mat原图像  mat2含有标记的图像
    // 把四通道原图像转换成三通道
    Mat image;
    cv::cvtColor(mat, image, cv::COLOR_BGRA2BGR);

    Mat imgGray,imgMask,img_;
    Mat maskWaterShed;//watershed()函数的参数
    //对标记的图像进行灰度化
    Mat image2;
    cvtColor(mat2,imgGray,COLOR_BGR2GRAY);
    //对标记的图像二值化并开运算,可得到标记画的线
    threshold(imgGray,imgMask,250,255,THRESH_BINARY);
    Mat k= getStructuringElement(0,Size(3,3));
    morphologyEx(imgMask,imgMask,MORPH_OPEN,k);
    //显示二值化并开运算的结果
    imwrite("/sdcard/DCIM/imgMask2.png",imgMask);
    //对二值化后的标记图像进行轮廓检测,可得到画的线的轮廓
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours(imgMask,contours,hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point());
    //在maskWaterShed上绘制出上面得到的轮廓
    maskWaterShed=Mat::zeros(imgMask.size(),CV_32S);
    for(int index=0;index<contours.size();index++){
        drawContours(maskWaterShed,contours,index,Scalar::all(index+1),2,8);
    }
    //分水岭算法 需要对原图像进行处理
    watershed(image,maskWaterShed);
    //显示分水岭算法分割的每个区域
    imwrite("/sdcard/DCIM/maskWaterShed2.png",maskWaterShed);
  
    //随机生成几种颜色
    vector<Vec3b> colors;
    for(int i=0;i<contours.size();i++){
        int b=theRNG().uniform(0,255);
        int g=theRNG().uniform(0,255);
        int r=theRNG().uniform(0,255);
        colors.push_back(Vec3b((uchar)b,(uchar)g,(uchar)r));
    }
    //给分水岭算法分割的每个区域添加颜色
    Mat resultImg=Mat(image2.size(),CV_8UC3);
    for(int i=0;i<imgMask.rows;i++){
        for(int j=0;j<imgMask.cols;j++){
            //绘制每个区域的颜色
            int index=maskWaterShed.at<int>(i,j);
            if(index==-1)//区域间的值被置为-1(边界)
            {
                resultImg.at<Vec3b>(i,j)=Vec3b(255,255,255);
            }
            else if(index<=0||index>contours.size())//没有标记清楚的区域被置为0
            {
                resultImg.at<Vec3b>(i,j)=Vec3b(0,0,0);
            }else{
                resultImg.at<Vec3b>(i,j)=colors[index-1];
            }
        }
    }
    //显示给分水岭算法分割的每个区域添加颜色的结果
    imwrite("/sdcard/DCIM/resultImg2.png",resultImg);
    //分割的区域与原图像结合
    resultImg=resultImg*0.8+image*0.2;
    imwrite("/sdcard/DCIM/resultImg3.png",resultImg);

}
相关推荐
Raink老师5 小时前
【AI面试临阵磨枪】详细解释 Transformer 架构的核心组件与工作流程。
人工智能·深度学习·transformer·ai 面试·ai 应用开发
qcx235 小时前
【AI Agent实战】OpenClaw 安全加固完全指南:安全攻击手段与五步防护实践(2026最新)
人工智能·安全
故事和你915 小时前
洛谷-数据结构1-1-线性表1
开发语言·数据结构·c++·算法·leetcode·动态规划·图论
脱氧核糖核酸__5 小时前
LeetCode热题100——53.最大子数组和(题解+答案+要点)
数据结构·c++·算法·leetcode
码农小白AI5 小时前
AI报告审核进入技术驱动时代:IACheck如何从规则引擎走向深度学习,构建检测报告审核“技术矩阵”
人工智能·深度学习
song150265372986 小时前
视觉检测设备:自动识别缺陷、尺寸、瑕疵、装配错误,一键全检
人工智能·计算机视觉·视觉检测
智能化咨询6 小时前
(163页PPT)某著名企业K3生产制造售前营销指导方案P164(附下载方式)
大数据·人工智能
Zzj_tju6 小时前
大语言模型技术指南:SFT、RLHF、DPO 怎么串起来?对齐训练与关键参数详解
人工智能·深度学习·语言模型
金智维科技官方6 小时前
RPA技术赋能电信运营商话单稽核:金智维如何驱动高精度自动化转型
人工智能·自动化·数字化·rpa·智能体·电信
脱氧核糖核酸__6 小时前
LeetCode 热题100——42.接雨水(题目+题解+答案)
数据结构·c++·算法·leetcode