簡體   English   中英

如何用黑色更改聯系人中的像素集 colors

[英]How to change the set of pixel colors in contatc with black color

考慮這張圖片:

在此處輸入圖像描述

我想通過紅色更改與黑色像素接觸的白色像素集,這樣: 在此處輸入圖像描述

我試圖在python中使用此代碼:

import numpy as np
from PIL import Image

im = Image.open('image.png')
data = np.array(im)

r1, g1, b1 = 255, 255, 255 # Original value
r2, g2, b2 = 0, 0, 255 # Value that we want to replace it with

red, green, blue = data[:,:,0], data[:,:,1], data[:,:,2]
mask = (red == r1) & (green == g1) & (blue == b1)
data[:,:,:3][mask] = [r2, g2, b2]

im = Image.fromarray(data)

但是我把所有的白色像素都換成了紅色。 但也可能是UNIX方法建議。

請發布輸入圖像的無損版本。 有損圖像會修改像素值,從而產生影響處理的偽像。 我重新創建了您的圖像並將其保存為無損 PNF 文件

我正在使用 OpenCV 來獲得您想要的結果。 我用原始輸入的非零元素創建了一個掩碼。 然后,我使用Flood-fill用你想要的顏色填充外部形狀。 如果你AND兩個圖像,可以獲得最終圖像。

讓我們看看代碼:

# import opencv:
import cv2

# image path
path = "D://opencvImages//"
fileName = "rectsLossless.png"

# Reading an image in default mode:
inputImage = cv2.imread(path + fileName)

# Grayscale image:
grayscaleImage = cv2.cvtColor(inputImage, cv2.COLOR_BGR2GRAY)

# Get non-zero mask:
binaryThresh = 1
_, binaryMask = cv2.threshold(grayscaleImage, binaryThresh, 255, cv2.THRESH_BINARY)

該位創建非零像素掩碼:

這將有助於將所有非白色元素歸零。 該圖像是掩碼的第一部分。 現在,讓我們用紅色填充外部形狀。 這是通過三個步驟實現的:

# Get image dimensions:
(imageHeight, imageWidth) = inputImage.shape[:2]

# Get image center:
xCenter = int(0.5 * imageWidth)
yCenter = int(0.5 * imageHeight)

# Get flood-fill target color
floodColor = inputImage[yCenter, xCenter]
print("Flood Color: %s" % floodColor)
# numpy array to tuple
floodColor = (int(floodColor[0]), int(floodColor[1]), int(floodColor[2]))

第一步獲取實際的填充顏色。 我想紅色或多或少位於圖像的中心。 然后,第二步涉及用白色填充所有“前景”像素。 讓我們在左上角播種:

# Flood fill at top left corner:
leftCorner = (1, 1)
whiteColor = (255, 255, 255)
cv2.floodFill(inputImage, None, leftCorner, whiteColor)

這是結果:

請注意,部分位於紅色矩形之外的形狀現在如何全部由白色連接。 讓我們再次填充,但這次使用我之前提取的紅色:

# Second Flood-fill
cv2.floodFill(inputImage, None, leftCorner, floodColor)

這會產生以下圖像:

讓我們通過將結果與原始非零掩碼進行AND運算來創建最終圖像:

# Create final image:
outImage = cv2.bitwise_and(inputImage, inputImage, mask=binaryMask)

這是最終結果:

這個問題非常接近這個問題
我的解決方案也很接近......

假設 colors 是黑色白色和紅色(一般情況可能比較棘手),我們可以使用以下階段:

  • 用白色填充黑色背景(使用cv2.floodFill )。
    紅色邊界上的白色 object 與背景合並。
  • 用黑色填充白色背景(使用cv2.floodFill )。
    紅色邊界上的白色 object 將變為黑色。
  • 將紅色通道從原始圖像復制到“填充”圖像。
    白色像素的紅色通道是 255,所以黑色和白色變成紅色。

代碼示例:

import cv2
import numpy as np

img = cv2.imread('red_white_black.jpg')

# Copy the original image to img2
img2 = img.copy()

# Fill the black background with white color
cv2.floodFill(img2, None, seedPoint=(0, 0), newVal=(255, 255, 255), loDiff=(50, 50, 50), upDiff=(50, 50, 50))

cv2.imshow('black background', img2)  # Show img2 for testing


# Fill the white background with black color
cv2.floodFill(img2, None, seedPoint=(0, 0), newVal=(0, 0, 0), loDiff=(50, 50, 50), upDiff=(50, 50, 50))

cv2.imshow('white background', img2)  # Show img2 for testing


# Copy the red color channel from the original image to img2
img2[:, :, 2] = img[:, :, 2]

cv2.imshow('img2', img2)  # Show img2 for testing
cv2.waitKey()
cv2.destroyAllWindows()

結果:
黑色背景:
在此處輸入圖像描述

白色背景:
在此處輸入圖像描述

img2
在此處輸入圖像描述

紅色周圍的黑色邊緣是因為原始圖像是 JPEG 而不是 PNG(顏色不純),並且紅色不是純紅色。

我們可以使用以下代碼修復它(代碼不是很優雅)...

red = img[:, :, 2]
r = np.median(img[:, :, 2][red > 50])
g = np.median(img[:, :, 1][red > 50])
b = np.median(img[:, :, 0][red > 50])

mask = np.logical_and(img[:, :, 0] > 100, img2[:, :, 0] <= 100)
img3 = img2.copy()
img3[:, :, 2][mask] = r
img3[:, :, 1][mask] = g
img3[:, :, 0][mask] = b
img3[:, :, 2] = cv2.morphologyEx(img3[:, :, 2], cv2.MORPH_CLOSE, np.ones((3, 3), np.uint8))
img3[:, :, 1] = cv2.morphologyEx(img3[:, :, 1], cv2.MORPH_OPEN, np.ones((3, 3), np.uint8))
img3[:, :, 0] = cv2.morphologyEx(img3[:, :, 0], cv2.MORPH_OPEN, np.ones((3, 3), np.uint8))
cv2.imshow('img3', img3)
cv2.waitKey()
cv2.destroyAllWindows()

結果:
在此處輸入圖像描述

暫無
暫無

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

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