34,35-基于距离变换与分水岭的图像分割

基于距离变换和分水岭算法的图像分割 1 原始代码【matlab】 2.1 图像增强   针对现场生产环境复杂、生产车间内存在各种干扰的问题,在分析图像前,必须对获取的图像进行预处理,截取ROI区域,提高图像的质量,使其更适于后续算法的分析和处理。本文首先截取图像的ROI区域,针对图片明暗分布不均、图像细微处对比度低的问题,采用对比度受限的自适应直方图均衡化方法(CLAHE)[5]对图像进行增强。传统直方图均衡化是在图像全局增强对比度,它对数据的处理不加选择,由于本系统采集的图像常会出现部分区域对比度较好,部分较差,CLAHE算法更适用于 阅读详情

基于距离变换与分水岭的图像分割(基于图像的拓扑结构)

1、图像分割概念;
2、距离变换和分水岭介绍;
3、相关API;
4、Code;

图像分割(Image Segmentation)

1、图像分割: 将对象从背景中分离出来;常见的图像分割算法实现有很多;

在这里插入图片描述

2、图像分割的目标是将图像中的像素根据一定的规则(算法)分为若干个(cluster)集合,每个集合包含一类像素;
3、图像分割算法可以分为监督学习方法和无监督学习方法,图像分割算法多数都是无监督学习方法(Kmeans); 属于数据处理与机器学习范围;

在这里插入图片描述

距离变换与分水岭介绍

1、距离变换:
在这里插入图片描述

2、分水岭:(与水淹山头现象大概类似);理论为分水岭浸泡理论;

在这里插入图片描述
3、距离变换算法的两种原理:①不断膨胀腐蚀(dilate,erode)得到;②基于倒角距离;分水岭变换常见算法:①基于浸泡理论实现;
在这里插入图片描述

相关API

1、距离变换API :cv::distanceTransform();
labels : 距离变换出来的相同距离的分类;
distancetype : 距离类型;
maskSize : 腐蚀和膨胀的掩膜
2、分水岭变换API : cv::watershed(); shed : 分水岭
markers : 输出分割标线;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

使用流程

1、将白色背景改为黑色,为变换做准备;
2、使用filter2D与Laplace算子实现图像对比度的提高;sharp锐化
3、通过threshold()转换为二值图像;
4、距离变换;
5、对距离变换的结果归一化到0-1之间;
6、使用阈值,再次二值化,得到标记;
7、腐蚀(erode)得到每个Peak;(peak : 山峰,山顶 )
8、发现轮廓;
9、绘制轮廓;
10、分水岭变换;
11、对每个分割区域着色输出结果;

Code

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

const char* input_win = "input image";
const char* output_win = "watershed segementation demo";

