目录:
ROI(region of interest),中文翻译过来就是感兴趣区域,在机器视觉、图像处理中,从被处理的图像以方框、圆、椭圆、不规则多边形等方式勾勒出需要处理的区域,这一部分区域被我们称之为感兴趣区域。
ROI选定的这个区域一般是我们所关注的重点,圈定该区域后我们可以进行进一步的处理,在一定程度上可以减少工作量。
ROI主要应用在视频监控领域,最常见的为ROI智能视频编码技术,具有ROI功能的摄像机可以让用户选择画面中感兴趣的区域,启用ROI功能后,重要的或者移动的区域将会进行高质量无损编码, 而对那些不移动,不被选择的区域降低其码率和图像质量,进行标准清晰度视频压缩,甚至是不传输这部分区域视频,达到节省网络带宽占用和视频存储空间。
图像处理------泛洪填充算法(Flood Fill Algorithm) 油漆桶功能
它可以填充由一个点开始进行迭代或者递归,来寻找或者填充和它相同或者相同值的点,或者找到边界上和它不同的点为止。
泛洪填充用途很多,图形对象的自动填充技术等等。在平面上画一个长方形,每次点油漆桶,只会改变该长方形内颜色,这就是泛洪填充。
6.1 ROI
总结:1. 提取ROI方法:numpy的array来提取(只能是方形的?)
比如在蓝色区域内我们感兴趣的区域就是虚线的矩形。
比如在lena图片里面,我们想扣下来lena的脸,我们需要设置好高和宽(自己量。。)自己在图上面量。
扣出ROI后我们可以进行我们喜欢的操作。
对lena 的脸提取ROI后修改再接回去:
1.通过 [] 选择要提取的ROI部分
2.对提取的ROI部分做处理。比如我们把它转化为灰度图
3.想把修改后的ROI接回去,若是灰度图一定要先转为RGB图,因为通道数不一样,接回去会报错!!!
4.gray 转换为 RGB
5.RGB接回原图
6.2 mask和提取不规则ROI
mask(遮罩),OpenCV中是如此定义Mask的:八位单通道的Mat对象,每个像素点值为零或者非零区域。当Mask对象添加到图像区上时,只有非零的区域是可见,Mask中所有像素值为零与图像重叠的区域就会不可见,也就是说Mask区域的形状与大小直接决定了你看到最终图像的大小与形状。一个具体的示例如下:
通过mask 来提取不规则的ROI,需要调用的API是bitwise_and。
比如 提取红色花朵这个不规则的ROI:
两种方法:(这里主要讨论常用的)
通过cv.inRange 并查表,剥离出颜色,然后bitwise_and(img,img,mask = mask_name)
mask_img = cv2.inRange(hsv, lower_blue, upper_blue)
bitwise_and(img,img,mask = mask_name)
6.3 cv.floodFill()
6.3.1 彩色图像填充
复制一张图(不想在原图上面动):?= image.copy()
开始准备mask:先准备一个模板
h,w = image.shape[:2]
mask = np.zeros([h+2, w+2], np.unit8)
开始渲染,用mask去渲染它:floodFill(image, mask, seedPoint, newVal[, loDiff[, upDiff[, flags]]])
floodFill(image, mask, seedPoint, newVal[, loDiff[, upDiff[, flags]]])
image参数表示输入/输出1或3通道,8位或浮点图像。
mask参数表示掩码,该掩码是单通道8位图像,比image的高度多2个像素,宽度多2个像素。填充时不能穿过输入掩码中的非零像素。
seedPoint参数表示泛洪算法(漫水填充算法)的起始点。
newVal参数表示在重绘区域像素的新值。
loDiff参数表示 当前观察像素值 与其 部件邻域像素值或待加入该组件的种子像素之间的亮度或颜色之负差的最大值。
upDiff参数表示当前观察像素值与其部件邻域像素值或待加入该组件的种子像素之间的亮度或颜色之正差的最大值。
FLOODFILL_FIXED_RANGE:表示此标志会考虑当前像素与种子像素之间的差,否则就考虑当前像素与相邻像素的差。
FLOODFILL_MASK_ONLY:表示函数不会去填充改变原始图像,而是去填充掩码图像mask,mask指定的位置为零时才填充,不为零不填充。(只在mask里面填充,所以mask 的取值至关重要,如果他认为被填充过了,就不会理你)
设置FLOODFILL_FIXED_RANGE – 改变图像,泛洪填充
设置FLOODFILL_MASK_ONLY – 不改变图像,只填充遮罩层本身,忽略新的颜色值参数。(他会对遮罩层本身进行一个填充,但是其实也是要填冲图像的,但是这里的遮罩层必须是0,,如果遮罩层为1了,他就根本不会填充图像)
mask = np.zeros([h+2,w+2],np.uint8)
# 这里必须是uint8才能去做mask,而且h和w都是必须+2。
# 个人想法:+2,是为了保证横竖两头,位移扫描的时候保证能把边界全部扫上
# 起始填充位,填充完后的值是什么(黄色),低值,高值,填充的flag:填充方法选择
# 所以从(30,30)这个点开始,min = 起始点像素值 - (100,100,100),,max = 起始点像素值 - (50,50,50),在[min, max]之间的都渲染。所以很明显黑色不在这个范围,没有渲染
cv.floodFill(copy_image, mask, (30,30),(0, 255,255), (100,100,100), (50,50,50), cv.FLOODFILL_FIXED_RANGE)
cv.imshow("fill_color_demo",copy_image)
6.3.2 二值填充
这里mask一定要注意注意!!!!是先初始化为1, 然后再赋值为0. 填充和其它问题刚好是一个相反的过程,使用其他的方法的时候,为1 的区域才会被填充,使用floodFill刚好相反,不为1的地发就会被填充。