计算机视觉 图片处理 在骨架化过程中,每次迭代都会从图像的边缘移除一层像素,直到只剩下单像素宽度的骨架

你说得对,if cv2.countNonZero(binary) == 0: break 这个条件确实表示图像中已经没有非零像素,即图像完全变为空白。这并不是骨架化完成的标志,而是表示图像已经被腐蚀到没有任何内容了。

在骨架化过程中,我们需要一个更合适的停止条件,以确保图像被正确地简化为单像素宽度的骨架,而不是被完全腐蚀掉。

骨架化的正确停止条件

在骨架化过程中,每次迭代都会从图像的边缘移除一层像素,直到只剩下单像素宽度的骨架。正确的停止条件是当图像中不再有可以被移除的像素时,即图像已经不能再被腐蚀,但仍然有非零像素存在。

改进的骨架化代码

以下是一个更完整的骨架化代码示例,其中包含了正确的停止条件:

import cv2
import numpy as npdef skeletonize(image):# 确保输入图像是二值化的_, binary = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)# 创建结构元素element = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))# 初始化骨架图像skeleton = np.zeros_like(binary)# 初始化前一次的骨架图像prev_skeleton = np.zeros_like(binary)# 迭代直到骨架图像不再变化while True:# 腐蚀操作eroded = cv2.erode(binary, element)# 膨胀操作temp = cv2.dilate(eroded, element)# 计算差值temp = cv2.subtract(binary, temp)# 更新骨架skeleton = cv2.bitwise_or(skeleton, temp)# 更新二值图像binary = eroded.copy()# 检查骨架图像是否发生变化if np.array_equal(skeleton, prev_skeleton):break# 更新前一次的骨架图像prev_skeleton = skeleton.copy()return skeleton# 读取图像
image = cv2.imread('your_image.png', cv2.IMREAD_GRAYSCALE)# 骨架化处理
skeleton = skeletonize(image)# 显示结果
cv2.imshow('Skeleton', skeleton)
cv2.waitKey(0)
cv2.destroyAllWindows()

代码解释

  1. 初始化骨架图像和前一次骨架图像

    • skeleton 用于存储当前的骨架图像。
    • prev_skeleton 用于存储上一次迭代的骨架图像,以便比较是否发生变化。
  2. 迭代处理

    • 每次迭代中,先对当前的二值图像进行腐蚀操作,然后进行膨胀操作。
    • 计算腐蚀和膨胀后的图像的差值,这个差值就是当前迭代的骨架部分。
    • 将差值与之前的骨架图像进行逻辑或操作,更新骨架图像。
    • 更新二值图像为腐蚀后的图像,继续下一次迭代。
  3. 停止条件

    • 使用 np.array_equal(skeleton, prev_skeleton) 检查当前的骨架图像是否与上一次的骨架图像相同。
    • 如果相同,说明骨架图像已经不再变化,此时已经完成了骨架化,退出循环。

为什么这样可以

在骨架化过程中,每次迭代都会从图像的边缘移除一层像素,直到只剩下单像素宽度的骨架。当骨架图像不再变化时,说明已经无法再从边缘移除像素,此时的骨架图像就是最终的骨架。

结果

使用上述代码,你可以得到一个单像素宽度的骨架图像,而不是一个完全空白的图像。这种骨架化方法在许多计算机视觉任务中非常有用,尤其是在需要提取形状特征的场景中。

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

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

相关文章

rt-thread audio框架移植stm32 adc+dac,用wavplayer录音和播放

D1 参考 rt-thread官方sdk中,正点原子stm32f429-atk-appollo的board中有audio文件夹,包括了mic/play的程序,wm8978的库文件因为我们基于stm32h750内置adcdac设计,所以不需要wm8978.c/h。只需要移植drv_sound.c和drv_mic.c D2 工程…

AI重塑软件测试:质量保障的下一站

软件开发的世界变化飞快,系统越来越复杂,用户的胃口越来越大,产品上线的压力也越来越大。作为测试工程师,你是不是常常觉得传统测试已经跟不上节奏了?手工测试累死人,自动化脚本维护到崩溃,测试…

【前端基础知识系列六】React 项目基本框架及常见文件夹作用总结(图文版)

在 React 开发中,一个清晰合理的项目结构不仅能提高开发效率,还能让代码更易于维护和扩展。尤其是在团队协作中,统一的项目结构规范至关重要。本文将通过图文结合的方式,详细介绍 React 项目的基本框架以及常见文件夹的定义与作用…

0815 UDP通信协议TCP并发服务器

Part 1.思维导图一.UDP通信协议1.原理服务器端:1.用socket函数创建一个套接字文件2.创建服务器端地址结构体并赋值3.用ford函数将套接字文件与地址结构体绑定4.创建接收客户端地址结构体5.利用sendto和recvfrom函数传输和接收信息客户端:1.用socket函数创…

一个基于纯前端技术实现的五子棋游戏,无需后端服务,直接在浏览器中运行。

一 功能特性1.1 核心游戏功能- **标准五子棋规则**:1515棋盘,黑子(玩家)先手 - **AI对战模式**:白子AI具有中等难度,会进行智能进攻和防守 - **胜负判定**:支持横向、纵向、斜向五子连线获胜 - **平局检测**&#xff1…

HBuilderX升级,Vue2 scss 预编译器默认已由 node-sass 更换为 dart-sass