int main(int argc, char** argv)
{
	Mat src = imread("C:\\Users\\hello\\Desktop\\39.jpg");
	if (src.empty())
	{
		cout << "could not load the image..." << endl;
		return -1;
	}
	namedWindow(input_win, WINDOW_AUTOSIZE);
	namedWindow(output_win, WINDOW_AUTOSIZE);
	imshow(input_win, src);
	//1、改变背景色
	for (int row = 0; row < src.rows; row++)
	{
		for (int col = 0; col < src.cols; col++)
		{
			if (src.at<Vec3b>(row, col) == Vec3b(255, 255, 255))
			{
				src.at<Vec3b>(row, col)[0] = 0;
				src.at<Vec3b>(row, col)[1] = 0;
				src.at<Vec3b>(row, col)[2] = 0;
			}
		}
	}
	imshow("black backbround", src);
	//2、锐化Sharp --- Sharpen
	Mat kernel = (Mat_<float>(3, 3) << 1, 1, 1, 1, -8, 1, 1, 1, 1);  //定义掩膜
	Mat imgLaplace;
	Mat sharpenImg ;
	filter2D(src, imgLaplace, CV_32F, kernel, Point(-1, -1),0,BORDER_DEFAULT);  //imgLaplace 的位图深度应为32F
	src.convertTo(sharpenImg, CV_32F);
	Mat resultImg = sharpenImg - imgLaplace;  //加减必须类型一致
	//锐化图像转换
	resultImg.convertTo(resultImg, CV_8UC3);
	imgLaplace.convertTo(imgLaplace, CV_8UC3);
	imshow("sharpen image", resultImg);
	src = resultImg; //copy back 

	//3、二值图像变换 convert to binary
	Mat binaryImg;
	cvtColor(src, resultImg, CV_BGR2GRAY);
	threshold(resultImg, binaryImg, 40, 255, THRESH_OTSU | THRESH_BINARY);  //产生二值图像,自动寻找阈值
	imshow("binary image", binaryImg);

	//4、距离变换
	Mat distImg;
	distanceTransform(binaryImg, distImg, DIST_L1, 3, 5);  //距离变换
	//5、归一化
	normalize(distImg, distImg, 0, 1, NORM_MINMAX, -1, Mat());  //归一化
	imshow("distance result", distImg);    
	//6、再次阈值化
	threshold(distImg, distImg, 0.4, 1, THRESH_BINARY);  //阈值0.4是自己提前试出来的
	imshow("distance binary image", distImg);
	//7、腐蚀
	Mat k1 = Mat::zeros(3, 3, CV_8UC1);
	erode(distImg, distImg, k1, Point(-1, -1));
	imshow("erode image", distImg);
	//8、mask标记
	Mat dist_8u;
	distImg.convertTo(dist_8u, CV_8U);
	vector<vector<Point>> contours;
	findContours(dist_8u, contours, RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

	Mat markers = Mat::zeros(src.size(), CV_32SC1);

	for (size_t i = 0; i < contours.size(); i++)
	{
		drawContours(markers, contours, static_cast<int>(i), Scalar::all(static_cast<int>(i) + 1),-1); //thicknesss : -1代表填充
	}
	circle(markers, Point(5, 5), 3, Scalar(255, 255, 255), -1);  
	imshow("my markers", markers * 1000); //markers像素值很低,*1000放大

	//根据markers对src进行分水岭
	watershed(src, markers);    //计算值会放到markers中

	Mat mark = Mat::zeros(markers.size(), CV_8UC1);
	markers.convertTo(mark, CV_8UC1);

	bitwise_not(mark, mark, Mat());
	imshow("watershed image", mark);    //分水岭图像为灰度图像,不太清晰

	//产生随机颜色填充
	vector<Vec3b> colors;
	for (size_t i = 0; i < contours.size(); i++)
	{
		int r = theRNG().uniform(0, 255);
		int g = theRNG().uniform(0, 255);
		int b = theRNG().uniform(0, 255);

		colors.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));
	}
	//着色
	Mat dst = Mat::zeros(markers.size(), CV_8UC3);
	for (int row = 0; row < markers.rows; row++)
	{
		for (int col = 0; col < markers.cols; col++)
		{
			int index = markers.at<int>(row, col);    
			if (index > 0 && index <= static_cast<int>(contours.size()))
			{
				dst.at<Vec3b>(row, col) = colors[index - 1];
			}
			else
			{
				dst.at<Vec3b>(row, col) = Vec3b(0, 0, 0);
			}
		}
	}
	imshow("final result", dst);

	waitKey(0);
	return 0;
}

效果

在这里插入图片描述
在这里插入图片描述

锐化图:
在这里插入图片描述
二值图:
在这里插入图片描述
距离变换:
在这里插入图片描述
再次二值化:
在这里插入图片描述
腐蚀:
在这里插入图片描述
Mark标记图像:
在这里插入图片描述
最终分水岭图像:
在这里插入图片描述
着色:
在这里插入图片描述

OpenCV手眼标定(calibrateHandeye()) 文章目录说明Code实验效果参考 说明 Code #include <opencv2/opencv.hpp> #include <iostream> #include <math.h> using namespace std; using namespace cv; Mat R_T2HomogeneousMatrix(const Mat& R, co... 阅读详情

相关推荐

基于距离变换和分水岭分割的图像分割代码

基于距离变换和分水岭分割的图像分割代码,VS2013, opencv2.4.9,

