切换填充颜色(黑色或白色,取决于所选的像素颜色)

时间:2019-06-09 11:43:20

标签: python opencv flood-fill

我正在编写一个简单的程序,通过单击图像的不同区域来逐渐填充(使用泛洪)图像(黑色背景和随机的白色矩形),使其完全变为白色。顺利完成。

因此,我想通过在填充白色和黑色之间切换来使其更加有趣。如图所示,如果我单击的像素是白色区域的一部分,则将其填充为黑色。否则,如果它是黑色区域的一部分,则将其填充为白色。

但是,当我将某些框更改为白色后,在单击它之后,它拒绝更改为黑色(无法将颜色切换回原来的颜色)。此外,由于我的矩形是使用3或4像素粗的线绘制的,因此在将所有线更改为黑色后,似乎仍“记住”这些线的存在,因此当我单击某些暗区时,有时会被那些看不见的“上一条”线变成白色。

我尝试打印像素颜色以确认拾取的颜色确实是白色或黑色,但是泛洪填充并没有使用正确的替代颜色(由我的if / else循环编写)填充

import numpy as np
import cv2 as cv
import random

width = 800
height = 500
img = np.zeros((height, width), np.uint8)
mask = np.zeros((height+2, width+2), np.uint8)


def click_event(event, x, y, flags, param):
    if event == cv.EVENT_LBUTTONDOWN:
        font = cv.FONT_HERSHEY_PLAIN
        strxy = "X: {0}  Y: {1}".format(x,y)
        print(strxy)
        fillmeup(x, y)
        cv.imshow("test", img)

def fillmeup(x, y):
    print(img[y,x])
    if img[y,x] == 0:
        cv.floodFill(img, mask, (x, y), 255)

    elif img[y,x] == 255:
        cv.floodFill(img, mask, (x, y), 0)

def drawboxes(qty):
    global img
    for _ in range(qty):
        w = int(random.random()*width)
        h = int(random.random()*height)
        x = random.randrange(0, width-w)
        y = random.randrange(0, height-h)
        img = cv.rectangle(img, (x, y), (x+w, y+h), 255, 2)

drawboxes(7)

cv.imshow("test", img)
cv.setMouseCallback("test", click_event)

cv.waitKey(0)
cv.destroyAllWindows() 

好吧,我希望以后每次在黑色区域上单击都会产生白色,反之亦然,但这没有发生。 而且当它确实切换回白色时,似乎已经被已经变成黑色的不可见线所包围。

以下是随附的样本结果。 01_start

02_selecting 2 boxes

03_selecting one of the thin white lines changes them to black: correct outcome

04_selecting some random random black space, but yet bounded white rectangles appear. the boundaries were the original white lines. weird outcome

1 个答案:

答案 0 :(得分:0)

floodFill()不仅更新图像,还更新mask

  

在输出时,与图像中填充像素相对应的遮罩像素将设置为1或如下所述在标志中指定的a值。因此,可以在多次调用该函数时使用相同的遮罩,以确保填充区域不重叠。

def fillmeup(x, y):
    print(img[y,x])
    mask = np.zeros((height+2, width+2), np.uint8)
    if img[y,x] == 0:
       cv.floodFill(img, mask, (x, y), 255)
    else:
       cv.floodFill(img, mask, (x, y), 0)

正如您所描述的,这对我有用。如果根本不需要遮罩,则可以编写

cv.floodFill(img, None, (x, y), ...)

这对我也适用,但是我没有发现任何证据表明None掩码参数对于floodFill()是合法的。如果在任何权威来源中发现答案是否合法,请通知我以更新答案。