# [数字图像学笔记] 5.噪音生成——泊松噪音（二）

OpenCV与数字图像处理 专栏收录该内容
14 篇文章 0 订阅

# 泊松噪音

## Knuth算法

P ( x = k ) = e − λ λ k k ! P(x=k) = \frac{e^{- \lambda} \lambda ^ k}{k!}

P ( t w a i t > t e v e n t ) = e − σ ⋅ t P(t_{wait} > t_{event}) = e^{- \sigma \cdot t}

P w a i t > P e v e n t P_{wait} > P_{event}

algorithm poisson random number (Knuth):
init:
Let L ← exp(−λ), k ← 0 and p ← 1.
do:
k ← k + 1.
Generate uniform random number u in [0,1] and let p ← p × u.
while p > L.
return k − 1.


p = p × u p = p × u 因上式得到了 P k = u k P_k = u^k , 又因为 u ∈ ( 0 , 1 ) u \in (0, 1) 所以这里其实得到的是单调递减的指数函数。所以，问题最后被简化成了每一次生成的 P k P_k 是否比第0次事件小，如果 P k > P 0 P_k > P_0 说明当前发生的事件可能是一个概率极低的事件。

## 散列生成算法

def poisson_distribution(lam: float, limits: int):
distributions = []
e_lam = math.pow(math.e, -lam)  				# e^{-lambda}
sum = 0

for k in range(0, 100):
lambda_k = math.pow(lam, k) 		 		# lambda^k
k_factorial = math.factorial(k)  			# k!
prob = (lambda_k / k_factorial) * e_lam  	# poisson distribution when x=k
sum = sum + prob

if limits - 1 <= k:
others = 1 - sum  						# long tail incidents
distributions.append(others)
break

if prob > 0:
distributions.append(prob)
k = k + 1
else:
break

return distributions

def generate_poisson_list(distribution, size=100):
pos = 0
poisson_list = []

for prob in distribution:
max = round(size * prob)  	# create a list has size,
# convert the probability to a certain length
# of array
p_list = []

if max < 1:					# size is not enough to init a list, skip
break

for i in range(max):		# assign k to the certain length array
p_list.append(pos)

pos = pos + 1
poisson_list.append(p_list)	# append the probability converted array

poisson_list = [i for elem in poisson_list for i in elem] # flat the ragged arrays to an 1-d array!
return poisson_list


def poisson_value2(poisson_list):
number = random.random() * (len(poisson_list) - 1)  # to avoid the situation when a[i]
# i = len(a)
number = round(number)
return poisson_list[number]  						# k = poisson_list[number]


knuth大神的代码实现则大概是这样的味道：

def poisson_value1(lamb):
L = math.exp(-lamb)
k = 0
p = 1

while p >= L:
k = k + 1
# Generate uniform random number u in [0, 1] and let p ← p × u.
p = random.random() * p

return k - 1


## 生成泊松噪音的图像

def poisson_noise1(image, pvals, dts, lamb):
output = np.zeros(image.shape, np.uint8)

for i in range(image.shape[0]):
for j in range(image.shape[1]):

# get the poisson value
noise_value = 0
for k in range(dts):
noise_value = noise_value + poisson_value1(pvals)

# add noise to original image
temp = image[i][j] + noise_value - dts * lamb  # compensating
if temp > 255:
temp = 255
if temp < 0:
temp = 0

# assign noised image to output
output[i][j] = temp

return output


def poisson_noise2(image, lamb):
output = np.zeros(image.shape, np.uint8)

for i in range(image.shape[0]):
for j in range(image.shape[1]):

# get the poisson value
noise_value = 0
for k in range(image[i][j]):
noise_value = noise_value + poisson_value2(lamb)

# add noise to original image
temp = noise_value
if temp > 255:
temp = 255

# assign noised image to output
output[i][j] = temp

return output


• 0
点赞
• 0
评论
• 2
收藏
• 一键三连
• 扫一扫，分享海报

03-02
12-04 917

11-20 1385
04-26 4282
06-19 6799
03-27 7331
04-01 1万+
07-24 615
08-06 6万+
09-18
09-18