基于hough变换的平行线识别

hough变换基本原理讲述

线段识别是识别图像中平行线的基础。但一张图像中所包含的线段几乎是无限的所以无法在图像中直接判断,因此引入Hough变换[32]。Hough变换的基础是建立极坐标空间用(ρ,θ)表示空间各点,并根据极坐标变换将图像中所有直线用空间各点(ρ,θ)表示。根据直线在极坐标系与直角坐标系间转换关系得式(1)。
ρ=xcos⁡θ+ysin⁡θ (1)
式中ρ为原点到该直线的垂直距离;θ为垂线与x轴的夹角。
Hough变换后得出极坐标空间与图像空间满足下述关系:(1) 极坐标空间中任意点(ρ, θ)都代表图像空间中的一条直线并将此直线记作l((ρ,θ));(2) 图像空间中任意点(x, y)对应于极坐标空间中一条三角函数线。

程序编写

- 程序实现步骤

在程序编写过程中将总体流程分为三部分:图像边缘线检测、线段检测与平行线检测。在图像边缘线检测中根据灰度梯度的变化情况,利用sobel算子完成边缘线检测;线段检测中利用Hough变换,识别边缘线中的线段,并输出所识别线段的角度和极径参数;在平行线检测过程中,根据平行线的几何特征制定线段组夹角、距离以及间距3种判定条件完成平行线判断,并识别程序流程图如下图所示。

程序代码

