我正在嘗試創建帶有源影像的霓虹燈效果。我已經包含了三個影像,源、我當前的嘗試和目標。程式獲取影像,找到白邊,并計算每個像素到最近的白邊的距離(這些部分都可以正常作業);從那里開始,我正在努力尋找合適的飽和度和值引數來創建霓虹燈。
從目標影像來看,我需要做的基本上是讓白色邊緣的飽和度為 0,然后隨著距離邊緣越遠而顯著增加;對于價值,我需要它在白邊上為 1,然后大幅減少。我想不出操縱 distance_image 的最佳方法(它保存每個像素與最近的白邊的距離),例如以飽和度和值實作這兩個結果。
from PIL import Image
import cv2
import numpy as np
from scipy.ndimage import binary_erosion
from scipy.spatial import KDTree
def find_closest_distance(img):
white_pixel_points = np.array(np.where(img))
tree = KDTree(white_pixel_points.T)
img_meshgrid = np.array(np.meshgrid(np.arange(img.shape[0]),
np.arange(img.shape[1]))).T
distances, _ = tree.query(img_meshgrid)
return distances
def find_edges(img):
img_np = np.array(img)
kernel = np.ones((3,3))
return img_np - binary_erosion(img_np, kernel)*255
img = Image.open('a.png').convert('L')
edge_image = find_edges(img)
distance_image = find_closest_distance(edge_image)
max_dist = np.max(distance_image)
distance_image = distance_image / max_dist
hue = np.full(distance_image.shape, 0.44*180)
saturation = distance_image * 255
value = np.power(distance_image, 0.2)
value = 255 * (1 - value**2)
new_tups = np.dstack((hue, saturation, value)).astype('uint8')
new_tups = cv2.cvtColor(new_tups, cv2.COLOR_HSV2BGR)
new_img = Image.fromarray(new_tups, 'RGB').save('out.png')
下圖顯示了源資料(左)、當前結果(中)和所需結果(右)。

uj5u.com熱心網友回復:
我想我會用
您需要調整sigma高斯的 (其寬度)、顏色、模糊強度等。希望能幫助到你。
uj5u.com熱心網友回復:
這是在 Python/OpenCV 中執行此操作的一種方法。
- 讀取輸入
- 轉換為灰度
- 二進制閾值
- 使用形態梯度獲得所需厚度的邊緣
- 在白色背景上將邊緣反轉為黑色
- 做距離變換
- 拉伸到全動態范圍
- 倒置
- 通過除以最大值歸一化到 0 到 1 的范圍
- 使用冪律衰減控制距離滾降(斜坡)
- 創建輸入大小和所需顏色的彩色影像
- 將衰減影像乘以彩色影像
- 保存結果
輸入:

import cv2
import numpy as np
import skimage.exposure
# read input
img = cv2.imread('rectangles.png')
# convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# threshold
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU)[1]
# do morphology gradient to get edges and invert so black edges on white background
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
edges = cv2.morphologyEx(thresh, cv2.MORPH_GRADIENT, kernel)
edges = 255 - edges
# get distance transform
dist = edges.copy()
distance = cv2.distanceTransform(dist, distanceType=cv2.DIST_L2, maskSize=3)
print(np.amin(distance), np.amax(distance))
# stretch to full dynamic range and convert to uint8 as 3 channels
stretch = skimage.exposure.rescale_intensity(distance, in_range=('image'), out_range=(0,255))
# invert
stretch = 255 - stretch
max_stretch = np.amax(stretch)
# normalize to range 0 to 1 by dividing by max_stretch
stretch = (stretch/max_stretch)
# attenuate with power law
pow = 4
attenuate = np.power(stretch, pow)
attenuate = cv2.merge([attenuate,attenuate,attenuate])
# create a green image the size of the input
color_img = np.full_like(img, (0,255,0), dtype=np.float32)
# multiply the color image with the attenuated distance image
glow = (color_img * attenuate).clip(0,255).astype(np.uint8)
# save results
cv2.imwrite('rectangles_edges.png', edges)
cv2.imwrite('rectangles_stretch.png', (255*stretch).clip(0,255).astype(np.uint8))
cv2.imwrite('rectangles_attenuate.png', (255*attenuate).clip(0,255).astype(np.uint8))
cv2.imwrite('rectangles_glow.png', glow)
# view results
cv2.imshow("EDGES", edges)
cv2.imshow("STRETCH", stretch)
cv2.imshow("ATTENUATE", attenuate)
cv2.imshow("RESULT", glow)
cv2.waitKey(0)
邊緣(倒置):

拉伸距離變換:

衰減距離變換:

發光結果:

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/530047.html
