简单的质心算法仿真和实验
程序
模拟光斑
# 理想光斑模型
def Gaussian2D(sigma, miu_1, miu_2, x, y):
z = (1 /sigma) * np.exp(-((x - miu_1) ** 2 + (y - miu_2) ** 2) / (sigma ** 2))
return z
# 生成带有高斯噪声光斑模型
#创建光斑模型图片
def generate(img_shape, sigma, miu_1, miu_2,N):
(width, height) = img_shape
X = np.arange(0, width, 1)
Y = np.arange(0, height, 1)
X, Y = np.meshgrid(X, Y)
img = Gaussian2D(sigma, miu_1, miu_2, X, Y)
# img = ns.salt_noise(img,N)
# img = img+ns.gau_noise(img,0.005)
img = ns.salt_noise(img, N)
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(X, Y, img, cmap=cm.coolwarm,
linewidth=0, antialiased=False)
ax.zaxis.set_major_locator(LinearLocator(10))
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))
# Add a color bar which maps values to colors.
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
return img
模拟随机的椒盐噪声
def salt_noise(img,N):
x_sum = 0
y_sum = 0
for i in range(N):
x = np.random.randint(0,500)
y = np.random.randint(0,500)
img[y][x] = np.max(img)
return img
通过CMOS相机得到的灰白光斑照片
def img_read(img_path):
img = plt.imread(img_path)
#+++++++++++++++++++++归一化到0-255之间+++++++++++++++
if len(img.shape) > 2:
img = img.mean(axis=2)
originalMinValue = np.min(img)
originalMaxValue = np.max(img)
originalRange = originalMaxValue - originalMinValue
img = 255 * (img - originalMinValue) / originalRange
img = np.around(img)
print(img)
return img
质心算法
def tr_centroid_algorithm(shape,img):
# 灰度值加总
x, y = shape
threshold = np.sum(img)/(x*y)
grayX_valueSum = 0.0
grayY_valueSum = 0.0
gray_valueSum = 0.0
for i in range(x):
for j in range(y):
if img[i][j] < threshold:
img[i][j] = 0
grayX_valueSum += i * img[i][j]
grayY_valueSum += j * img[i][j]
gray_valueSum += img[i][j]
x_c = grayX_valueSum / gray_valueSum
y_c = grayY_valueSum / gray_valueSum
center_position = (y_c, x_c)
return center_position
#=================加权平方质心算法================
##不适合椒盐噪声比较大的
def square_centroid_algorithm(shape, img):
#加权平方质心算法
x, y = shape
grayX_valueSum = 0.0
grayY_valueSum = 0.0
gray_valueSum = 0.0
threshold = np.sum(img) / (x * y)
for i in range(x):
for j in range(y):
if img[i][j] < threshold:
img[i][j] = 0
grayX_valueSum += i*((img[i][j])**2)
grayY_valueSum += j*((img[i][j])**2)
gray_valueSum += (img[i][j])**2
x_c = grayX_valueSum/gray_valueSum
y_c = grayY_valueSum/gray_valueSum
center_position = (y_c, x_c)
return center_position
主程序
if __name__ == '__main__':
path = "008.png"
img = er.img_read(path)
shape = img.shape
center_ax1 = ca.tr_centroid_algorithm(shape,img)
center_ax2 = ca.square_centroid_algorithm(shape, img)
print(center_ax1,center_ax2)
plt.figure()
plt.plot(center_ax1[0],center_ax1[1],marker='o',markersize=5,
label="traditional centroid algorithm")
plt.plot(center_ax2[0],center_ax2[1],marker='o',markersize=2,
label="square centroid algorithm")
plt.imshow(img,cmap="gray")
plt.legend()
plt.show()
仿真结果
理想高斯光斑对应的实验结果(289,307)
加上随机椒盐噪声(250,250)
传统(249.737741615272, 250.04379953388042)
加权(249.49177547117412, 250.08141883380614)
传统(249.9948760536369, 249.95908029324465)
加权(249.99246537464057, 249.9253089391913)
实验结果
实验原理图
实验装置图
实验结果处理
CMOS像素:2048×1536
001.pgm
传统阈值算法:(946.8248700956387, 739.0951441664839)
平方加权算法:(946.9951532351402, 739.6160210844841)
002.pgm
传统阈值算法:(1219.9349157580625, 432.73786390104505)
平方加权算法:(1222.6862424084402, 428.7885181805899)
003.pgm
传统阈值算法:(1158.2684591625016, 996.4485059513937)
平方加权算法:(1159.0742006690245, 1004.2174495319779)
004.pgm
传统阈值算法:(1615.910249562971, 511.5607608509442)
平方加权算法:(1628.8798166031754, 491.8004277438292)
备注:001.pgm和002.pgm是激光器直接照射,003.pgm和004.pgm是上述装置图得到的结果