簡體   English   中英

OpenCV - 如何對 RGB 圖像使用 floodFill?

[英]OpenCV - How to use floodFill with RGB image?

我正在嘗試在如下圖像上使用floodFill來提取天空:

在此處輸入圖片說明

但即使我設置了loDiff=Scalar(0,0,0)upDiff=Scalar(255,255,255) ,結果也只是顯示了種子點並且不會變大(綠點):

在此處輸入圖片說明

代碼:

Mat flood;
Point seed = Point(180, 80);
flood = imread("D:/Project/data/1.jpeg");
cv::floodFill(flood, seed, Scalar(0, 0, 255), NULL, Scalar(0, 0, 0), Scalar(255, 255, 255));
circle(flood, seed, 2, Scalar(0, 255, 0), CV_FILLED, CV_AA);

這是結果(紅點是種子):

在此處輸入圖片說明

如何設置功能以獲得更大的區域(如整個天空)?

您需要正確設置loDiffupDiff參數。

請參閱floodFill 文檔

loDiff – 當前觀察到的像素與其屬於該組件的鄰居之一或添加到該組件的種子像素之間的最大較低亮度/色差。
upDiff – 當前觀察到的像素與其屬於組件的鄰居之一之間的最大亮度/色差,或添加到組件的種子像素。

這是一個 Python 代碼示例:

import cv2
flood = cv2.imread("1.jpeg");

seed = (180, 80)

cv2.floodFill(flood, None, seedPoint=seed, newVal=(0, 0, 255), loDiff=(5, 5, 5, 5), upDiff=(5, 5, 5, 5))
cv2.circle(flood, seed, 2, (0, 255, 0), cv2.FILLED, cv2.LINE_AA);

cv2.imshow('flood', flood)
cv2.waitKey(0)
cv2.destroyAllWindows()

結果:
地面

如果您希望洪水填充輪廓盡可能接近圖像中的對比元素,您可以做的另一件事是執行 Kmeans 顏色量化以將圖像分割為指定數量的集群。 由於天空和山/樹有明顯的色差,我們可以將圖像分割成三種顏色,這樣可以更好地分離物體。

例如clusters=3

輸入圖像-> Kmeans 顏色分割

Floodfill 結果為綠色

注意分割后,只有三種顏色定義圖像。 通過這種方式,填埋場將更好地沿着山脈/樹木的輪廓

代碼

import cv2
import numpy as np

# Kmeans color segmentation
def kmeans_color_quantization(image, clusters=8, rounds=1):
    h, w = image.shape[:2]
    samples = np.zeros([h*w,3], dtype=np.float32)
    count = 0

    for x in range(h):
        for y in range(w):
            samples[count] = image[x][y]
            count += 1

    compactness, labels, centers = cv2.kmeans(samples,
            clusters, 
            None,
            (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10000, 0.0001), 
            rounds, 
            cv2.KMEANS_RANDOM_CENTERS)

    centers = np.uint8(centers)
    res = centers[labels.flatten()]
    return res.reshape((image.shape))

# Load image and perform kmeans
image = cv2.imread('1.jpg')
kmeans = kmeans_color_quantization(image, clusters=3)
result = kmeans.copy()

# Floodfill
seed_point = (150, 50)
cv2.floodFill(result, None, seedPoint=seed_point, newVal=(36, 255, 12), loDiff=(0, 0, 0, 0), upDiff=(0, 0, 0, 0))

cv2.imshow('image', image)
cv2.imshow('kmeans', kmeans)
cv2.imshow('result', result)
cv2.waitKey()     

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM