1. 程式人生 > >OpenCV-python 漫水操作

OpenCV-python 漫水操作

版權宣告:原創內容,轉載請註明來源https://blog.csdn.net/e01114255/article/details/76186656

原創內容,轉載請註明來源https://blog.csdn.net/qq_37354021/article/details/80854577

水漫填充演算法實現 
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.

 #cv.FLOODFILL_FIXED_RANGE填充方法為僅僅在mask的區域激進型  這種方法要mask設為1  填充的mask區域必需是0.  原理是不為1的才會被填充  

# -*- 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;其實更正為mask[:] = 1;
        mask[:] = 0
        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()