天天看点

opencv-python填充算法(水漫填充)

水漫填充算法实现

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",)
    h, w = img.shape[:]
    mask = np.zeros((h+, w+), np.uint8)
    seed_pt = None
    fixed_range = True
    connectivity = 

    def update(dummy=None):
        if seed_pt is None:
            cv2.imshow('floodfill', img)
            return
        flooded = img.copy()
        mask[:] = 
        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(,), random.randint(,), random.randint(,)), (lo,)*, (hi,)*, flags)

        cv2.circle(flooded, seed_pt, , (, , ), -)#选定基准点用红色圆点标出
        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', , , update)
    cv2.createTrackbar('hi', 'floodfill', , , update)

    while True:
        ch =  & cv2.waitKey()
        if ch == :
            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 = -connectivity #选择4方向或则8方向种子扩散
            print 'connectivity =', connectivity
            update()
    cv2.destroyAllWindows()