百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

「python opencv视觉零到实战」 八、图片选区操作

bigegpt 2024-09-25 14:34 3 浏览


一、学习目标

  1. 了解什么是ROI
  2. 了解floodFill的使用方法

如有错误欢迎指出~

目录

「python opencv 计算机视觉零基础实战」 第一节

「python opencv视觉入门到实战」二、格式与摄像头

「python opencv 视觉入门到实战」 三、图像编辑

「python opencv视觉入门到实战」 第四节色彩空间

「python opencv视觉入门到实战」 五、对象追踪

「python opencv视觉零基础到实战」 六、图像运算

「python opencv视觉零基础实战」 七逻辑运算应用

二、了解OpenCV中图像ROI的颜色填充

2.1 了解ROI是什么

ROI指的是region of Interest,翻译过来就是你所感兴趣的区域。若在一张图片中,你感兴趣的是某一个区域,那么这个区域就可以称为ROI。我们通过一些方法选取了该区域后,可以进行操作;例如颜色填充、图像变换等编辑。

现有一张图如下:


我们对这张图的激光雕刻机部分感兴趣,那么就可以选取该部分。如何进行选取呢?我们可以通过代码得知该图片的大小:

import cv2

img = cv2.imread(r'C:\Users\mx\Desktop\111.png')
dst=cv2.medianBlur(img,5)

得到该图片的高宽分别为447与755。


我们可以通过粗略的丈量得知激光雕刻机应在整个图片的正中央,那么宽应该为一半,大致在200到400之间;由于图片中激光雕刻机位于图片偏下部分,所以可以粗略得知高度在200至400之间。这时我们可以直接读取图片后获取指定的行列得到该区域图片。

cv2.imshow("img", dst)
cv2.waitKey (0)
cv2.destroyAllWindows()

以上代码读取图片后,通过选取图片区域进行ROI选择。img[200:400,200:400]代码中,第一个200:400指的是200指400行,第二个200:400指的是200至400列。通过两个选取的行与列的交叉区域则是所选择的ROI区域。图示如下,红色框框表示列,紫色框框表示行,其中重叠区域则是ROI选择区域。

以上代码在运行结果如下:


从结果中,我们可以知道,该值的列选择还应该往右边移动一部分,由于我们是200至400这个区域,那么我们现在应该移动的访问从图片上看,应该是接近300指500。修改代码。

dst=cv2.blur(img,(2,24))

运行后最后得到如下结果:


我们得到ROI内容后,可以对该部分的内容进行编辑,例如转为灰度图像:

cv2.GaussianBlur( SRC,ksize,sigmaX )

结果如下:

也可以将转换后的图片与原图进行结合,只需要将转换后的图片值对原图该区域的值进行替换即可,完整代码如下:

dst=cv2.GaussianBlur(img,(0,0),20)	

在以上代码中需要注意的是,灰度图像必须转为RGB图形才能对原图进行赋值。以上代码中灰度转RGB图像的代码为:

gray_roi_rgb = cv2.cvtColor(gray_roi, cv2.COLOR_GRAY2BGR)

最终运行结果如下:

2.2 泛洪填充及floodFill使用方法

泛洪填充指指定起始点,通过该像素点所链接的周围像素点在所指定的颜色值范围内进行颜色填充。该操作需要一个遮罩或者说掩膜进行运算处理。

首先我们依旧开始读取一张图像:

import cv2

img = cv2.imread(r'C:\Users\mx\Desktop\111.png')
h,w,c=img.shape

接着通过copy方法可以快速复制一张图片:

for row in range(h):
    for col in range(w):
        b=img[row,col,0]
        g=img[row,col,1]
        r=img[row,col,2]

由于我们需要建立一个遮罩,这个遮罩跟原图片大小一致,所以代码可以写成如下:

srand=np.random.normal(0,30,3)
img[row,col,0]=b+srand[0]
img[row,col,1]=g+srand[1]
img[row,col,2]=r+srand[2]

以上代码通过shape获取了原图片的高宽,接着通过zeros创建一个与原图大小一致的纯黑图片。那为什么要加2呢?因为接下来我们需要对图片进行颜色填充,官方的规定要+2,具体什么原因我本人没有进行深究,按照官方要求来就可以了。

