├── .gitattributes ├── .gitignore └── main1.cpp /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # ========================= 18 | # Operating System Files 19 | # ========================= 20 | 21 | # OSX 22 | # ========================= 23 | 24 | .DS_Store 25 | .AppleDouble 26 | .LSOverride 27 | 28 | # Icon must end with two \r 29 | Icon 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear on external disk 35 | .Spotlight-V100 36 | .Trashes 37 | 38 | # Directories potentially created on remote AFP share 39 | .AppleDB 40 | .AppleDesktop 41 | Network Trash Folder 42 | Temporary Items 43 | .apdisk 44 | -------------------------------------------------------------------------------- /main1.cpp: -------------------------------------------------------------------------------- 1 | #include "opencv2/highgui/highgui.hpp" 2 | #include "opencv2/imgproc/imgproc.hpp" 3 | #include 4 | #include 5 | using namespace cv; 6 | using namespace std; 7 | 8 | string hehe[100]={"time_0.jpg","time_1.jpg","time_2.jpg","time_3.jpg","time_4.jpg", 9 | "time_5.jpg","time_6.jpg","time_7.jpg","time_8.jpg","time_9.jpg",}; 10 | 11 | //----------------------------------------------------------------------------- 12 | //平面几何相关函数http://www.cnblogs.com/zjutlitao/p/3243883.html 13 | //----------------------------------------------------------------------------- 14 | #define eps 0.0000000001 15 | #define PI acos(-1.0) 16 | int dcmp(double x){ 17 | if(fabs(x)0)return Length(v3); 34 | else return fabs(Cross(v1,v2))/Length(v1); 35 | } 36 | //----------------------------------------------------------------------------- 37 | class MyLine{ 38 | public: 39 | int id;//编号 40 | int k;//倾斜角[0-360) 41 | int l;//长度 42 | public: 43 | MyLine(int ID=0,int K=0,int L=0){id=ID,k=K,l=L;}//构造函数 44 | bool operator<(const MyLine &A){return ktemp-->dst(src为原图;temp是src经canny提取边缘的图, 54 | //用于下面霍夫变换;dst是最终结果图,要在temp灰度图的基础上变为彩色图才能呈现画线效果) 55 | 56 | Canny(src, temp, 10, 140, 3);//提取边缘(如果不边缘提取就会浪费巨大时间) 57 | cvtColor(temp, dst, CV_GRAY2BGR);//将边缘提取的灰度图转换为BGR图便于画线 58 | 59 | 60 | //储存检测圆的容器 61 | std::vector circles; 62 | //调用Hough变换检测圆 63 | //参数为:待检测图像,检测结果,检测方法(这个参数唯一),累加器的分辨率,两个圆间的距离,canny门限的上限(下限自动设为上限的一半),圆心所需要的最小的投票数,最大和最小半径 64 | HoughCircles(temp,circles,CV_HOUGH_GRADIENT,2,50,200,100,100,300); 65 | //找出圆盘(因为最大的不一定是的,所以加了几个限制条件) 66 | int pos=0; 67 | int max=-1; 68 | for(size_t i = 0; i < circles.size(); i++ ) 69 | { 70 | Vec3f f=circles[i]; 71 | if(f[2]>max && f[0]+f[2]=0 && f[1]+f[2]0) 72 | { 73 | max=f[2]; 74 | pos=i; 75 | } 76 | } 77 | Point center(circles[pos][0],circles[pos][1]);//找到的圆心 78 | int radius= circles[pos][2];//找到的半径 79 | circle(dst,center,radius,Scalar(255),2); 80 | 81 | list list_MyLine; 82 | vector lines2;//线段检测 83 | HoughLinesP(temp, lines2, 1, CV_PI/180, 50, 50, 10 ); 84 | for( size_t i = 0; i < lines2.size(); i++ ) 85 | { 86 | Vec4i l = lines2[i]; 87 | Point A(l[0], l[1]),B(l[2], l[3]); 88 | if(DistancetoSegment(center,A,B)<30)//根据圆心到指针的距离阈值滤掉其他线段 89 | { 90 | bool down=(A.y+B.y-2*center.y>0);//判断长的在过圆心的水平线上部还是下部 91 | if(A.x==B.x){//斜率为无穷的情况 92 | list_MyLine.push_back(MyLine(i,90+(down?180:0),Length(Point(A.x-B.x,A.y-B.y)))); 93 | }else if(A.y==B.y){//水平的情况 94 | list_MyLine.push_back(MyLine(i,A.x+B.x-2*center.x>0 ? 0:180,Length(Point(A.x-B.x,A.y-B.y)))); 95 | }else{ 96 | if(down){ 97 | if(A.y>center.y) 98 | list_MyLine.push_back(MyLine(i,360-atan2(A.y-B.y,A.x-B.x)*180/PI,Length(Point(A.x-B.x,A.y-B.y)))); 99 | else 100 | list_MyLine.push_back(MyLine(i,360-atan2(B.y-A.y,B.x-A.x)*180/PI,Length(Point(A.x-B.x,A.y-B.y)))); 101 | }else{ 102 | if(A.y10)//两个角度之差小于10°的算是同一类 129 | { 130 | if(num!=0){//对本组的度数和长度求平均 131 | Du[num-1]/=t_num; 132 | Le_ping[num-1]/=t_num; 133 | Le[num-1]=Le_ping[num-1]*0.2+Le_max[num-1]*0.8; 134 | } 135 | if(now_k==888)break;//右边界直接跳出 136 | t_num=0;//重新统计下一组 137 | num++;//组数增加1 138 | cout<<"---------------------------\n";//输出分割线 139 | } 140 | t_num++;//组内多一条线 141 | Du[num-1]+=now_Line.k; 142 | Le_ping[num-1]+=now_Line.l; 143 | if(now_Line.l>Le_max[num-1])Le_max[num-1]=now_Line.l; 144 | now_Line.print(); 145 | list_MyLine.pop_front(); 146 | pre_k=now_k; 147 | } 148 | cout<<"---------------------------\n\n"; 149 | 150 | cout<<"---------------------------\n"; 151 | int t; 152 | for(int i=0;iLe[j]){ 155 | t=Le[i],Le[i]=Le[j],Le[j]=t; 156 | t=Du[i],Du[i]=Du[j],Du[j]=t; 157 | }//if end 158 | }//for end 159 | }//for end 160 | char s[3][10]={"hour :","minute:","second:"}; 161 | for(int i=0;i