水漫填充算法实现
help(cv2.floodFill)
floodFill(image, mask, seedPoint, newVal[, loDiff[, upDiff[, flags]]]) -> retval, image, mask, rect
参数解释:
image:
mask:掩码图像,大小比原图多两个像素点。设输入图像大小为width * height, 则掩码的大小必须为 (width+2) * (height+2) , mask可为输出,也可作为输入 ,由flags决定。
seedPoint :其实填充标记点
newVal:填充值
loDiff:为像素值的下限差值
flags参数 : 0~7位为0x04或者0x08 即 4连通或者8 连通
8~15位为填充mask的值大小 , 若为0 , 则默认用1填充
16~23位为 : CV_FLOODFILL_FIXED_RANGE =(1 << 16), CV_FLOODFILL_MASK_ONLY =(1 << 17)
flags参数通过位与运算处理
当为CV_FLOODFILL_FIXED_RANGE 时,待处理的像素点与种子点作比较,如果满足(s – lodiff , s + updiff)之间(s为种子点像素值),则填充此像素 . 若无此位设置,则将待处理点与已填充的相邻点作此比较
CV_FLOODFILL_MASK_ONLY 此位设置填充的对像, 若设置此位,则mask不能为空,此时,函数不填充原始图像img,而是填充掩码图像. 若无此位设置,则在填充原始图像的时候,也用flags的8~15位标记对应位置的mask.
# -*- coding: utf-8 -*-
"""
Created on Wed Jul 26 13:56:41 2017
@author: cross
"""
import numpy as np
import cv2
import random
if __name__ == '__main__':
img = cv2.imread("G:\python_cv2\orange.jpg",4)
h, w = img.shape[:2]
mask = np.zeros((h+2, w+2), np.uint8)
seed_pt = None
fixed_range = True
connectivity = 4
def update(dummy=None):
if seed_pt is None:
cv2.imshow('floodfill', img)
return
flooded = img.copy()
mask[:] = 1
lo = cv2.getTrackbarPos('lo', 'floodfill')
hi = cv2.getTrackbarPos('hi', 'floodfill')
flags = connectivity
if fixed_range:
flags |= cv2.FLOODFILL_FIXED_RANGE
cv2.floodFill(flooded, mask, seed_pt, (random.randint(0,255), random.randint(0,255), random.randint(0,255)), (lo,)*3, (hi,)*3, flags)
cv2.circle(flooded, seed_pt, 2, (0, 0, 255), -1)#选定基准点用红色圆点标出
cv2.imshow('floodfill', flooded)
def onmouse(event, x, y, flags, param):#鼠标响应函数
global seed_pt
if flags & cv2.EVENT_FLAG_LBUTTON:#鼠标左键响应,选择漫水填充基准点
seed_pt = x, y
update()
update()
cv2.setMouseCallback('floodfill', onmouse)
cv2.createTrackbar('lo', 'floodfill', 20, 255, update)
cv2.createTrackbar('hi', 'floodfill', 20, 255, update)
while True:
ch = 0xFF & cv2.waitKey()
if ch == 27:
break
if ch == ord('f'):
fixed_range = not fixed_range #选定时flags的高位比特位0,也就是邻域的选定为当前像素与相邻像素的的差,这样的效果就是联通区域会很大
print 'using %s range' % ('floating', 'fixed')[fixed_range]
update()
if ch == ord('c'):
connectivity = 12-connectivity #选择4方向或则8方向种子扩散
print 'connectivity =', connectivity
update()
cv2.destroyAllWindows()