OpenCV —— 图像分割之基于距离变换的分水岭分割

图像分割处理流程 1. 原图像灰度化,二值化,开运算消除噪点 2. 距离变换,归一化 `distanceTransform` `normalize` 3. 再次二值化,得到确定的前景,即种子 4. 根据种子生成 Marker,可以通过以下两种方式生成: * 查找连通分量 `connectedComponents` * 查找轮廓,绘制轮廓 `findContours`, `drawContours` 5. 分水岭变换 `watershed` 6. 输出图像

学无止境 4213

opencv中基于距离变换与分水岭变换的图像分割代码

在win32控制台程序中,opencv中基于距离变换与分水岭变换的图像分割代码

分水岭算法java,C++实现分水岭算法(Watershed Algorithm)

分水岭分割方法(Watershed Segmentation),是一种基于拓扑理论的数学形态学的分割方法,其基本思想是把图像看作是测地学上的拓扑地貌,图像中每一点像素的灰度值表示该点的海拔高度,每一个局部极小值及其影响区域称为集水盆,而集水盆的边界则形成分水岭。分水岭的概念和形成可以通过模拟浸入过程来说明。在每一个局部极小值表面,刺穿一个小孔,然后把整个模型慢慢浸入水中,随着浸入的加深,每一个局部...

weixin_42498643的博客 606

Flutter for web 首次加载过慢问题优化

Flutter web 加载慢优化

Bright_TY的专栏 7834

UDP_千兆光通信(四)Tri Mode Ethernet MAC ip核

