一、学习目标

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

如有错误欢迎指出~

目录

[python opencv 计算机视觉零基础到实战] 一、opencv的helloworld

[【python opencv 计算机视觉零基础到实战】二、 opencv文件格式与摄像头读取] 一、opencv的helloworld

[[python opencv 计算机视觉零基础到实战] 三、numpy与图像编辑] 一、opencv的helloworld

[[python opencv 计算机视觉零基础到实战] 四、了解色彩空间及其详解] 一、opencv的helloworld

[[python opencv 计算机视觉零基础到实战] 五、对象追踪] 一、opencv的helloworld
[python opencv 计算机视觉零基础到实战] 六、图像运算
[python opencv 计算机视觉零基础到实战] 七、逻辑运算与应用

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

2.1 了解ROI是什么

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

先有一张图如下:

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

import cv2
img = cv2.imread(r"C:\Users\Administrator\Desktop\1.jpg")
print(img.shape)

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

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

import cv2img = cv2.imread(r'C:\Users\Administrator\Desktop\1.jpg')#读取
cv2.namedWindow("Image",cv2.WINDOW_NORMAL)#创建一个窗口
cv2.imshow("Image", img)#显示图像roi=img[200:400,200:400]
cv2.imshow("roi", roi)#显示图像cv2.waitKey (0)#等待关闭
cv2.destroyAllWindows()#destroy

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

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

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

roi=img[200:400,280:450]

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

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

gray_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
cv2.imshow("gray_roi", gray_roi)#显示图像

结果如下:

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

import cv2img = cv2.imread(r'C:\Users\Administrator\Desktop\1.jpg')#读取
cv2.namedWindow("Image",cv2.WINDOW_NORMAL)#创建一个窗口
cv2.imshow("Image", img)#显示图像roi=img[200:400,280:450]
cv2.imshow("roi", roi)#显示图像gray_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
cv2.imshow("gray_roi", gray_roi)#显示图像gray_roi_rgb = cv2.cvtColor(gray_roi, cv2.COLOR_GRAY2BGR)#灰度图像转RGB
img[200:400,280:450]=gray_roi_rgb
cv2.imshow("Image2", img)#显示图像cv2.waitKey (0)#等待关闭
cv2.destroyAllWindows()#destroy

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

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

最终运行结果如下:

2.2 泛洪填充及floodFill使用方法

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

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

import cv2
import numpy as npimg = cv2.imread(r"C:\Users\Administrator\Desktop\1.jpg")
cv2.imshow("img", img)

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

copyimg = image.copy()

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

h, w = copyimg.shape[:2]
mask = np.zeros([h + 2, w + 2], np.uint8)

以上代码通过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 npimg = 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,可以明显看到效果:

cv2.floodFill(copyimg, mask, (0,0), (0, 255, 255), (50,50, 50), (50, 50 ,50), cv2.FLOODFILL_FIXED_RANGE)

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

其中颜色值可以可以进行修改,修改方法不再赘述。
该系列文章首发于ebaina

三、总结

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