clc;
clear;
iceThickness=0;
%%   图片的读入与裁剪
f=imread('C:\Users\huawei\Desktop\海冰识别\前期过程\所识别图片\dachuang1.png');
%f=imcrop(f,[900,760,200,300]);  %裁剪图片
% f=imcrop(f,[670,0,689,817]);  %裁剪图片
% f=imcrop(f,[890,0,689,817]);  %裁剪图片
f=imcrop(f,[850,710,400,400]);
figure(10)
imshow(f);
%%   判断参数的定义
%角度----------------------------------- 2
theta_chazhi=3;
%两线间距离(极坐标下 )---------------- 70~15
distance_max=70;
distance_min=15;
%端点距离 ---------------------------- -10~25
boundray_point_distance_max=15;
boundray_point_distance_min=-15;
%中点距离----------------------------- -10~20
middle_point_distance_max=20;
middle_point_distance_min=-10;
%平行条件判断---------------------------- 13
parallel_judge=10;
%两线间距离(直角坐标系下)-------------- 10~100
xy_distance_max=100;
xy_distance_min=10;
%直线本身长度----------------------------- 25
length_min=25;
%两线长度差值--------------------------- 0.25~2.5
length_ratio_max=2;
length_ratio_min=0.5;%%   输出值预定义
iceThickness=0;
iceParameter.k_1=0;
iceParameter.k_2=0;
iceParameter.b_1=0;
iceParameter.b_2=0;
iceParameter.start_1=[0,0];
iceParameter.start_2=[0,0];
iceParameter.end_1=[0,0];
iceParameter.end_2=[0,0];%%   从视频中读入图片
% video=VideoReader('C:\Users\86132\Desktop\大创\20171203(1).mp4');      %读取MP4文件
% nFrames=video.NumberOfFrames;     %从视频中读取视频的总帧数
% n=round((nFrames-10)/25);
% im=cell(1,n);
% for k=1:n
%     m1=read(video,25*k);%读取第k帧,存入im中
%     im{k}=im2double(m1);%将图片存入元胞im,
% end
% f=imcrop(im{14},[850,0,689,817]);% figNames=struct2cell(dir('C:\Users\86132\Desktop\大创\截图\*.jpg'));
% [~,len]=size(figNames);
% for i=1:len
%     name=figNames{1,i};
% end
% f=imread(['C:\Users\86132\Desktop\大创\所识别图片\',name]);
% f=imcrop(f,[870,0,689,817]);  %裁剪图片%%   图像的基本处理
I=rgb2gray(f);     %进行灰度化% imshow(I),title('原图I');
% figure (1)
% imshow(I),title('裁剪图');se=strel('disk',20);%disk指定构建一个圆形的结构体,第二个参数指定结构体的半径
%接下来,进行基于重建的开操作。使用imerode和imreconstruct函数实现
Ie=imerode(I, se);%先腐蚀‘erosion’
Iobr=imreconstruct(Ie, I);%再重建% figure(10)
% imshow(Iobr);Iobrd=imdilate(Iobr, se);%在基于重建的开操作的结果基础上,进行腐蚀
Iobrcbr=imreconstruct(imcomplement(Iobrd), imcomplement(Iobr));%重建,标记图像为腐蚀后图像取补,模板为腐蚀前原图取补。
Iobrcbr=imcomplement(Iobrcbr);%重建结果再取补,得到实际基于重建的闭操作的结果。% figure(2)
% imshow(Iobrcbr),title('基本图像处理后所得图形');%%   图像的边缘检测
BW=edge(Iobrcbr,'sobel');
% figure(3);
% imshow(BW),title('边缘图');%%   图像中的直线检测
[x,y]=size(BW);
[H,T,R]=hough(BW,'RhoResolution',1,'Theta',-90:1:89.5);      %Hough变换
P=houghpeaks(H,10,'threshold',ceil(0.05*max(H(:))));   %查找Hough峰值
lines1=houghlines(BW,T,R,P,'FillGap',15,'MinLength',20);
L=0;
for k=1:length(lines1)
%     if lines1(k).theta<=45&&lines1(k).theta>=-45L=L+1;Lines(L).point1=lines1(k).point1;Lines(L).point2=lines1(k).point2;Lines(L).theta=lines1(k).theta;Lines(L).rho=lines1(k).rho;
%     end
end
figure(4),imshow(BW,[]),title('直线检测图');
hold on
n=length(Lines);
for i=1:nfor j=1:3color(i,j)=rand(1);end
end
for k=1:length(Lines)xy=[Lines(k).point1;Lines(k).point2];plot(xy(:,1),xy(:,2),'LineWidth',2,'color',color(k,:));
endif (L)==0return;
end
for i=1:length(Lines)A(i)=Lines(i).theta;       %A代表角度B(i)=Lines(i).rho;         %B代表极径长度x1y1(i,1:2)=Lines(i).point1;   %x1y1代表起始点的坐标x2y2(i,1:2)=Lines(i).point2;   %x2y2代表终止点的坐标
end
%合并相同的直线的不同线段
o=1;h(1:length(A))=0;
A1(1)=A(1);B1(1)=B(1);
X1Y1(1,1:2)=x1y1(1,1:2);
X2Y2(1,1:2)=x2y2(1,1:2);
for i=2:length(A)z=A(i)-A(i-1);l=B(i)-B(i-1);if (z~=0||l~=0)o=o+1;elseh(o)=h(o)+1;  %记录相同直线的个数endA1(o)=A(i);   %A1代表角度B1(o)=B(i);   %B1代表极径长度
end
z(1:17)=0;
same_number(1:length(A1))=h(1:length(A1))+1;o=0; %用same_number来接收相同直线的个数
for i=1:length(same_number)xy1(1:same_number(i),1:2)=x1y1((1+o):(same_number(i)+o),1:2);xy1(same_number(i)+1:2*same_number(i),1:2)=x2y2((1+o):(same_number(i)+o),1:2); %记录同一下直线上的所有点if A1(i)~=0for k=1:2*same_number(i)z=0;for j=1:2*same_number(i)if xy1(k,1)>=xy1(j,1)z=z+1;endendif z==2*same_number(i)X1Y1(i,1:2)=xy1(k,1:2);endendfor k=1:2*same_number(i)z=0;for j=1:2*same_number(i)if xy1(k,1)<=xy1(j,1)z=z+1;endendif z==2*same_number(i)X2Y2(i,1:2)=xy1(k,1:2);endendendif A1(i)==0for k=1:2*same_number(i)z=0;for j=1:2*same_number(i)if xy1(k,2)>=xy1(j,2)z=z+1;endendif z==2*same_number(i)X1Y1(i,1:2)=xy1(k,1:2);endendfor k=1:2*same_number(i)z=0;for j=1:2*same_number(i)if xy1(k,2)<=xy1(j,2)z=z+1;endendif z==2*same_number(i)X2Y2(i,1:2)=xy1(k,1:2);endendendo=o+same_number(i);
end%%   坐标转换for i=1:size(A1,2)if A1(i)>=0&&A1(i)<=90K(i)=tan((90-A1(i))*(pi/180));  %k_lines表示直线在直角坐标系中的斜率endif A1(i)>=-90&&A1(i)<0K(i)=tan((-90-A1(i))*(pi/180));endend%利用中点和上一个循环得到的斜率计算两直线之间的平均距离for i=1:size(A1,2)Middle(i,1)=0.5*(X1Y1(i,1)+X2Y2(i,1));Middle(i,2)=0.5*(X1Y1(i,2)+X2Y2(i,2));B(i)=Middle(i,2)-K(i)*Middle(i,1);  %b_lines代表直线的截距endfor u=1%% 判断条件1:利用角度差值初步判断两线是否平行%查找并记录近似平行的直线o=0;for i=1:length(A1)for j=i+1:length(A1)if abs(A1(i)-A1(j))<=theta_chazhi&&A1(i)>=-5&&A1(i)<=60    %根据角度的差异大小,以及角度本身的大小进行判断  o=o+1;paralleltheta_number(o,1:2)=[i,j];endendendif o==0break;endf=0;for i=1:size(paralleltheta_number,1)distance(i)=abs(B1(paralleltheta_number(i,1))-B1(paralleltheta_number(i,2)));   %计算线段之间的距离if distance(i)<=distance_max&&distance(i)>=distance_minf=f+1;Paralleltheta_number(f,1:2)=paralleltheta_number(i,1:2);endendif f==0break;end%%   判断条件2:用两条线段间的距离判断for i=1:size(Paralleltheta_number,1)a(1:2)=X1Y1(Paralleltheta_number(i,1),1:2);b(1:2)=X2Y2(Paralleltheta_number(i,1),1:2);c(1:2)=X1Y1(Paralleltheta_number(i,2),1:2);d(1:2)=X2Y2(Paralleltheta_number(i,2),1:2);middle(i,1)=0.5*(a(1)+b(1));middle(i,2)=0.5*(a(2)+b(2));middle_2(i,1)=0.5*(c(1)+d(1));middle_2(i,2)=0.5*(c(2)+d(2));point_distance(1,i)=sqrt((middle(i,1)-middle_2(i,1))^2+(middle(i,2)-middle_2(i,2))^2);  %每一对平行线的中点距离point_distance(2,i)=sqrt((a(1)-c(1))^2+(a(2)-c(2))^2);point_distance(3,i)=sqrt((b(1)-d(1))^2+(b(2)-d(2))^2);endp=0;            for i=1:size(Paralleltheta_number,1)e(i)=abs(B1(Paralleltheta_number(i,1))-B1(Paralleltheta_number(i,2)));panduan(1:3,i)=point_distance(1:3,i)-e(i);    %线段距离和中点以及端点的距离差值大小if (panduan(1,i)<=middle_point_distance_max&&panduan(1,i)>=middle_point_distance_min)||(panduan(2,i)<=boundray_point_distance_max&&panduan(2,i)>=boundray_point_distance_min)||(panduan(3,i)<=boundray_point_distance_max&&panduan(3,i)>=boundray_point_distance_min)p=p+1;Paralleltheta_number2(p,1:2)=Paralleltheta_number(i,1:2);endendif p==0break;end%% 判断条件3:判断两条直线是否有相交的情况%将线段参数中的角度theta转化为斜率k_linesfor i=1:size(Paralleltheta_number2,1)theta(i,1)=A1(Paralleltheta_number2(i,1));theta(i,2)=A1(Paralleltheta_number2(i,2));for j=1:2if theta(i,j)>=0&&theta(i,j)<=90k_lines(i,j)=tan((90-theta(i,j))*(pi/180));  %k_lines表示直线在直角坐标系中的斜率endif theta(i,j)>=-90&&theta(i,j)<0k_lines(i,j)=tan((-90-theta(i,j))*(pi/180));endendend%利用中点和上一个循环得到的斜率计算两直线之间的平均距离for i=1:size(k_lines,1)k_merge(i,1)=0.5*(k_lines(i,1)+k_lines(i,2));a(1:2)=X1Y1(Paralleltheta_number2(i,1),1:2);b(1:2)=X2Y2(Paralleltheta_number2(i,1),1:2);c(1:2)=X1Y1(Paralleltheta_number2(i,2),1:2);d(1:2)=X2Y2(Paralleltheta_number2(i,2),1:2);middle(i,1)=0.5*(a(1)+b(1));middle(i,2)=0.5*(a(2)+b(2));middle_2(i,1)=0.5*(c(1)+d(1));middle_2(i,2)=0.5*(c(2)+d(2));b_lines(i,1)=middle(i,2)-k_merge(i,1)*middle(i,1);  %b_lines代表直线的截距b_lines(i,2)=middle_2(i,2)-k_merge(i,1)*middle_2(i,1);b_distance(i,1)=(abs(b_lines(i,1)-b_lines(i,2))/sqrt(1+k_merge(i,1)^2));  %b_distance表示由虚设斜率所得两直线之间的平均距离endo=0;for i=1:size(Paralleltheta_number2,1)judge(i,1)=abs(b_distance(i,1)-abs(B1(Paralleltheta_number2(i,1))-B1(Paralleltheta_number2(i,2))));if (judge(i,1)<=parallel_judge)&&(b_distance(i,1)>=xy_distance_min)&&(b_distance(i,1)<=xy_distance_max)  %平行线判断标准o=o+1;Paralleltheta_number3(o,1:2)=Paralleltheta_number2(i,1:2);ice_thickness1(o)=b_distance(i);endendif o==1     %如果经过判断的直线组只剩下一个那么就直接输出此时的直线结果end%% 判断条件4:判断直线自身长度,以及两直线差值是否满足要求Q=0;for i=1:size(Paralleltheta_number3,1)a(1:2)=X1Y1(Paralleltheta_number3(i,1),1:2);%线段1起始点b(1:2)=X2Y2(Paralleltheta_number3(i,1),1:2);%线段1终止点c(1:2)=X1Y1(Paralleltheta_number3(i,2),1:2);%线段2起始点d(1:2)=X2Y2(Paralleltheta_number3(i,2),1:2);%线段2终止点self_distance(i,1)=sqrt((a(1)-b(1))^2+(a(2)-b(2))^2)+1;self_distance(i,2)=sqrt((c(1)-d(1))^2+(c(2)-d(2))^2)+1;self_distance_panduan(i)=abs(self_distance(i,1)/self_distance(i,2));if (self_distance(i,1)>length_min&&self_distance(i,2)>length_min)&&(self_distance_panduan(i)<length_ratio_max&&self_distance_panduan(i)>length_ratio_min)Q=Q+1;Paralleltheta_number4(Q,1:2)=Paralleltheta_number3(i,1:2);ice_thickness2(Q)=ice_thickness1(i);endend%如果经过判断的直线组只剩下一个那么就直接输出此时的直线结果if Q~=0end
end

基于hough变换的平行线识别相关推荐

  1. 【图像识别】基于 Hough变换钟表表盘识别Matlab代码

    1 简介 本设计主要针对指针式仪表的数字化读数的研究,提高读取效率和读数的准确性.以MATLAB为载体对图像进行仿真处理,通过设备采集图片,对图像进行表盘定位,图像预处理,边缘检测,Hough变换等操 ...

  2. 【表盘识别】基于Hough变换实现指针式仪表识别(倾斜矫正)

    一.简介 模型参考这里. 二.源代码 clear all; close all; clc; ​ img= imread('3.jpg'); img= rgb2gray(img); %% 归一化处理 f ...

  3. matlab人眼虹膜定位,基于Hough变换的人眼虹膜定位方法

    基于Hough变换的人眼虹膜定位方法 matlab 2021-2-12 下载地址 https://www.codedown123.com/64459.html 图像处理源代码,基于Hough变换的人眼 ...

  4. 【答题卡识别】Hough变换答题卡识别【含Matlab源码 250期】

    ⛄一.获取代码方式 获取代码方式Q: 完整代码已上传我的资源:[答题卡识别]基于matlab Hough变换答题卡识别[含Matlab源码 250期] 获取代码方式2: 付费专栏图像处理(Matlab ...

  5. Udacity无人驾驶工程师课程笔记:1 计算机视觉基础——基于Hough变换的车道线提取

    Udacity无人驾驶工程师课程笔记:1 计算机视觉基础--基于Hough变换的车道线提取 图像处理 颜色选择 区域遮罩 组合颜色和区域选择 边缘检测 Canny边缘检测 Hough变换 Hough变 ...

  6. 基于kl变换的人脸识别_简述几种人脸识别的主要方法

    人脸识别的方法很多,以下介绍一些主要的人脸识别方法.(1)几何特征的人脸识别方法几何特征可以是眼.鼻.嘴等的形状和它们之间的几何关系(如相互之间的距离).这些算法识别速度快,需要的内存小,但识别率较低 ...

  7. 基于K-L变换的人脸识别

    原理介绍 K-L变换是模式识别中常用的一种特征提取方法,出发点是从一组特征中计算出一组按重要性从大到小排列的新特征,它们是原有特征的线性组合,并且相互之间是不相关的,实现数据的降维. 在人脸识别中,可 ...

  8. 【表盘识别】基于matlab Hough变换钟表表盘识别【含Matlab源码 1069期】

    ⛄一.Hough简介 霍夫变换(Hough Transform)是图像处理中的一种特征提取技术,它通过一种投票算法检测具有特定形状的物体.该过程在一个参数空间中通过计算累计结果的局部最大值得到一个符合 ...

  9. 【答题卡识别】基于hough变换答题卡判定与成绩统计含Matlab源码

    1 简介 目前,考试阅卷使用光标阅读机进行阅卷.而教师个人及普通学校则难以承担光标阅读机高昂的购买与维护费用.如何保证计算机视觉相关技术在教育教学领域被充分应用,使教师个人,普通学校以及偏远山区的学校 ...

最新文章

  1. 欧拉筛 筛法求素数 及其例题 时间复杂度O(n)
  2. linux中根目录下各个目录的作用
  3. webpack插件机制
  4. executing an update/delete query问题
  5. Ubuntu下pip安装、升级、卸载
  6. inotifypropertychanged接受不执行_死刑立即执行很好理解,缓期2年执行是什么意思?是2年后再执行吗...
  7. 多线程中局部静态变量初始化的陷阱
  8. Dubbo是如何进行远程服务调用的?(源码流程跟踪)
  9. 工具 转_好用的语音转文字工具,总有一款适合你!
  10. 微信红包订单存储架构变迁的最佳实践
  11. Linux定时器的简单使用
  12. 利用Windows自带的Certutil查看文件MD5
  13. 组合数学6--母函数与递推关系
  14. 天津大学计算机学院课表,天津大学软件实践1汇编语言课程教学大纲-天津大学计算机学院.PDF...
  15. 【C++】DISALLOW_COPY_AND_ASSIGN
  16. mysql8 2058_SQLyog连接MySQL8.0报2058错误的解决方案
  17. 自定义封包协议c语言,Socket分包,封包,粘包
  18. 猫眼电影MySQL数据库怎么写_MySQL简要分析猫眼电影TOP100榜
  19. Rai StudiesQuick Start Site for JAVA Developers
  20. 深度学习loss函数理解

热门文章

  1. linux基础命令归纳(可读性高,易上手)
  2. 史元春和孙正兴:人机交互
  3. 量化投资分析-Tushare数据获取
  4. 猿创征文|Java中的IO流大家族 (两万字详解)
  5. CRC16_MODBUS
  6. 使用jupyter 调取arcgis中arcpy
  7. 顶会论文合集 | 联邦学习 x 计算机视觉
  8. 解决U盘感染病毒后所有文件及文件夹被隐藏的方法
  9. arcgis 分子式标注
  10. java access jdbc_JAVA软件逆向之hxtt的Access_JDBC30.jar