其中 Transmit Engine 从 AXI-Stream TX 接口接收数据,并添加前导码 Preamble、帧起始界定符 SFD、帧校验序列 FSC 等,并在必要时(长度小于最小 MAC 帧长度)填充数据,因此在使用 TEMAC 时,MAC 帧的这几个部分就不需要我们自己添加了(不过其他的 MAC 帧部分,可选的帧过滤器 Frame Filter 用于过滤与一组可配置过滤器匹配的帧,一般用于过滤掉目的 MAC 地址与本设备不一致的帧,TEMAC 默认开启帧过滤器。默认值为使用64位宽的计数器。

lzr232的博客 1767

open cv基于距离变换与分水岭的图像分割

/* 什么是图像分割(Image Segmentation) 图像分割是图像处理最重要的处理手段之一 图像分割的目标是将图像中像素根据一定的规则分为若干(N)个cluster(集群)集合 每个集合包含一类像素,根据算法分为监督学习和无监督学习方法,图像分割的 算法多数都是无监督学习方法—Kmeans 应用领域:如果应用到单幅图像上则是主要为图像窄化 骨架提取 粘连物体的分离等 如果应用到原图跟模板图则是应用于图像匹配 封闭性是分水岭算法的一个重要特征 其他图像分割方法,如阈值,边缘检测等都不会考虑像素在

Chroniccandy的博客 1010

STRING数据库的蛋白质相互作用(PPI)网络分析

在转录调控相关的文献中,我们经常能够看到这样的蛋白质相互作用网络(protein protein interaction network,PPI network)。具体而言,这些相关的文献中首先通过RNA-seq、表达谱芯片或者蛋白质组分析等,找到了在不同分组样本间一系列的差异表达基因或蛋白。

weixin_43029125的博客 9450

C++ OpenCV基于距离变换与分水岭的图像分割

点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达图像分割图像分割,英文名image segmentation,就是把图像分成若干个特定的、具有独特性质的区域并提出感兴趣目标的技术和过程。它是由图像处理到图像分析的关键步骤。现有的图像分割方法主要分以下几类:基于阈值的分割方法基于区域的分割方法基于边缘的分割方法以及基于特定理论的分割方法从数学角度来看,图像分割是将数字图像划分成...

小白学视觉 1062

【SpringBoot香樟转转】debugDay01

在学黑马程序员的苍穹外卖项目,刚开始学,想用maven编译一下代码,结果报错,找不到符号。本着先理解原则,看着能找到这个变量呀。

m0_72696598的博客 1737

不会精准对比前人研究写“讨论与对比”段落?教你用ChatGPT辅助,直接让这部分提升一个档次(附提示词指令)

一个我觉得很有效的做法是,选取几篇具有代表性的文献,从研究方法、变量设置或结论方面进行对照分析,并指出本研究在哪些方面进行了补充或修正。除了简单说“提出了新的方法”或“首次应用某模型”,更需要说明这一做法在结果解读、研究设计或理论拓展上的具体意义,最好能够与现有研究进行比较,形成明确的差异化描述。段落应包含:研究结果解释、与前人研究对比、研究贡献、局限性反思,并在结尾提出未来研究的可能方向。讨论与对比部分一般位于文献综述、研究讨论或结果分析的后面,目的是对比已有研究,突出自己研究的价值与新意。

智能AI让学术科研更容易 170

OpenCV(26)图像分割 -- 距离变换与分水岭算法(硬币检测、扑克牌检测、车道检测)

一、基础理论 1、思想 防止同化。 任何灰度图像都可以看作是一个地形表面,其中高强度表示山峰,低强度表示山谷。你开始用不同颜色的水(标签)填充每个孤立的山谷(局部最小值)。随着水位的上升,根据附近的山峰(坡度),来自不同山谷的水明显会开始合并,颜色也不同。为了避免这种情况,你要在水融合的地方建造屏障。你继续填满水,建造障碍,直到所有的山峰都在水下。然后你创建的屏障将返回你的分割结果。这就是Watershed背后的“思想”。你可以访问Watershed的CMM网页...

great_yzl的博客 1万+

36、真核生物RNA PolII启动子预测相关研究

本文综述了真核生物RNA聚合酶II启动子预测的研究进展,涵盖转录调控机制、核心启动子元件(如TATA框、INR、GC框)、转录因子结合位点预测的挑战与方法。介绍了基于权重矩阵、神经网络和隐马尔可夫模型等多种启动子预测算法,并探讨了启动子分类策略及评分加权方法。通过Hertz-Stormo-Hartzell流程和基因微阵列分析实例,展示了如何识别保守调控序列。文章还总结了当前预测技术的局限性,提出了整合多组学数据、开发深度学习模型、加强实验验证等未来研究方向,旨在提升启动子识别的准确性与生物学意义。

palm99的专栏 187

opencv入门(18)-- 基于距离变换的分水岭分割

图像分割(Image Segmentation)是对图像中指定对象进行定位轮廓分割。图像分割的目的是将图像中像素根据一定规则分为若干个簇(cluster)集合,每个集合包办一类像素。根据算法可分为监督学习和无监督学习。距离变换:可以参考点与多边形的关系,可以算出每个像素点到多边形轮廓的距离得到距离图像。距离变换常见的算法有:不断膨胀/腐蚀得到和基于倒角距离两种。定义是计算一个图像中非零像素点到最近的零像素点的距离,也就是到零像素点的最短距离。

weixin_43212588的博客 715

十五、【测试执行篇】异步与并发:使用 Celery 实现测试任务的后台执行与结果回调

本文介绍如何使用Celery实现测试任务的异步执行与结果回调,解决同步执行测试计划导致的请求阻塞问题。主要内容包括:Celery的基本概念与工作原理(任务队列、消息中间件、Worker进程),在Django项目中集成Celery的步骤,以及将同步测试逻辑改造为异步任务的方法。

blues_C的博客 707

基于深度学习的停车位检测系统(UI界面 + YOLOv8/v7/v6/v5代码 + 训练数据集)

传统的停车位检测方法主要依赖于人工或基于简单图像处理的技术,存在检测速度慢、准确率低、环境适应性差等问题。近年来,随着深度学习技术的快速发展,基于目标检测的停车位检测系统已成为研究的热点。本文基于YOLO(You Only Look Once)系列模型(包括YOLOv5、YOLOv6、YOLOv7和YOLOv8),开发了一个完整的停车位检测系统,支持实时检测、结果可视化以及UI交互界面。本文实现了一个基于深度学习的停车位检测系统,采用YOLO模型在实时视频流中进行高效检测。

YOLO 332

OpenCV 图像处理学习二十二,基于距离变换和分水岭的图像分割

基于距离变换和分水岭的图像分割

weixin_44651073的博客 2355

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Opencv-C++笔记 (20) : 距离变换与分水岭的图像分割

在 O p e n C v OpenCvOpenCv 中算法不从最小值开始增长,可以将相对较高的灰度值像素作为起始点(需要用户手动标记),从标记处开始进行淹没,则很多小区域都会被合并为一个区域,这被称为基于图像标(mark)的分水岭算法。cv2.distanceTransform计算的是图像内非零值像素点到最近的零值像素点的距离,即计算二值图像中所有像素点距离其最近的值为 0 的像素点的距离。在使用cv::watershed函数进行分水岭算法分割时,需要先进行前期处理,包括图像的预处理和创建标记图像。

jiyanghao19的博客 1625

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Python opencv图像处理基础总结(七) 基于分水岭算法的图像分割

opencv图像处理基础总结,基于分水岭算法的图像分割,介绍了分水岭算法的原理、距离变换、opencv有关函数的用法,基于距离的分水岭分割的流程,python代码实现分水岭算法的图像分割

叶庭云 成为自己的光 5942

分水岭算法和距离变换函数

分水岭算法和距离变换函数分水岭算法原理算法流程距离变换函数区域标记结果分割示例代码分水岭分割距离函数 分水岭算法原理 在地理学中,分水岭是一个山脊,该山脊通过不同的水系来区分排水区域。集水盆地是把水排入河流或水库的地理区域。分水岭变换把这些概念应用到灰度图像处理中,从而解决许多图像分割问题。 我们把灰度图像视为一个拓扑表面,表面中f(x,y)的值被解释为高度。例如,我们可以把下图中的简单图像形象化为下图中的三维表面。如果雨水降落到该表面上,那么雨水明显会流人集水盆地中。正好降落到分水岭脊线上的雨水会等概率地

留缘的博客 5776

【youcans 的 OpenCV 例程200篇】180.基于距离变换的分水岭算法

分水岭算法是基于形态学的图像分割方法,体现了边缘检测、阈值处理和区域提取的概念和思想,往往会产生更稳定的分割结果。 最简单的分水岭算法的是基于距离变换,通过每个像素到最接近零值的像素的距离生成标注图像。 OpenCV 提供了函数 **cv.watershed** 实现基于标记的分水岭算法,函数 **cv.distanceTransform** 实现距离变换,计算图像中每个像素到最近的零像素点的距离。

youcans的博客 2776

基于距离变换和分水岭的图像分割

第一步:读取图片 Mat img = imread("../img/cards.png", CV_LOAD_IMAGE_COLOR); if(img.empty()) return -1; namedWindow( "input", CV_WINDOW_AUTOSIZE ); imshow("input", img); 所读取的图片如下: 第二步:将图片的白色的背景变为黑色的背景 fo...

xiuxiu__deng的博客 2565

基于距离变换和分水岭算法的图像分割(图像变换 )

// 加载图像 Mat src = imread("../data/cards.png"); // 成功加载 if (!src.data) return -1; // 显示图像 imshow("Source Image", src); 如果我们用白色背景图像,转换它的黑色是好的。这将有助于我们descimi

chaihuimin的专栏 5325

【OpenCV学习笔记】之基于距离变换与分水岭图像分割算法

什么是图像分割? 图像分割(Image Segmentation)是图像处理最重要的处理手段之一。 图像分割的目标是将图像中像素根据一定的规则分为若干(N)个cluster集合,每个集合包含一类像素。 根据算法分为监督学习方法和无监督学习方法,图像分割的算法多数都是无监督学习方法 - KMeans  距离变换常见算法有两种:  距离变换的定义 :计算图像中像素点到最近零像素点的距离,也就是...

zhu_hongji的博客 4970
上一篇: 33-点多边形测试
下一篇: 1-EmguCV
hellohake
博客等级 码龄10年 4543粉丝 108原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值