目录 一、问题描述 二、问题原因 三、问题解析及解决方案 一、问题描述 最近开发新项目,升级了HBuilderX版本到4.75,最近要在之前的项目添加功能的时候发现报错,错误如下:Vue2 scss 预编译器默认已由 node-sass 更换为 dart-sa…

像素风球球大作战 HTML 游戏

像素风球球大作战 HTML 游戏 下面是一个简单的像素风格球球大作战 HTML 游戏代码&#xff1a; <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-widt…

文件导出时无法获取响应头Content-Disposition的文件名

1. 为什么Content-Disposition无法获取&#xff1f; 要拿到 Content-Disposition 里的 filename&#xff0c;可以用正则或者简单的字符串解析。 浏览器默认不让前端访问非标准响应头&#xff0c;Content-Disposition 需要后端显式暴露。 在浏览器开发者工具 → Network → Re…

Leetcode 128. 最长连续序列 哈希

原题链接&#xff1a; Leetcode 128. 最长连续序列 解法1: map&#xff0c;不符合要求 class Solution { public:int longestConsecutive(vector<int>& nums) {if (nums.size()0) return 0;map<int,int> mp;for(auto x: nums){mp[x];}int pre;int l0,r0,res0;…

禾赛激光雷达AT128P/海康相机(2):基于欧几里德聚类的激光雷达障碍物检测

目录 一、参考连接 二、实验效果​编辑 三、安装相应的 ros 依赖包 四、代码驱动 4.1 代码下载 4.2 代码文件放置(请按照这个命名放置代码) 4.3 代码编译 4.4 报错 一、参考连接

Vue Router的常用API有哪些?

文章目录一、路由配置相关二、路由实例方法&#xff08;router 实例&#xff09;三、组件内路由 API&#xff08;useRouter / useRoute&#xff09;四、导航守卫&#xff08;路由拦截&#xff09;五、路由视图与导航组件六、其他常用 API七、history模式和hash模式有什么区别&a…

从现场到云端的“通用语”:Kepware 在工业互联中的角色、使用方法与本土厂商(以胡工科技为例)的差异与优势

从现场到云端的“通用语”&#xff1a;Kepware 在工业互联中的角色、使用方法与本土厂商&#xff08;以胡工科技为例&#xff09;的差异与优势 文章目录从现场到云端的“通用语”&#xff1a;Kepware 在工业互联中的角色、使用方法与本土厂商&#xff08;以胡工科技为例&#x…

深入理解Prompt构建与工程技巧:API高效实践指南

深入理解Prompt构建与工程技巧&#xff1a;API高效实践指南 引言 Prompt&#xff08;提示&#xff09;工程是推动大模型能力极限的关键手段。合理的Prompt不仅能显著提升模型输出的相关性与准确性&#xff0c;在实际落地的API接口开发中同样起到举足轻重的作用。本文将系统介…

C++之多态(从0到1的突破)

世间百态&#xff0c;每个人都扮演着不同的角色&#xff0c;都进行着不同的行为。C更是如此&#xff0c;C中也会出现有着不同行为的多种形态的出现&#xff0c;那就让我们一起进入C的多态世界吧&#xff01;&#xff01;&#xff01; 一. 多态的概念 多态&#xff0c;顾名思义&…

路由器NAT的类型测定

目前所使用的NAT基本都是NAPT&#xff0c;即多端口的NAT技术&#xff0c;因此本文主要是设计了两种测定路由器NAPT类型的实验。 实验环境 设备 主机A&#xff1a;Windows主机B&#xff1a;Windows路由器 软件 ncWiresharkSocketTools 在局域网内部完成所有测试&#xff0c;完全…

ROS 2系统Callback Group概念笔记

核心概念 Callback Group&#xff08;回调组&#xff09;是一个管理一个或多个回调函数执行规则的容器。它决定了这些回调函数是如何被节点&#xff08;Node&#xff09;的 executor 调度的&#xff0c;特别是当多个回调函数同时就绪时&#xff0c;它们之间是并行执行还是必须串…

Qt——主窗口 mainWindow

主窗口 mainWindow 前面学习的所有代码&#xff0c;都是基于QWidget控件&#xff0c;其更多的是作为别的窗口的部分 现在来学习QMainWindow&#xff0c;即主窗口&#xff0c;其包含以下属性 Window Title&#xff1a;标题栏Menu Bar&#xff1a;菜单栏Tool Bar Area&#xff1a…

无训练神经网络影响下的智能制造

摘要 未训练神经网络&#xff08;Untrained Neural Networks, UNNs&#xff09;作为近年来人工智能领域的新兴范式&#xff0c;正在逐步改变智能制造的发展路径。不同于传统深度学习依赖大规模标注数据与高性能计算资源的模式&#xff0c;UNNs 借助网络结构自身的归纳偏置与初…

微服务自动注册到ShenYu网关配置详解

一、配置逐行详解 shenyu:register:registerType: http # 注册中心类型:使用 HTTP 协议进行注册serverLists: ${shenyu-register-serverLists} # ShenYu Admin 的地址列表props:username: ${shenyu-register-props-username} # 注册认证用户名password: ${shenyu-regi…

时序数据库IoTDB的列式存储引擎

在大数据时代&#xff0c;工业物联网&#xff08;IIoT&#xff09;场景正以前所未有的速度生成着海量的时间序列数据。这些数据通常由成千上万的传感器&#xff08;如温度、压力、转速传感器&#xff09;持续不断采集产生&#xff0c;它们具备鲜明的特点&#xff1a;数据时间属…