发布于2025-01-05 09:02 阅读(954) 评论(0) 点赞(0) 收藏(4)
I'm trying to modify the sorrounding values around clusters in an image so that the neighbours pixels decrease to zero following a exponential decay. I need to find a way to control the decaying rate with a parameter. I also want to keep the original non-zero values in the image.
I have created an example were I used convolution (with average kernel) to create the haloe of decaying values. Unfortunately, it does not create what I really want, since the values decay too quickly, and the non zero values are not kept. I tried as well using a gaussian kernel and varying the sigma value so I can control the spread, the problem is that it reduces the value too much near the clusters. Maybe using a custom filter could help?
import matplotlib.pyplot as plt
import numpy as np
from scipy.ndimage import convolve
matrix = np.zeros((100, 100))
# Create clusters of values
matrix[45:55, 40:50] = 0.5
for i, value in enumerate(np.linspace(0.5, 0.2, 20)):
matrix[70:90, 20 + i] = value # Decreasing along the columns
# Create an average kernel (15x15 window)
size = 3
kernel = np.ones((size, size)) / (
size * size
) # Normalize the kernel to get the average
# Apply the average filter
filtered_matrix = convolve(matrix, kernel, mode="nearest")
# Combine the original values with the filtered (halo) values
result = np.where(matrix > 0, matrix, filtered_matrix)
# Plot the original, filtered, and combined matrices
fig, ax = plt.subplots(1, 3, figsize=(18, 6))
# Original matrix
im1 = ax[0].imshow(matrix, cmap="viridis")
ax[0].set_title("Original Matrix")
plt.colorbar(im1, ax=ax[0], label="Increment [m]", fraction=0.046, pad=0.04)
# Filtered matrix (after applying the average kernel)
im2 = ax[1].imshow(filtered_matrix, cmap="viridis")
ax[1].set_title("Filtered Matrix with Average Kernel")
plt.colorbar(im2, ax=ax[1], label="Increment [m]", fraction=0.046, pad=0.04)
# Final result with original values preserved and haloes included
im3 = ax[2].imshow(result, cmap="viridis")
ax[2].set_title("Result with Haloes Included")
plt.colorbar(im3, ax=ax[2], label="Increment [m]", fraction=0.046, pad=0.04)
plt.tight_layout()
plt.show()
Note that Convolution with Gaussian kernel represents an isotropic diffusion process that will decrease the intensity of objects isotropically, so pasting the original image on top will destroy the halo.
Something like the following, using mathematical morphology should work. Iteratively expand the contour of the objects (e.g., with dilation). Everytime you expand the contour of objects , ensure that the added pixel intensities are decayed exponentially (with a decay factor with which you can control the spread of the halo).
The decay_factor
, num_iter
(the number of iterations) and the structuring element (footprint
) type (e.g., disk
or square
) and size (se_sz
) are the parameters you can vary to get the desired effect.
from skimage.morphology import dilation, disk, square
decay_factor = 0.05
se_sz = 3
num_iter = 7
out_matrix = matrix.copy()
prev_filtered_matrix = matrix.copy()
for i in range(num_iter):
filtered_matrix = dilation(prev_filtered_matrix, square(se_sz))
decayed_expansion = (filtered_matrix - prev_filtered_matrix)*np.exp(-decay_factor*i)
out_matrix = out_matrix + decayed_expansion # add exp-decayed expansion
prev_filtered_matrix = filtered_matrix
# Plot the original, filtered, and combined matrices
fig, ax = plt.subplots(1, 2, figsize=(18, 6))
plt.gray()
# Original matrix
im1 = ax[0].imshow(matrix)
ax[0].set_title("Original Matrix")
plt.colorbar(im1, ax=ax[0], label="Increment [m]", fraction=0.046, pad=0.04)
# Final result with original values preserved and haloes included
im3 = ax[1].imshow(out_matrix)
ax[1].set_title("Result with Haloes Included")
plt.colorbar(im3, ax=ax[1], label="Increment [m]", fraction=0.046, pad=0.04)
plt.tight_layout()
plt.show()
The output obtained with square
SE is the one shown below:
Note that here we are not changing the original image (so no change in original image intensity), only adding a fringe layer (with decayed intensity) at every iteration, eliminating the need to paste the original image to the output in the end.
You can optionally keep the images normalized (e.g., scaling the maximum intensity value to 1) at each iteration.
The next animation shows halo expansion:
作者:黑洞官方问答小能手
链接:https://www.pythonheidong.com/blog/article/2046775/85d8702d4c4f5036280a/
来源:python黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 python黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-1
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!