python计算不规则图形面积_python opencv中的不规则形状检测和测量

正如我在评论中提到的那样,对于这个问题,分水岭似乎是一个很好的方法.但是当你回答时,定义标记的前景和背景是困难的部分!我的想法是使用形态梯度沿着冰晶获得良好的边缘并从那里开始工作;形态梯度似乎很有效.

import numpy as np

import cv2

img = cv2.imread('image.png')

blur = cv2.GaussianBlur(img, (7, 7), 2)

h, w = img.shape[:2]

# Morphological gradient

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 7))

gradient = cv2.morphologyEx(blur, cv2.MORPH_GRADIENT, kernel)

cv2.imshow('Morphological gradient', gradient)

cv2.waitKey()

4c88f0415c12a7e4909334bff3fa6aa5.png

从这里开始,我使用一些阈值来对梯度进行二值化.可能有一种更清洁的方法来做到这一点……但这比我尝试过的其他一些想法更好.

# Binarize gradient

lowerb = np.array([0, 0, 0])

upperb = np.array([15, 15, 15])

binary = cv2.inRange(gradient, lowerb, upperb)

cv2.imshow('Binarized gradient', binary)

cv2.waitKey()

9838428b7b64778f34bc08cd55d96dc5.png

现在我们有几个问题.它需要一些清理,因为它很乱,而且,图像边缘的冰晶出现了 – 但我们不知道那些晶体实际上在哪里结束所以我们应该忽略那些.为了从掩码中删除它们,我遍历边缘上的像素并使用floodFill()从二进制图像中删除它们.不要在行和列的顺序上混淆; if语句指定图像矩阵的行和列,而floodFill()的输入需要点(即x,y形式,与row,col相反).

# Flood fill from the edges to remove edge crystals

for row in range(h):

if binary[row, 0] == 255:

cv2.floodFill(binary, None, (0, row), 0)

if binary[row, w-1] == 255:

cv2.floodFill(binary, None, (w-1, row), 0)

for col in range(w):

if binary[0, col] == 255:

cv2.floodFill(binary, None, (col, 0), 0)

if binary[h-1, col] == 255:

cv2.floodFill(binary, None, (col, h-1), 0)

cv2.imshow('Filled binary gradient', binary)

cv2.waitKey()

6xwNW.png

大!现在只是打开和关闭一些清理它…

# Cleaning up mask

foreground = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel)

foreground = cv2.morphologyEx(foreground, cv2.MORPH_CLOSE, kernel)

cv2.imshow('Cleanup up crystal foreground mask', foreground)

cv2.waitKey()

410fd300e4d6aa36b74e09f463375a29.png

所以这个图像被标记为“前景”,因为它具有我们想要分割的对象的可靠前景.现在我们需要创建一个确定的对象背景.现在,我以天真的方式做到了这一点,这只是为了使你的前景成长,所以你的对象可能都是在那个前景中定义的.但是,您可以使用原始蒙版或甚至渐变以不同的方式来获得更好的定义.尽管如此,这仍然可以,但不是很强大.

# Creating background and unknown mask for labeling

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (17, 17))

background = cv2.dilate(foreground, kernel, iterations=3)

unknown = cv2.subtract(background, foreground)

cv2.imshow('Background', background)

cv2.waitKey()

b91de874f67ae5669dfdaacd721f1d02.png

因此所有的黑色都是流域的“确定背景”.我还创建了未知矩阵,它是前景和背景之间的区域,这样我们就可以预先标记传递到分水岭的标记,“嘿,这些像素肯定在前景中,这些像素肯定是背景,我我不确定这些之间.“现在剩下要做的就是分水岭!首先,使用连接的组件标记前景图像,识别未知和背景部分,并将它们传递到:

# Watershed

markers = cv2.connectedComponents(foreground)[1]

markers += 1 # Add one to all labels so that background is 1, not 0

markers[unknown==255] = 0 # mark the region of unknown with zero

markers = cv2.watershed(img, markers)

你会注意到我在img上运行了分水岭().您可以尝试在图像的模糊版本上运行它(可能是中间模糊 – 我尝试了这个并且为晶体获得了更平滑的边界)或其他预处理版本的图像,这些版本定义了更好的边界或某些东西.

将标记可视化需要一些工作,因为它们在uint8图像中都是小数字.所以我做的是在0到179中为它们分配一些色调并在HSV图像中设置,然后转换为BGR以显示标记:

# Assign the markers a hue between 0 and 179

hue_markers = np.uint8(179*np.float32(markers)/np.max(markers))

blank_channel = 255*np.ones((h, w), dtype=np.uint8)

marker_img = cv2.merge([hue_markers, blank_channel, blank_channel])

marker_img = cv2.cvtColor(marker_img, cv2.COLOR_HSV2BGR)

cv2.imshow('Colored markers', marker_img)

cv2.waitKey()

d933367dc5d47f89a2543afe68abd51c.png

最后,将标记覆盖到原始图像上以检查它们的外观.

# Label the original image with the watershed markers

labeled_img = img.copy()

labeled_img[markers>1] = marker_img[markers>1] # 1 is background color

labeled_img = cv2.addWeighted(img, 0.5, labeled_img, 0.5, 0)

cv2.imshow('watershed_result.png', labeled_img)

cv2.waitKey()

094e6198d2f63c4158996a109664704d.png

嗯,那就是整个管道.您应该能够连续复制/粘贴每个部分,并且您应该能够获得相同的结果.该管道中最薄弱的部分是对梯度进行二值化并定义流域的确定背景.距离变换可能有助于以某种方式对梯度进行二值化,但我还没有到达那里.无论哪种方式……这是一个很酷的问题,我很想看到你对这个管道所做的任何改变,或者它对其他冰晶图像的影响.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/511741.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度解析开源推荐算法框架EasyRec的核心概念和优势

简介:如何通过机器学习PAI实现快速构建推荐模型 作者:程孟力 - 机器学习PAI团队 随着移动app的普及,个性化推荐和广告成为很多app不可或缺的一部分。他们在改善用户体验和提升app的收益方面带来了巨大的提升。深度学习在搜广推领域的应用也…

助力公益数字化 火山引擎向公益机构捐赠多款技术产品

5月18日,字节跳动公益联合火山引擎举办了“科技应用创新让公益更美好”线上交流会,与中国红十字基金会、壹基金等多家公益机构探讨如何利用科技信息化产品提升公益事业的效率,从而进一步解决社会问题。 交流会上,火山引擎联合Pic…

云效发布策略指南|滚动、分批、灰度怎么选?

简介:在日常和用户交流过程中,我们也经常会被用户问到关于发布的问题,比如不同职能团队之间应该如何配合、发布的最佳实践应该是什么样子的等等。今天我们就来聊聊常见应用发布方式的选择,以及每种发布模式适合什么样的场景。 无论…

shell安装mysql5.7_一键部署----shell脚本安装MySQL5.7

运维开发网 https://www.qedev.com2020-11-09 12:30出处:51CTO作者:wx5ddda4c97f426一键部署----shell脚本安装MySQL5.7#/bin/bashyum-yinstallncursesbisoncmakegccgcc-cncurses-develuseraddmysql-s/sbin/nologinread-p"输入你存放压缩包的绝对路…

极致用云,数智护航

简介:我们邀请到了阿里云混合云监控平台(Sunfire)团队负责人王肇刚来给我们分析下阿里背后的数字化业务运维安全工程标准及解决方案。 本次分享涵盖了全新发布的数字化业务运维安全工程标准、安全生产解决方案,以及全新升级的产品能力:包括了…

Lakehouse 架构解析与云上实践

简介:本文整理自 DataFunCon 2021大会上,阿里云数据湖构建云产品研发陈鑫伟的分享,主要介绍了 Lakehouse 的架构解析与云上实践。 作者简介:陈鑫伟(花名熙康),阿里云开源大数据-数据湖构建云产品…

菜鸟教程 mysql like_MySQL LIKE 子句

MySQL LIKE 子句我们知道在 MySQL 中使用 SQL SELECT 命令来读取数据,同时我们可以在 SELECT 语句中使用 WHERE 子句来获取指定的记录。WHERE 子句中可以使用等号 来设定获取数据的条件,如 "runoob_author RUNOOB.COM"。但是有时候我们需要获…

云原生 Serverless Database 使用体验

简介:表格存储 Tablestore 作为一款广泛应用 Serverless DataBase,能够提供经济的计费模式,可以大幅缩减业务成本的同时, 具备极致的弹性服务能力和完全零运维的特性,能够给用户带来更丝滑的使用体验。 作者 | 李欣 …

