常见的接触角用蔡司显微镜拍摄后,有三种处理方法:量角法、切线法、量高法
但是结果都不是很好,且认为误差较大,可以通过图像处理,来判定角度。
先写了浸入条件的(其的还没写好,寄):
# -*- coding: utf-8 -*-
"""
Created on Sat Nov 18 10:57:47 2023
@author: ChuanQi
@email: laijiugo@163.com
1. 截取图片 θ<90°
2. 对图片获取初值 基准点的确定(可以在左边,但不要太下面)
3. 观察像素点,拟合直线的情况(确定omit_last值 保证噪声的去除)
4. 角度在title
"""
from PIL import Image
from PIL import ImageFilter
import matplotlib.pyplot as plt
import numpy as np
plt.close('all')
plt.rcParams['font.sans-serif'] = ['SimHei'] # 步骤一(替换sans-serif字体)
plt.rcParams['axes.unicode_minus'] = False # 步骤二(解决坐标轴负数的负号显示问题)
file_name = 'jcj2.png' # 图片边界稍有留白
img = Image.open(file_name)
plt.imshow(img)
img = img.filter(ImageFilter.CONTOUR)
img_filter = np.array(img)[:,:,0] # 图像边缘不要有伪影
position = np.array([[0,0]])
#%%
#chu_zhi = input('输入初值 [ _ , _ ]:')
chu_zhi = [343,176] # 255白色 随意 只要在曲线左边 (y,x)
while True:
if img_filter[chu_zhi[0],chu_zhi[1]+1] != 255:
new_point = np.array([[chu_zhi[0],chu_zhi[1]+1]])
position = np.concatenate((position,new_point))
chu_zhi[0] = chu_zhi[0]-1 # 上移
else:
chu_zhi[1] = chu_zhi[1]+1 # 右移
if chu_zhi[0] == 0 or chu_zhi[1] == np.size(img_filter,1)-1:
break
#%% theta<90
omit_last = 20 # 舍去后续的偏差点 # 图像显示后观察
x_y = position[1:-omit_last,:][:,[1,0]] # plot是x,y array(row,col)刚好相反
x = np.array(x_y[:,0])
y = np.array(x_y[:,1])
reg = np.polyfit(x,y,5)
r_y = np.polyval(reg, x)
# 求解theta
import sympy as sp
xx = sp.symbols('xx')
fuc = np.polyval(reg, xx)
fuc_x = sp.diff(fuc, xx)
#print("对x求导结果 : ", fuc_x)
fun_x_value = float(fuc_x.evalf(subs={xx:x.min()})) # 将x带入 求k
theta = round(abs(np.arctan(fun_x_value)*180/np.pi),2)
x_qiexian = np.arange(len(x))+x[0] # X0
y_qiexian = fun_x_value*(x_qiexian-x[0])+y[0] # 绘制切线
plt.plot(x,y,'b*')
plt.plot(x_qiexian,y_qiexian,'r-')
plt.xlim(0,img.size[0])
plt.ylim(img.size[1],0)
plt.plot([x[0],img.size[0]], [y[0],y[0]],'g-')
plt.text(x[0]+5, y[0]-5, 'θ={}°'.format(theta),color='red')
plt.title('真实图像的拟合')
fig = plt.figure()
plt.plot(x,y,'b*',label='像素点')
plt.plot(x,r_y,'r-',label='拟合值')
plt.title('像素点的拟合程度') # 修改omit_last
plt.legend()
print('导数值:',fun_x_value)
print('theta=',theta)
其实就是拟合的思想,如果相对噪声具有更好的抗干扰效果,可以找整个图片倒数最大的点作为边界,再拟合,求初始点的斜率,并转化成角度。
结果图