Python+OpenCV图像处理(六)—— ROI与泛洪填充

一、ROI

ROI(region of interest),感兴趣区域。机器视觉、图像处理中,从被处理的图像以方框、圆、椭圆、不规则多边形等方式勾勒出需要处理的区域,称为感兴趣区域,ROI。

代码如下:

#进行图片截取、合并、填充
import cv2 as cv
src=cv.imread('E:\imageload\lena.jpg')
cv.namedWindow('first_image', cv.WINDOW_AUTOSIZE)
cv.imshow('first_image', src)
face = src[200:300, 200:400]    #选择200:300行、200:400列区域作为截取对象
gray = cv.cvtColor(face, cv.COLOR_RGB2GRAY)  #生成的的灰度图是单通道图像
backface = cv.cvtColor(gray, cv.COLOR_GRAY2BGR)  #将单通道图像转换为三通道RGB灰度图,因为只有三通道的backface才可以赋给三通道的src
src[200:300, 200:400] = backface
cv.imshow("face", src)
cv.waitKey(0)
cv.destroyAllWindows()

运行结果:

注意:COLOR_RGB2GRAY是把三通道RGB对象转换为单通道灰度对象

二、泛洪填充(彩色图像填充)

代码如下:

#泛洪填充(彩色图像填充)
import cv2 as cv
import numpy as np
def fill_color_demo(image):
    copyImg = image.copy()
    h, w = image.shape[:2]
    mask = np.zeros([h+2, w+2],np.uint8)   #mask必须行和列都加2,且必须为uint8单通道阵列
    #为什么要加2可以这么理解:当从0行0列开始泛洪填充扫描时,mask多出来的2可以保证扫描的边界上的像素都会被处理
    cv.floodFill(copyImg, mask, (220, 250), (0, 255, 255), (100, 100, 100), (50, 50 ,50), cv.FLOODFILL_FIXED_RANGE)
    cv.imshow("fill_color_demo", copyImg)

src = cv.imread('E:/imageload/baboon.jpg')
cv.namedWindow('input_image', cv.WINDOW_AUTOSIZE)
cv.imshow('input_image', src)
fill_color_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

运行结果:

注意:

1.opencv里的mask都是为uin8类型的单通道阵列

2.泛洪填充算法也叫漫水填充算法。opencv的floodFill函数原型: floodFill(image, mask, seedPoint, newVal[, loDiff[, upDiff[, flags]]]) -> retval, image, mask, rect

  image参数表示输入/输出1或3通道,8位或浮点图像。

  mask参数表示掩码,该掩码是单通道8位图像,比image的高度多2个像素,宽度多2个像素。填充时不能穿过输入掩码中的非零像素。

  seedPoint参数表示泛洪算法(漫水填充算法)的起始点。

  newVal参数表示在重绘区域像素的新值。

  loDiff参数表示当前观察像素值与其部件邻域像素值或待加入该组件的种子像素之间的亮度或颜色之负差的最大值。

  upDiff参数表示当前观察像素值与其部件邻域像素值或待加入该组件的种子像素之间的亮度或颜色之正差的最大值。

  flags参数:操作标志符,包含三部分:(参考opencv学习之路(31)、GrabCut & FloodFill图像分割 - 进击的小猴子 - 博客园)

    低八位(0~7位):用于控制算法的连通性,可取4(默认)或8。

    中间八位(8~15位):用于指定掩码图像的值,但是如果中间八位为0则掩码用1来填充。

    高八位(16~32位):可以为0或者如下两种标志符的组合:

    FLOODFILL_FIXED_RANGE:表示此标志会考虑当前像素与种子像素之间的差,否则就考虑当前像素与相邻像素的差。FLOODFILL_MASK_ONLY:表示函数不会去填充改变原始图像,而是去填充掩码图像mask,mask指定的位置为零时才填充,不为零不填充。  

