数字图像处理(实践篇)十九 漫水填充

2023-12-08 11:28

本文主要是介绍数字图像处理(实践篇)十九 漫水填充,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一 漫水填充算法--FloodFill

二 涉及的函数

三 实践


一 漫水填充算法--FloodFill

FloodFill漫水填充算法就是选中与种子点相连接的区域,利用指定颜色进行区域颜色填充。可以通过设置连通方式或像素的范围控制填充的效果。通常是用来标记或者分离图像的一部分,以便做进一步分析和处理。

二 涉及的函数

cv2.floodFill()函数原型如下:

cv2.floodFill(image, mask, seedPoint, newVal, loDiff=None, upDiff=None, flags=None)

输入:

image:【输入/输出】1或者3通道、 8bit或者浮点图像。仅当参数flags的FLOODFILL_MASK_ONLY标志位被设置时image不会被修改,否则的话,image会被修改。

mask:【输入/输出】 操作掩码,必须为单通道、8bit,且比原图image宽、高多2个像素。使用前必须先初始化。只有对于掩码层上对应为0的位置才能泛洪,所以掩码层初始化为0矩阵。

seedPoint:漫水填充的种子点,起始像素点。根据该点的像素判断决定和其相近颜色的像素点,是否被泛洪处理。

newVal:被填充的像素点的新像素值(B,G,R)。

loDiff:(loDiff1,loDiff2,loDiff3),添加进种子点区域条件的下界差值。例如,seed(B0,G0,R0),泛洪区域下界为(B0-loDiff1,G0-loDiff2,R0-loDiff3)。

upDiff:(upDiff1,upDiff2,upDiff3),添加进种子点区域条件的上界差值。例如,seed(B0,G0,R0),泛洪区域上界为(B0+upDiff1,G0+upDiff2,R0+upDiff3)。

flag:为泛洪算法的处理模式。

当为CV_FLOODFILL_FIXED_RANGE时,待处理的像素点与种子点作比较,在范围之内,则填充此像素 。 改变图像,填充newvalue。      

当为CV_FLOODFILL_MASK_ONLY 时,函数不填充原始图像iamge,而是填充掩码图像。不改变原图像,也就是newvalue参数失去作用,而是改变对应区域的掩码。

返回:

image:【输入/输出】

mask:【输入/输出】 操作掩码。

三 实践

实践①:不同的seedPoint

  • 代码
import numpy as np
import cv2
import matplotlib.pyplot as plt
def dealImg(img):b, g, r = cv2.split(img)img_rgb = cv2.merge([r, g, b])return img_rgb
def dealImageResult(img_path):im = cv2.imread(img_path)h, w = im.shape[:2]im1 = im.copy()im2 = im.copy()im3 = im.copy()im4 = im.copy()im5 = im.copy()mask1 = np.zeros([h+2, w+2], np.uint8)mask2 = np.zeros([h+2, w+2], np.uint8)mask3 = np.zeros([h+2, w+2], np.uint8)mask4 = np.zeros([h+2, w+2], np.uint8)mask5 = np.zeros([h+2, w+2], np.uint8)cv2.floodFill(im1,  mask1, (20, 20), (255, 255, 0), (100, 100, 50), (50, 50, 50), cv2.FLOODFILL_FIXED_RANGE)cv2.floodFill(im2,  mask2, (90, 80), (255, 255, 0), (100, 100, 50), (50, 50, 50), cv2.FLOODFILL_FIXED_RANGE)cv2.floodFill(im3,  mask3, (100, 150), (255, 255, 0), (100, 100, 50), (50, 50, 50), cv2.FLOODFILL_FIXED_RANGE)cv2.floodFill(im4,  mask4, (180, 180), (255, 255, 0), (100, 100, 50), (50, 50, 50), cv2.FLOODFILL_FIXED_RANGE)cv2.floodFill(im5,  mask5, (200, 190), (255, 255, 0), (100, 100, 50), (50, 50, 50), cv2.FLOODFILL_FIXED_RANGE)fig = plt.figure(figsize=(10, 10))im = dealImg(im)im1 = dealImg(im1)im2 = dealImg(im2)im3 = dealImg(im3)im4 = dealImg(im4)im5 = dealImg(im5)titles = ["img", "seedPoint=(20, 20)", "seedPoint=(40, 40)", "seedPoint=(60, 70)", "seedPoint=(100, 150)", "seedPoint=(200, 190)"]images = [im, im1, im2, im3, im4, im5]for i in range(6):plt.subplot(2, 3, i + 1), plt.imshow(images[i], "gray")plt.title("{}".format(titles[i]), fontsize=20, ha='center')plt.xticks([]), plt.yticks([])# plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0.3, hspace=0)# plt.tight_layout()plt.show()fig.savefig('test_results.jpg', bbox_inches='tight')
if __name__ == '__main__':dealImageResult("4.jpeg")pass
  • 效果图

实践②:指定位置的填充

  • 代码
