说明
此文为静态图像分割——水表指针提取(一)的续,主要解决指针分割后的图像指针角度问题。
图像摆正
核心代码
I=imread('img4.jpg');
BW=rgb2gray(I);
thresh=[0.01,0.10];
sigma=2;
f = edge(double(BW),'canny',thresh,sigma);
title('canny 边缘检测');
[H, theta, rho]= hough(f,'theta',-89.9:1:89.9);
peak=houghpeaks(H,5);
hold on
lines=houghlines(f,theta,rho,peak,'FillGap',5,'MinLength',20);
figure(1),imshow(f,[]),hold on
for k=1:length(lines) %画出直线
xy=[lines(k).point1;lines(k).point2];
plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','red');
end
x=lines(1).point1(1)-lines(1).point2(1);
y=lines(1).point1(2)-lines(1).point2(2);
mm=x*x+y*y;
angle=0;
for i=1:k %寻找最长直线的角度
x=lines(i).point1(1)-lines(i).point2(1);
y=lines(i).point1(2)-lines(i).point2(2);
m=x*x+y*y;
if(m>=mm)
mm=m;
angle=lines(i).theta;
end
end
i=imread('a4.bmp');
if(angle<0)
A = imrotate(i,90+angle,'bilinear','crop');
else
A = imrotate(i,angle-90,'bilinear','crop');
end
figure(2), imshow(A);saveas(2,'44-rotate.jpg');
saveas(1,'44-canny-line.jpg');
实验结果
指针角度
思路:先将指针的轮廓标出,然后找到轮廓的质心,再求出轮廓与质心距离,找到距离质心最远的点,最后求出质心与最远点连线的线段角度,根据线段角度计算读数(例如,以0°为0,180°为5)。
轮廓标记代码
filename = sprintf('1.jpg');
I = imread(filename);
BW = im2bw(I, graythresh(I));
BW=~BW;
[L,num]=bwlabel(BW,8);
STATS = regionprops(BW,'basic'); %获取轮廓信息,Area、Centroid、BoundingBox
[B,L] = bwboundaries(BW,'noholes'); %寻找边缘
imshow(label2rgb(L, @jet, [.5 .5 .5])),hold on
for k = 1:length(B)
boundary = B{k};
plot(boundary(:,2), boundary(:,1), 'w', 'LineWidth', 2) %框轮廓
for i=1:num
if((STATS(i).Area>600)&&(STATS(i).Area<2500))
rectangle('Position',STATS(i).BoundingBox,'Curvature',[0,0],'LineWidth',2,'EdgeColor','r');
%text命令
text(STATS(i).Centroid(1),STATS(i).Centroid(2),'pointer','Color','black');
plot(STATS(i).Centroid(1),STATS(i).Centroid(2), '*');
end
end
end
标记效果
从上图标记效果来看,由于初始的指针分割效果不佳,所以无法将每张图的指针区域标记出来,这对想通过上述思路解决问题造成了阻碍。遗憾最后也未能找到无需人工读数的方法,对于拍摄环境复杂的照片,建议人工读数。