接触角的定义
接触角(contact angle)指在气、液、固三相交点处所作的气-液界面的切线穿过液体与固-液交界线之间的夹角(θ),也是润湿程度的量度,主要测量方法为外形图像分析方法及称重法。————互动百科
具体思路
以下图为例:
将原图转为灰度图在转为二值图
去掉连通域中较小的区域。(MATLAB中默认白色为前景区域)
寻找边缘,并找出曲率突变的点即为突变点。
Note:黄色的线为液滴附着的水平面,一般斜率都不会太大,故在寻找突变点(即交点的时候)可以认为水平面的斜率在一个设置的范围内,在此范围内的点的斜率都置为0,剩下的斜率变化最大的点即为所找的两个突变点,这样利用突变点加上对蓝色弧线(液滴的边缘)的拟合即可求出接触角。
,
代码实现
%%%%%%%%%%%%接触角交点的自动计算%%%%%%%%%%%%%%
clc
clear
img_orignal =imread('0517.jpg') ;
img_gray =rgb2gray(img_orignal);%变灰度
% figure;imshow(img_gray);title('灰度图像');
level=graythresh(img_gray);
img_bin =im2bw(img_gray,level) ; %灰度图变二值图
figure;imshow(img_bin),title('二值图像');
img_bin = bwmorph(img_bin,'clean',Inf);
% figure;imshow(img_bin);title('clean')
STATS = regionprops(img_bin,'area'); %获得各个连通域的面积
areas = [STATS.Area];
img_change = bwareaopen(img_bin,max(areas));%去掉小于最大连通域面积的小连通域
figure
imshow(img_change)
title('img_change')
% imshow(label2rgb(L, @jet, [.5 .5 .5]))%显示图像
img_edge = bwperim(img_change,8) ; %查找二值图像的边缘
figure;
handle = imshow(img_edge);
title('img_edge');
[m,n] = size(img_change);
img_coordinate = zeros(m,n);
p = 0;
for j = 100:n-100 % 100:n-100,100可以按照自己的图片尺寸适当调整
for i = m:-1:1
if img_change(i,j) == 1
img_coordinate(i,j) = 1;
p = p+1;
coor(p,1) = i;
coor(p,2) = j;
break;
end
end
end
% figure;imshow(img_coordinate),title('img_coordinate');
% x,y坐标分离
coor_x = coor(:,2);
coor_y = coor(:,1);
for i = 2:size(coor,1)
if coor_x(i)~= coor_x(i-1) %防止斜率出现无穷大的情况,保证程序可以正常运行
k(i-1) = (coor_y(i)-coor_y(i-1))/(coor_x(i)-coor_x(i-1)); %相邻两点之间的斜率
end
end
for j = 1:size(k,2)
if k(j)<8&&k(j)>-8 %小于或者大于指定的斜率k认为是固体平面的斜率,并将其置0
k(j) = 0;
end
end
[Kv,index] = sort(k,'descend'); %Kv:相连点的斜率,index:Kv值对应的索引
catastrophe_a = coor_x(index(1));
catastrophe_b = coor_x(index(end));
if catastrophe_a>catastrophe_b
left_p = index(end); %左突变点
right_p = index(1); %右突变点
else
left_p = index(1); %左突变点
right_p = index(end);%右突变点
end
%%%%%%%%%%%%%%%直线坐标与圆弧坐标点的分离%%%%%%%%%%%%%
line_num = 0;%计数器
circle_num = 0;%计数器
for i = 1:size(coor,1)
if i<left_p-2||i>right_p+2
line_num = line_num+1;
line(line_num,1) = coor_x(i); %line第一列是x,第二列是y
line(line_num,2) = coor_y(i);
else
circle_num = circle_num+1;
circle(circle_num,1) = coor_x(i); %circle第一列是x,第二列是y
circle(circle_num,2) = coor_y(i);
end
end
hold on
[B,L] = bwboundaries(img_coordinate,'noholes');%寻找边缘,不包括孔
imshow(label2rgb(L, @jet, [.5 .5 .5]))%显示图像
for k = 1:length(B) %length(B)=4 即:B中有4个封闭区域
boundary = B{k};
handle = plot(boundary(:,2),boundary(:,1), 'g', 'LineWidth',0.00001); %boundary(:,2)代表索引矩阵第二列
end %整个循环表示的是描边
title('边缘提取后的图像');
str = ('交点');
msize = 8;
handle = plot(coor_x(left_p),coor_y(left_p),'o','LineWidth',2,'Color','r');
text(coor_x(left_p),coor_y(left_p)+50,str,'fontsize',msize);
handle = plot(coor_x(right_p+1),coor_y(right_p+1),'o','LineWidth',2,'Color','r');
text(coor_x(right_p+1),coor_y(right_p+1)+50,str,'fontsize',msize);
存在的问题
- 算出的交点可能会有所误差,原因是图像处理过程无法保证得到尽量完整的边缘。如程序中
msize = 8;
handle = plot(coor_x(left_p),coor_y(left_p),'o','LineWidth',2,'Color','r');
text(coor_x(left_p),coor_y(left_p)+50,str,'fontsize',msize);
handle = plot(coor_x( right_p + 1 ),coor_y( right_p + 1 ),'o','LineWidth',2,'Color','r');
text(coor_x(right_p+1),coor_y(right_p+1)+50,str,'fontsize',msize);`
变成
msize = 8;
handle = plot(coor_x(left_p),coor_y(left_p),'o','LineWidth',2,'Color','r');
text(coor_x(left_p),coor_y(left_p)+50,str,'fontsize',msize);
handle = plot(coor_x( right_p ),coor_y( right_p ),'o','LineWidth',2,'Color','r');
text(coor_x(right_p+1),coor_y(right_p+1)+50,str,'fontsize',msize);
得到的交点图