[python opencv 计算机视觉零基础到实战] 八、ROI泛洪填充相关推荐

  1. [python opencv 计算机视觉零基础到实战] 十一找到图片中指定内容

    一.学习目标 了解图片内容定位方法matchTemplate使用 了解minMaxLoc方法使用 上一篇<[python opencv 计算机视觉零基础到实战] 十.图片效果毛玻璃> 如有 ...

  2. [python opencv 计算机视觉零基础到实战] 十、图片效果毛玻璃

    一.学习目标 了解高斯模糊的使用方法 了解毛玻璃的图片效果添加 了解如何自己做一个噪声图片 上一篇:[python opencv 计算机视觉零基础到实战] 九.模糊 如有错误欢迎指出~ 二.了解模糊与 ...

  3. [python opencv 计算机视觉零基础到实战] 七、逻辑运算与应用

    一.学习目标 了解opencv中图像的逻辑运算 了解opencv中逻辑运算的应用 目录 [python opencv 计算机视觉零基础到实战] 一.opencv的helloworld [[python ...

  4. [python opencv 计算机视觉零基础到实战] 六、图像运算

    一.学习目标 了解opencv中图像运算的方法 了解opencv中图像运算的运用 如有错误欢迎指出~ 二.了解OpenCV中图像运算的运用 目录 [python opencv 计算机视觉零基础到实战] ...

  5. [python opencv 计算机视觉零基础到实战] 四、了解色彩空间及其详解

    一.学习目标 了解什么是色彩空间 了解opencv中色彩空间的转换 目录 [python opencv 计算机视觉零基础到实战] 一.opencv的helloworld [[python opencv ...

  6. [python opencv 计算机视觉零基础到实战] 三、numpy与图像编辑

    一.学习目标 了解图片的通道与数组结构 了解使用numpy创建一个图片 了解使用numpy对图片的一般操作方法 目录 [python opencv 计算机视觉零基础到实战] 一.opencv的hell ...

  7. 【python opencv 计算机视觉零基础到实战】二、 opencv文件格式与摄像头读取

    一.学习目标 了解图片的结构属性 了解如何捕获视频 了解waitkey的使用方法 目录 [python opencv 计算机视觉零基础到实战] 一.opencv的helloworld [[python ...

  8. [python opencv 计算机视觉零基础到实战] 一 opencv的helloworld

    前置条件 说明:本系列opencv实战教程将从基础到实战,若只是简单学习完python也可以通过该教程完成一般的机器学习编程:文中将会对很多python的基础内容进行讲解,但由于文章定位的原因将不会赘 ...

  9. [python opencv 计算机视觉零基础到实战] 十八、用鼠标进行画画

    一.学习目标 了解如何在图片中加入文字 了解如何使用鼠标进行图像绘制 二.了解如何通过鼠标进行图像绘制 2.1 了解putText方法的使用 putText方法接收图像,文字内容, 坐标 ,字体,大小 ...

最新文章

  1. C# Image 、 byte[] 、Bitmap之间的转化
  2. BZOJ2299 [HAOI2011]向量 【裴蜀定理】
  3. R语言tseries包
  4. 专题导读:大数据支撑的智能应用
  5. windows下安装Redis测试
  6. 服务站: WCF 消息传递基础 -- MSDN Magazine, April 2007
  7. java过滤集合,java – 如何通过交集过滤集合集合?
  8. Nginx之(一)Nginx是什么
  9. Binding.scala使用教程8--binding.scala结合semanticUI
  10. 【数据结构】(森林)求以孩子兄弟表示法存储的森林叶子结点数
  11. 刚刚,百度宣布造车!
  12. 惠普m227fdw引擎通信错误_惠普打印机HPM227提示耗材余量错误怎么办?
  13. C++根据三个点坐标计算夹角
  14. android 动画闪屏问题,Android中闪屏实现方法小结(普通闪屏、倒计时闪屏、倒计时+动画...
  15. vue手机端打开高德地图app
  16. [线段树分治][DP] LOJ #534. 「LibreOJ Round #6」花团
  17. python3GUI--翻译器-v2.0(附源码)
  18. day184-2018-12-21-英语流利阅读-待学习
  19. com.ibm.websphere.ce.cm.ConnectionWaitTimeoutException
  20. 百度智能云人脸识别java_demo完整实例

热门文章

  1. 服务端和客户端证书各种组合下对访问者(浏览器/中间人)的影响
  2. Autofac框架初识与应用
  3. MiniProfiler,一个.NET简单但有效的微型分析器
  4. gRPC-微服务间通信实践
  5. RabbitMq如何确保消息不丢失
  6. 关于Dapper实现读写分离的个人思考
  7. ABP快速开发一个.NET Core电商平台
  8. abp vnext2.0核心组件之DDD组件之实体结构源码解析
  9. [ASP.NET Core 3框架揭秘] 跨平台开发体验: Docker
  10. WTM 构建DotNetCore开源生态,坐而论道不如起而行之