那问题来了,遮罩是什么?还记得我们在逻辑运算应用那一个小节中,通过色彩提取后,可以得到目标对象的颜色范围,这个颜色范围是一张黑白图片,白色为选取的区域,黑色为不选取的区域,这时我们通过将提取出来的图片作为遮罩对图片进行bitwise_and运算,这时就可以还原出原本色彩,抠选出原图中的图像内容。其实遮罩的作用就是如此,我们通过zeros创建一张纯黑图片后,使用floodFill函数对指定目标进行填充;在填充之前,将进行一定的计算。由于floodFill函数将会选取出目标点,该目标点将作用在这张纯黑色的遮罩图片中,该纯黑图片将会对计算后选取的点进行指的变换,该区域就会变成白色,最终得到颜色填充的区域,进行填充。

我们首先看一下floodFill函数,floodFill函数接收7个参数,函数原型如下:

floodFill(image, mask, seedPoint, newVal, loDiff=None, upDiff=None, flags=None)
  • image为传入的图像参数
  • mask为遮罩
  • seedPoint为选中的颜色填充的起始点
  • newVal填充的颜色像素值
  • loDiff选中起始点的颜色像素值的最低范围,例如是红色,那么红色减去该值后得到最低的取值范围
  • upDiff选中起始点的颜色像素值的最高范围,例如是红色,那么红色加该值后得到最高的取值范围
  • flags为CV_FLOODFILL_FIXED_RANGE或者CV_FLOODFILL_MASK_ONLY
    ,两者填充方式不一样,当前示例将讲解CV_FLOODFILL_FIXED_RANGE。若选择CV_FLOODFILL_FIXED_RANGE,则会比较像素点与其实像素点,若在颜色值的范围内,则进行填充。
    此时我们调用floodFill方法,传入图片,遮罩,起始点,填充的颜色值,最低值,最高值与填充模式。
cv2.floodFill(copyimg, mask, (220,420), (0, 255, 255), (5, 5, 5), (5, 5 ,5), cv2.FLOODFILL_FIXED_RANGE)

copyimg为图片;mask为遮罩;220,420为起始点;0, 255, 255为填充的颜色,为黄色;5, 5, 5为选中的起始点减去该颜色值,判断周围的颜色是否低于该值;5, 5 ,5为选中的起始点加上该颜色值,判断周围的颜色是否高于该值。最终的完整代码如下:
img = cv2.imread(r"C:\Users\Administrator\Desktop\1.jpg")
cv2.imshow(“img”, img)

在复制图像上进行操作

import cv2
import numpy as np

img = cv2.imread(r"C:\Users\Administrator\Desktop\1.jpg")
cv2.imshow("img", img)
copyimg = img.copy()
h, w = copyimg.shape[:2]
mask = np.zeros([h + 2, w + 2], np.uint8)
cv2.floodFill(copyimg, mask, (220,420), (0, 255, 255), (5, 5, 5), (5, 5 ,5), cv2.FLOODFILL_FIXED_RANGE)
cv2.imshow("fill_color", copyimg)

cv2.waitKey (0)#等待关闭
cv2.destroyAllWindows()#destroy

运行结果如下:


我们现在可以证明220,420是否是起始点,我们可以换一个值,例如0,0。若在左上角进行颜色填充那么则判断正确:


我们也可以改变填充值的选择范围,将2个5,5,5改为50,50,50,可以明显看到效果:

dst=cv2.GaussianBlur(img,(5,5),0)

这时候的相关所链接的颜色范围扩大,那么所能填充的范围也肯定是扩大,运行结果如下:


其中颜色值可以可以进行修改,修改方法不再赘述。

该系列文章首发于ebaina,了解更多可查看扩展链接。

三、总结

  1. 了解了ROI是感兴趣的选择范围
  2. 了解了ROI可以通过图片内容进行选择,并且可以与原图进行结合
  3. 了解了泛洪填充的方法
  4. 初步了解了mask遮罩以及floodFill函数的使用方法

相关推荐

C#.NET Autofac 详解(c# autoit)