3.个人理解:参数3起始点的像素值减去参数5的像素值表示的是从起始点开始搜索周边范围的像素最低值,参数3起始点的像素值加上参数5的像素值表示的是从起始点开始搜索周边范围的像素最大值。有了这个范围,然后该函数就可以在这个连续像素范围内填充指定的颜色newVal参数值。

4.设置FLOODFILL_FIXED_RANGE – 改变图像,泛洪填充     

   设置FLOODFILL_MASK_ONLY – 不改变图像,只填充遮罩层本身,忽略新的颜色值参数

三、泛洪填充(二值图像填充)

代码如下:

#泛洪填充(二值图像填充)
import cv2 as cv
import numpy as np
def fill_binary():
    image = np.zeros([400, 400, 3], np.uint8)
    image[100:300, 100:300] = 255
    cv.imshow("fill_binary", image)
    mask = np.ones([402, 402], np.uint8)   #mask要保证比原图像高和宽都多2
    mask[101:301, 101:301] = 0
    cv.floodFill(image, mask, (200,200), (255 , 0, 0), cv.FLOODFILL_MASK_ONLY) #mask不为0的区域不会被填充,mask为0的区域才会被填充
    cv.imshow("filled_binary", image)
fill_binary()
cv.waitKey(0)
cv.destroyAllWindows()

运行结果:

注意:

1.个人认为,不管是FLOODFILL_FIXED_RANGE还是FLOODFILL_MASK_ONLY操作,泛洪填充都不会填充掩膜mask的非零像素区域

2. mask[101:301, 101:301] = 0 这条语句为什么是101:301而不是100:300呢?我觉得应该是掩膜mask是比原图像左右上下都多了1,所以掩膜mask左右一共比原图像多2,上下也比原图像多2。那么原图像的100就自然对应到掩膜的101,同样原图像的300就自然对应到掩膜的301。

3.当FLOODFILL_MASK_ONLY设置了的时候,原图不会改变,只会用中间八位的值填冲mask。 floodFill的flags参数的中间八位的值就是用于指定填充掩码图像的值的,但是如果flags中间八位的值为0,则掩码会用1来填充。

Python中使用OpenCV进行不规则多边形ROI区域提取需要以下步骤: 1. 导入所需的库 我们需要导入OpenCV库,并将其命名为cv2。 2. 读取图像 使用cv2.imread()函数读取图像。这里假设图像文件名为"image.jpg"。 3. 创建ROI多边形 定义一个包含不规则多边形顶点的列表作为ROI区域。 4. 创建掩膜 使用cv2.fillPoly()函数创建一个与图像大小相同的空白图像,作为掩膜。然后使用cv2.fillPoly()函数在掩膜上填充多边形。 5. 应用掩膜 使用cv2.bitwise_and()函数将原始图像与掩膜进行按位与操作,即只保留ROI区域。 6. 显示结果 使用cv2.imshow()函数显示提取的ROI区域。 7. 释放窗口 使用cv2.waitKey(0)等待按下任意键后,使用cv2.destroyAllWindows()函数关闭窗口。 以下是一个简单的示例代码: ```python import cv2 import numpy as np # 读取图像 image = cv2.imread('image.jpg') # 创建ROI多边形 roi_vertices = np.array([[(100, 100), (300, 100), (200, 300), (50, 200)]], dtype=np.int32) # 创建掩膜 mask = np.zeros_like(image) cv2.fillPoly(mask, roi_vertices, 255) # 应用掩膜 roi_image = cv2.bitwise_and(image, mask) # 显示结果 cv2.imshow('ROI Image', roi_image) # 释放窗口 cv2.waitKey(0) cv2.destroyAllWindows() ``` 将以上代码保存为Python脚本,运行后会显示提取的ROI区域图像。其中,roi_vertices是一个包含多边形顶点的列表,可以根据需要调整顶点的坐标和个数来定义不规则多边形的形状。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值