首推业人一体,北森2022春季发布会,正式发布iTalentX5.0

5月19日,中国最大的一体化HR SaaS及人才管理平台北森于线上召开“HR x业务”2022春季新品发布会,基于“业务人力一体化”理念发布iTalentX5.0,以战略和业务为牵引,用数字化平台赋能经理、员工和HRBP, 实现人力资源与业…

【阿里云 CDP 公开课】 第二讲:CDH/HDP 何去何从

简介:Hadoop社区版CDH/HDP已经不再更新,也将终止服务。后续的平台路线图怎么规划?Cloudera CDP整合了CDH和HDP,有哪些性能提升和功能增强?如何平滑的进行迁移?本文结合CDH/HDP平台现状,详细介绍…

mysql表全连接_关于mysql 实现表连接(左,右,内,全连接)

mysql 实现表连接(左,右,内,全连接)查询中出现两个表的连接,下面通过实例来讲解一下各种连接查询的不同之处表 a,和表b 如下图a 表中 有 abcdb表中有 abcf内连接:SELECT * from a INNER JOIN b on a.nameb.…

阿里云 Serverless Kubernetes 的落地实践分享

简介:Serverless Kubernetes 基于 Kubernetes 之上,提供按需使用、节点免运维的 Serverless 能力,让开发者真正实现通过 Kubernetes 标准化 API 进行 Serverless 应用编程,值得关注。 作者 | 元毅(阿里云容器平台高级开…

DevLake 加入 Apache 孵化器,开源共建 Apache 生态首个研发大数据平台

4 月 29 日,开源研发数据平台 DevLake 通过投票决议,正式成为 Apache 软件基金会 (ASF) 的孵化项目。 进入孵化后,Apache DevLake 将遵循 The Apache Way[1],在导师们的引导下,坚持以人为本、社区高于代码的理念&#…

idea连接mysql注册登录_IDEA+MySQL实现登录注册的注册验证时出现 Cannot resolve query parameter '2'...

问题描述:在ideamysqltomcat 实现登录注册jsp的注册信息insert验证时出现 cannot resolve query parameter 2贴上创建链接的代码:if(conn ! null){string sql "select *from login_info where dbuser?";pstm conn.preparestatement(sql);ps…

如何画一张架构图(内含知识图谱)

简介:架构图是什么?为什么要画架构图?如何画好架构图?有哪些方法?本文从架构的定义说起,分享了阿里文娱高级技术专家箫逸关于画架构图多年的经验总结,并对抽象这一概念进行了深入地讨论。内容较…

软件分析与设计:分析什么?如何设计?

简介:分析与设计这两个词我们平时经常听到,也经常讲,那么分析与设计的本质究竟是什么呢?到底要分析什么?又到底要怎样去设计?这3个问题如果平时没有一些积累,突然被问到这些,一时也会…

协程到底有什么用?6种I/O模式告诉你!

作者 | 陆小风来源 | 码农的荒岛求生今天来聊一聊协程的作用。假设磁盘上有10个文件,你需要读取的内存,那么你该怎么用代码实现呢?在接着往下看之前,先自己想一想这个问题,看看自己能想出几种方法,各自有什…

阿里云数据治理系列(一):治理项目启动前的必答三问

简介:近一年以来,越来越多的企业在考虑或正在启动数据治理的项目。作为在该领域从业多年的人士,也常会被咨询:数据治理不是很多年前就有的概念么?为什么忽然很多企业都在提及?是不是新瓶装旧酒?…

揭晓远程证明架构EAA:机密容器安全部署的最后一环 | 龙蜥技术

简介:如果需要在云上 HW-TEE 环境里启动一个加密容器,如何在启动过程中获取容器的解密密钥? 文 / 周亮, 云原生机密计算 SIG 核心成员。 在云原生场景下,基于HW-TEE(如Intel SGX, Intel TDX 和 AMD SEV&am…

java哪个城市的需求量大_4大互联网热门城市Java薪资情况,看完你想去哪个城市发展呢?...

程序员作为薪资最高的行业之一,一直是很多人转行的热门首选行业。Java程序员又在所有程序员中占比最大, 因此,Java程序员的薪资就能够很好的代表行业的薪资水准。今天就为大家整理一下4大热门城市的Java薪资情况,看看你还差多少&a…