简介Autofac是一个成熟的、功能丰富的.NET依赖注入(DI)容器。相比于内置容器,它额外提供:模块化注册、装饰器(Decorator)、拦截器(Interceptor)、强o的属性/方法注...

webapi 全流程(webapi怎么部署)

C#中的WebAPIMinimalApi没有控制器,普通api有控制器,MinimalApi是直达型,精简了很多中间代码,广泛适用于微服务架构MinimalApi一切都在组控制台应用程序类【Progr...

.NET外挂系列:3. 了解 harmony 中灵活的纯手工注入方式

一:背景1.讲故事上一篇我们讲到了注解特性,harmony在内部提供了20个HarmonyPatch重载方法尽可能的让大家满足业务开发,那时候我也说了,特性虽然简单粗暴,但只能解决95%...

C# 使用SemanticKernel调用本地大模型deepseek

一、先使用ollama部署好deepseek大模型。具体部署请看前面的头条使用ollama进行本地化部署deepseek大模型二、创建一个空的控制台dotnetnewconsole//添加依赖...

C#.NET 中间件详解(.net core中间件use和run)

简介中间件(Middleware)是ASP.NETCore的核心组件,用于处理HTTP请求和响应的管道机制。它是基于管道模型的轻量级、模块化设计,允许开发者在请求处理过程中插入自定义逻辑。...

IoC 自动注入:让依赖注册不再重复劳动

在ASP.NETCore中,IoC(控制反转)功能通过依赖注入(DI)实现。ASP.NETCore有一个内置的依赖注入容器,可以自动完成依赖注入。我们可以结合反射、特性或程序集扫描来实现自动...

C#.NET 依赖注入详解(c#依赖注入的三种方式)

简介在C#.NET中,依赖注入(DependencyInjection,简称DI)是一种设计模式,用于实现控制反转(InversionofControl,IoC),以降低代码耦合、提高可...

C#从零开始实现一个特性的自动注入功能

在现代软件开发中,依赖注入(DependencyInjection,DI)是实现松耦合、模块化和可测试代码的一个重要实践。C#提供了优秀的DI容器,如ASP.NETCore中自带的Micr...

C#.NET 仓储模式详解(c#仓库货物管理系统)

简介仓储模式(RepositoryPattern)是一种数据访问抽象模式,它在领域模型和数据访问层之间创建了一个隔离层,使得领域模型无需直接与数据访问逻辑交互。仓储模式的核心思想是将数据访问逻辑封装...

C#.NET 泛型详解(c# 泛型 滥用)

简介泛型(Generics)是指在类型或方法定义时使用类型参数,以实现类型安全、可重用和高性能的数据结构与算法为什么需要泛型类型安全防止“装箱/拆箱”带来的性能损耗,并在编译时检测类型错误。可重用同一...

数据分析-相关性分析(相关性 分析)

相关性分析是一种统计方法,用于衡量两个或多个变量之间的关系强度和方向。它通过计算相关系数来量化变量间的线性关系,从而帮助理解变量之间的相互影响。相关性分析常用于数据探索和假设检验,是数据分析和统计建模...

geom_smooth()函数-R语言ggplot2快速入门18

在每节,先运行以下这几行程序。library(ggplot2)library(ggpubr)library(ggtext)#用于个性化图表library(dplyr)#用于数据处理p...

规范申报易错要素解析(规范申报易错要素解析)

为什么要规范申报?规范申报是以满足海关监管、征税、统计等工作为目的,纳税义务人及其代理人依法向海关如实申报的行为,也是海关审接单环节依法监管的重要工作。企业申报的内容须符合《中华人民共和国海关进出口货...

「Eurora」海关编码归类 全球海关编码查询 关务服务

  海关编码是什么?  海关编码即HS编码,为编码协调制度的简称。  其全称为《商品名称及编码协调制度的国际公约》(InternationalConventionforHarmonizedCo...

9月1日起,河南省税务部门对豆制品加工业试行新政7类豆制品均适用投入产出法

全媒体记者杨晓川报道9月2日,记者从税务部门获悉,为减轻纳税人税收负担,完善农产品增值税进项税额抵扣机制,根据相关规定,结合我省实际情况,经广泛调查研究和征求意见,从9月1日起,我省税务部门对豆制品...