import numpy as np
import cv2
import matplotlib.pyplot as plt
def dealImg(img):b, g, r = cv2.split(img)img_rgb = cv2.merge([r, g, b])return img_rgb
def dealImageResult(img_path):im = cv2.imread(img_path)h, w = im.shape[:2]print(h, w)im1 = im.copy()im2 = im.copy()im3 = im.copy()mask1 = np.ones([h+2, w+2], np.uint8)mask1[0:100, 0:100] = 0mask2 = np.ones([h+2, w+2], np.uint8)mask2[0:200, 0:200] = 0mask3 = np.ones([h+2, w+2], np.uint8)mask3[0:w, 0:h] = 0cv2.floodFill(im1,  mask1, (20, 20), (255, 255, 0), (100, 100, 50), (50, 50, 50), cv2.FLOODFILL_FIXED_RANGE)cv2.floodFill(im2,  mask2, (20, 20), (255, 255, 0), (100, 100, 50), (50, 50, 50), cv2.FLOODFILL_FIXED_RANGE)cv2.floodFill(im3,  mask3, (20, 20), (255, 255, 0), (100, 100, 50), (50, 50, 50), cv2.FLOODFILL_FIXED_RANGE)fig = plt.figure(figsize=(10, 10))im = dealImg(im)im1 = dealImg(im1)im2 = dealImg(im2)im3 = dealImg(im3)titles = ["img", "mask1_result", "mask2_result", "mask3_result"]images = [im, im1, im2, im3]for i in range(4):plt.subplot(2, 2, i + 1), plt.imshow(images[i], "gray")plt.title("{}".format(titles[i]), fontsize=20, ha='center')plt.xticks([]), plt.yticks([])# plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0.3, hspace=0)# plt.tight_layout()plt.show()fig.savefig('test_results.jpg', bbox_inches='tight')
if __name__ == '__main__':dealImageResult("4.jpeg")pass
  • 效果图

前文回顾

 入门篇目录

 数字图像处理(入门篇)一 图像的数字化与表示

 数字图像处理(入门篇)二 颜色空间

 数字图像处理(入门篇)三 灰度化

 数字图像处理(入门篇)四 像素关系

 数字图像处理(入门篇)五 图像数据预处理之颜色空间转换

 数字图像处理(入门篇)六 图像数据预处理之坐标变化

 数字图像处理(入门篇)七 图像数据预处理之灰度变化

 数字图像处理(入门篇)八 图像数据预处理之直方图

 数字图像处理(入门篇)九 图像数据预处理之滤波

 数字图像处理(入门篇)十 边缘检测

 数字图像处理(入门篇)十一 形态学处理

 数字图像处理(入门篇)十二 自适应阈值分割

 数字图像处理(入门篇)十三 仿射变换

 数字图像处理(入门篇)十四 透视变换

实践篇目录

数字图像处理(实践篇)一 将图像中的指定目标用bBox框起来吧!

数字图像处理(实践篇)二 画出图像中目标的轮廓

数字图像处理(实践篇)三 将两张图像按照指定比例融合

数字图像处理(实践篇)四 图像拼接-基于SIFT特征点和RANSAC方法

数字图像处理(实践篇)五 使用Grabcut算法进行物体分割

数字图像处理(实践篇)六 利用hough变换进行直线检测

数字图像处理(实践篇)七 利用霍夫变换进行圆环检测

数字图像处理(实践篇)八 Harris角点检测

数字图像处理(实践篇)九 基于边缘的模板匹配

数字图像处理(实践篇)十 图像质量检测

数字图像处理(实践篇)十一 图像中的条形码解析

数字图像处理(实践篇)十二 基于小波变换的图像降噪

数字图像处理(实践篇)十三 数据增强之给图像添加噪声!

数字图像处理(实践篇)十四 图像金字塔

数字图像处理(实践篇)十五 基于傅里叶变换的高通滤波和低通滤波

数字图像处理(实践篇)十六 基于分水岭算法的图像分割

数字图像处理(实践篇)十七 Shi-Tomasi 角点检测

数字图像处理(实践篇)十八 人脸检测

这篇关于数字图像处理(实践篇)十九 漫水填充的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/469674

相关文章

Docker多阶段镜像构建与缓存利用性能优化实践指南

《Docker多阶段镜像构建与缓存利用性能优化实践指南》这篇文章将从原理层面深入解析Docker多阶段构建与缓存机制,结合实际项目示例,说明如何有效利用构建缓存,组织镜像层次,最大化提升构建速度并减少... 目录一、技术背景与应用场景二、核心原理深入分析三、关键 dockerfile 解读3.1 Docke

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

PHP应用中处理限流和API节流的最佳实践

《PHP应用中处理限流和API节流的最佳实践》限流和API节流对于确保Web应用程序的可靠性、安全性和可扩展性至关重要,本文将详细介绍PHP应用中处理限流和API节流的最佳实践,下面就来和小编一起学习... 目录限流的重要性在 php 中实施限流的最佳实践使用集中式存储进行状态管理(如 Redis)采用滑动

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

MySQL分库分表的实践示例

《MySQL分库分表的实践示例》MySQL分库分表适用于数据量大或并发压力高的场景,核心技术包括水平/垂直分片和分库,需应对分布式事务、跨库查询等挑战,通过中间件和解决方案实现,最佳实践为合理策略、备... 目录一、分库分表的触发条件1.1 数据量阈值1.2 并发压力二、分库分表的核心技术模块2.1 水平分

SpringBoot通过main方法启动web项目实践

《SpringBoot通过main方法启动web项目实践》SpringBoot通过SpringApplication.run()启动Web项目,自动推断应用类型,加载初始化器与监听器,配置Spring... 目录1. 启动入口:SpringApplication.run()2. SpringApplicat