生成RGB高斯光斑图像

  1. 高斯光束分布模型

其中,光斑中心坐标为 (x0, y0);标准差 σ 用以控制光斑大小;峰值强度 A 归一化为[0 ∼ 255](x, y) 为图像中任意点的坐标。

  1. 引入噪声模型,暂时使用均匀分布的噪声矩阵:

N(x, y, k) ∼ Uniform(a, b)

其中,k ∈ (R, G, B) 为颜色通道。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import cv2
import numpy as np

def create_gaussian_spot(image_size=(400, 400), center=(200, 200), sigma=30, intensity=255):
"""
创建模拟的高斯光斑图像
参数:
image_size: 图像尺寸 (width, height)
center: 光斑中心 (x, y)
sigma: 高斯分布的标准差
intensity: 最大强度值
返回:
spot_image: 生成的光斑图像
"""
width, height = image_size
x = np.arange(0, width, 1, dtype=np.float32)
y = np.arange(0, height, 1, dtype=np.float32)
x, y = np.meshgrid(x, y)

# 创建二维高斯分布
gaussian = np.exp(-((x - center[0])**2 + (y - center[1])**2) / (2 * sigma**2))

# 归一化到0-255
gaussian = (gaussian * intensity).astype(np.uint8)

# 创建RGB图像(三个通道相同)输出灰度图
rgb_image = np.stack([gaussian, gaussian, gaussian], axis=2)

# 添加一些随机噪声模拟真实情况
noise = np.random.randint(0, 20, (height, width, 3), dtype=np.uint8)
rgb_image = cv2.add(rgb_image, noise)

return rgb_image

# 创建图像
spot_image = create_gaussian_spot()

# 显示图像
cv2.imshow('Gaussian Spot', spot_image)
cv2.waitKey(0) # 等待按键
cv2.destroyAllWindows() # 关闭窗口

# 可选:保存图像
cv2.imwrite('gaussian_spot.png', spot_image)
print("图像已保存为 'gaussian_spot.png'")
  • 灰度高斯光斑(分辨率为 400 × 400,质心为图像中心)
代码产生的灰度高斯光斑;质心为图像中心为(200,200)

一阶矩求质心

  1. 获取图像的分辨率,得知图像的像素点矩阵。
  2. 对图像进行灰度处理,将原本的RGB颜色转化为明暗图像。常用浮点算法得到:

Gray = 0.3R + 0.59G + 0.11B

  1. 采取合适的降噪阈值 Q ,只将大于阈值的灰度赋予权重。

采用Q=128降噪之后的光斑图像
  1. 计算图像中所有像素的灰度值之和,每个像素与其对应的二维坐标的乘积之和:

光斑质心算法得到的计算值
  • Python代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import cv2
import numpy as np


def calculate_centroid(image_path, threshold=128):
"""
使用一阶矩计算光斑质心
参数:
image_path: 输入图像路径
threshold: 降噪阈值Q,默认为128
返回:
centroid_x, centroid_y: 质心坐标
processed_image: 处理后的图像
"""
# 1. 读取图像并获取分辨率
image = cv2.imread(image_path)
if image is None:
raise ValueError("无法读取图像,请检查图像路径")

height, width = image.shape[:2]
print(f"图像分辨率: {width} x {height}")

# 2. 灰度处理 - 使用公式 Gray = 0.3R + 0.59G + 0.11B
# 将BGR图像分离通道
b, g, r = cv2.split(image.astype(np.float32))

# 应用灰度转换公式
gray_image = 0.3 * r + 0.59 * g + 0.11 * b
gray_image = gray_image.astype(np.uint8)

# 3. 应用阈值处理
# 创建掩码:大于阈值的保留原值,小于等于阈值的设为0
mask = gray_image > threshold
processed_image = np.zeros_like(gray_image, dtype=np.float32)
processed_image[mask] = gray_image[mask]

# 4. 计算质心坐标
# 创建坐标网格
x_coords, y_coords = np.meshgrid(np.arange(width), np.arange(height))

# 计算分子和分母
sum_intensity = np.sum(processed_image)

if sum_intensity == 0:
raise ValueError("没有找到足够亮的光斑,请调整阈值")

centroid_x = np.sum(x_coords * processed_image) / sum_intensity
centroid_y = np.sum(y_coords * processed_image) / sum_intensity

return centroid_x, centroid_y, processed_image.astype(np.uint8)


def visualize_results(original_image, processed_image, centroid_x, centroid_y):
"""
可视化处理结果
"""
# 在原始图像上标记质心
result_image = original_image.copy()
center = (int(centroid_x), int(centroid_y))

# 绘制质心标记
cv2.circle(result_image, center, 5, (0, 0, 255), -1) # 红色实心圆
cv2.circle(result_image, center, 10, (0, 0, 255), 2) # 红色圆圈
cv2.putText(result_image, f'Centroid: ({centroid_x:.2f}, {centroid_y:.2f})',
(10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)

# 显示图像
cv2.imshow('Original Image', original_image)
cv2.imshow('Processed Image', processed_image)
cv2.imshow('Result with Centroid', result_image)

print(f"质心坐标: ({centroid_x:.2f}, {centroid_y:.2f})")

cv2.waitKey(0)
cv2.destroyAllWindows()

return result_image


# 主函数
if __name__ == "__main__":
# 获取用户输入的图像路径
image_path = "gaussian_spot.png"

# 设置阈值
threshold_input = input("请输入阈值 (默认128,直接回车使用默认值): ").strip()
if threshold_input:
try:
threshold = int(threshold_input)
except ValueError:
print("输入阈值无效,使用默认值128")
threshold = 128
else:
threshold = 128

try:
# 读取原始图像
original_image = cv2.imread(image_path)
if original_image is None:
raise ValueError(f"无法读取图像: {image_path}")

# 计算质心
centroid_x, centroid_y, processed_image = calculate_centroid(image_path, threshold=threshold)

# 显示结果并获取标记后的图像
result_image = visualize_results(original_image, processed_image, centroid_x, centroid_y)

# 可选:保存处理后的图像
save_choice = input("是否保存结果图像? (y/n): ").strip().lower()
if save_choice == 'y' or save_choice == 'yes':
output_path = "Centriod_result.png" # 修正了文件名
cv2.imwrite(output_path, result_image)
print(f"结果图像已保存为: {output_path}")

except Exception as e:
print(f"处理过程中出现错误: {e}")