《使用OpenCV的分水岭算法》

  之前利用watershed想对相对前背景较为明显的图像进行图像语义分割的预打标,因为虽然前景明显,但是边缘打标也是很困难的,可以用该方法对大部分的边缘进行获取,然后用pixel Annotation进行标注即可。

Key Words:分水岭算法、OpenCV、 图像分割

Beijing, 2020

作者:RaySue

Code:

Agile Pioneer  

文章目录

  • 分水岭算法原理
  • OpenCV函数
  • 使用流程
    • 使用分水岭算法的通用步
    • 分割鸡蛋为例
  • 参考

分水岭算法原理

算法步骤:

  1. 构建图像梯度图像(构造边缘)。
  2. 通过一定规则生成 n 个最初的注水区域(先验知识或局部梯度最小值,种子)。
  3. 往注水区域内加水,当两注水区域即将合并时,记录下此时的边界。
  4. 当图像边缘彻底被分割成 n 个独立区域是算法结束。


OpenCV函数

void watershed( InputArray image, InputOutputArray markers );
cv2.watershed(image, markers)

使用流程

使用分水岭算法的通用步

  • 自动生成种子

    • 输入图像 -> 灰度 -> 二值化(二值化之后注意一下前景是 255 还是 0) -> 距离变换 -> 寻找种子 -> 生成Marker -> 分水岭变换 -> 输出图像
  • 手动指定已经确定的前景(2)和背景(1)作为种子

分割鸡蛋为例

  • 代码

import cv2
import numpy as np
import matplotlib.pyplot as pltdef watershed(image_path):image_name = image_path.split("/")[-1]image = cv2.imread(image_path)# image = multiScaleSharpen(image, 5)# 前提:降噪# blurred = cv2.pyrMeanShiftFiltering(image, 25, 100)gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 第一步:灰度处理# 第二步:二值化处理 + 反色处理 255 -> 0 | 0 -> 255# ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)# 对二值化的结果执行开运算# noise removalkernel = np.ones((3, 3), np.uint8)opening = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel, iterations=2)# sure background areasure_bg = cv2.dilate(opening, kernel, iterations=3)# Finding sure foreground areadist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)# 通过距离变换的结果取二值化,得到前景ret, sure_fg = cv2.threshold(dist_transform, 0.5 * dist_transform.max(),255, 0)# Finding unknown regionsure_fg = np.uint8(sure_fg)unknown = cv2.subtract(sure_bg, sure_fg)# Marker labellingret, markers = cv2.connectedComponents(sure_fg)# Add one to all labels so that sure background is not 0, but 1markers = markers + 1# Now, mark the region of unknown with zeromarkers[unknown == 255] = 0sure_bg[unknown == 255] = 0sure_bg[sure_bg == 255] = 2sure_bg = sure_bg.astype(np.int32)# plt.figure(1)# plt.title("sure_bg")# plt.imshow(sure_bg)# 分水岭只是对0的位置进行分割 1-背景 0-待分割 2-前景result = cv2.watershed(image, markers=markers)# 分水岭结果标记轮廓为红色image[result == -1] = [255, 0, 0]# cv2.imwrite("./watershed_res.jpg", result)plt.figure(0)plt.subplot(231)plt.title("binary")plt.imshow(binary)plt.subplot(232)plt.title("seed new")plt.imshow(sure_bg)plt.subplot(233)plt.title("distance")plt.imshow(dist_transform * 50)plt.subplot(234)plt.title("seed ori")plt.imshow(markers)plt.subplot(235)plt.title("result markers")plt.imshow(result)plt.subplot(236)plt.title("watershed")plt.imshow(image)# plt.savefig(os.path.join(output_dir, "watershed_" + image_name))plt.show()watershed("/Users/i/Desktop/Screenshot 2020-10-23_17-48-13-153.jpg")


参考

https://blog.csdn.net/HXG2006/article/details/80019736

https://blog.csdn.net/weixin_40647819/article/details/90231477

使用OpenCV的分水岭算法相关推荐

  1. pythonopencv算法_python opencv之分水岭算法示例

    本文介绍了python opencv之分水岭算法示例,分享给大家,具体如下: 目标 使用分水岭算法对基于标记的图像进行分割 使用函数cv2.watershed() 原理: 灰度图像可以被看成拓扑平面, ...

  2. opencv实现分水岭算法

    opencv实现分水岭算法 // 分水岭算法原理 // IplImage* marker_mask = 0; IplImage* markers = 0; //IplImage* img0 = 0, ...

  3. python opencv 利用分水岭算法实现对物体的分割 图文详细注释版 以分割官网提供的硬币为例

    分水岭算法可以实现自动分割多个物体,opencv中 cv.watershed() 函数实现了分水岭算法 话不多说,上代码 # 利用分水岭算法分离多个相同硬币 import numpy as np im ...

  4. 【OpenCV】- 分水岭算法

    文章目录 什么是图像分割 分水岭算法 1.实现分水岭算法:watershed()函数 2.处理流程(视频) 3.示例程序(书中) 什么是图像分割 将图像中像素根据一定的规则分为若干个cluster集合 ...

  5. opencv之分水岭算法分割及图像修补

    1)分水岭算法 原理: 任何一幅灰度图像都可以被看成是拓扑平面,灰度值高的区域可以被看成是山峰,灰度值低的区域可以被看成是山谷,我们向每一个山谷中灌不同颜色的水,随着水位的升高,不同山谷的水就会相遇汇 ...

  6. OpenCV之分水岭算法

    分水岭算法 在许多实际的应用中,我们需要分割图像,但是无法从背景图像中获得有用信息.但是分水岭算法在这方面往往非常有效,它可以将图像中的边缘转化为"山脉",将均匀区域转化为&quo ...

  7. 【python】【openCV】分水岭算法

    脑血管医学图像颅内分割尝试--分水岭算法 code 1.2 不分割颅内直接分割 code 2.0 实验版 code 3.0 批量处理版 code 3.1 加入孔洞填充 总结 本篇博客原目的同https ...

  8. opencv 图像分割-分水岭算法

    任何灰度图都恶意被看作是一个地形面,高强度表示山峰和山丘,低强度则表示山谷.开始使用不同的水来填充每个孤立的山谷(局部最小值).随着水的上升,来自不同山谷的水,开始融合.为了避免这种情况,在水合并的地 ...

  9. Opencv 分水岭算法 watershed的图像分割

    分水岭算法 参考博客: (1)迈克老狼2012   https://www.cnblogs.com/mikewolf2002/p/3304118.html (2)-牧野-              h ...

最新文章

  1. firebase 推送_如何使用Firebase向Web应用程序添加推送通知?
  2. 微软职位内部推荐-Sr. SW Engineer for Privacy Id
  3. mnn python 笔记
  4. C++中的 c_str() 函数
  5. Android笔记(三十一)Android中线程之间的通信(三)子线程给主线程发送消息...
  6. 如何使用matplotlib绘制一个函数的图像
  7. sqlserver常用函数/存储过程/数据库角色
  8. k近邻算法C++二维情况下的实现
  9. Mysql中int(M)的含义
  10. ld-linux.so.2 重定向,2-Linux重定向和管道、Shell编程.doc
  11. cordova 某个页面强制横屏_小白科普:从输入网址到最后浏览器呈现页面内容,中间发生了什么?...
  12. 系统建模与仿真 - 电子书下载(高清版PDF格式+EPUB格式)
  13. element cannot be mapped to a null key
  14. Fiddler - IOS 开启证书(描述文件与设备管理 / 证书信任设置)
  15. CSS中的伪类选择器、颜色、度量单位、文本字体及文本样式设置
  16. MySQL功能大全(细品)
  17. 拉普拉斯变换的性质 - 对查表
  18. 天兔lepus部署文档
  19. 运维自动化工具-ansible的安装与ad-hoc模式场景应用
  20. 智能手机PDR和VDR思考

热门文章

  1. 股票beta值的均值_如何在R中找到值的均值
  2. 捷径app 保存视频_Android N App捷径
  3. android传感器_Android传感器
  4. testng 监听器_TestNG侦听器
  5. scala中命名参数函数_Scala中的命名参数和默认参数值
  6. 全栈工程师的价值是什么?
  7. C++学到什么程度才算是精通?
  8. xcodebuild -exportArchive -allowProvisioningUpdates
  9. maven之打包插件(maven-assembly-plugin,maven-shade-plugin与maven-assembly-plugin)
  10. 10个有关RESTful API良好设计的最佳实践