p2.png现在用好之上过程记录下来。

题目:方格分割

  学习验证码快一个星期了,终于将样本集切出来了,现在题材是怎么样切粘连字符,现在将自己之就学过程记录下来;

6×6底方格,沿着格子的边线剪开成为稀片段。
求这片组成部分的样完全相同。

  第一部分:

如图:p1.png, p2.png, p3.png 就是中的分割法。

脚很可怜有转自http://drops.wooyun.org/tips/141;感谢原作者。

试计算:
概括这3种分法在内,一共来微微种不同之分割方法。
顾:旋转对如的属同一栽分割法。

俺们知道,对于未黏连的字符,直接用扫描线分割法就可,就是看啦一个竖条上从未有过文字像素,则这竖条就是有限独字符间的空域部分;

请提交该整数,不要填写任何多余的情节还是说明文字。

当然,对于未黏连的字符,CFS算法效果啊非常好,它至关重要是使并通域进行私分;

图片 1图片 2图片 3

再有CFS4D的计,他独自扫描上下横4单如从判断是否也实的并通域;


若CFS则是将他方圆的8个像从判断的。

 

 

一致开始思念的凡本在一个方一个方搜索,但是没考虑到dfs只能是平等笔画画!!!所以样例的持有情况还未曾考虑到脚是自比赛的下写的代码(知道结果的时候还是比较悲伤的,花了特别把的日最后还是入坑了
 哎  还是有待锻炼啊~~!!!):

对此每次字符大小和数目还同样的验证码还得据此平均分割法,也就是直接先管中的字有完全切下,然后按涨幅平均分为几卖,这种方法对字符粘连于多为此别样措施不好划分的验证码很有因此

<↓↓↓这个代码是蹭的啊!!!只是自我比赛时写的~~可以略过>

 

 1 #include<stdio.h>
 2 #include<math.h>
 3 #include<ctype.h>
 4 #include<string.h>
 5 #include<stdlib.h>
 6 
 7 int aa[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
 8 int line[10][10];
 9 struct data {
10     int dis[6][6];
11 }vis[10000];
12 int sum;
13 void dfs(int x,int y,int n)
14 {
15     n++;
16     int i,j;
17     if(n>=18){
18         for(i=0;i<6;i++){
19             for(j=0;j<6;j++){
20                 vis[sum].dis[i][j]=line[i][j];
21                 //printf("%d ",line[i][j]);
22             }
23             //printf("\n");
24         }
25         //system("pause");
26         sum++;
27         return ;
28     }
29     int a,b;
30     for(i=0;i<4;i++){
31         a=x+aa[i][0];
32         b=y+aa[i][1];
33         if(a>=0&&a<6&&b>=0&&b<6&&line[a][b]==-1){
34             line[a][b]=1;
35             line[5-a][5-b]=0;
36             dfs(a,b,n);
37             line[a][b]=-1;
38             line[5-a][5-b]=-1;
39         }
40     }
41     return ;
42 }
43 int main ()
44 {
45     memset(line,-1,sizeof(line));
46     sum=0;
47     line[0][0]=1;
48     line[5][5]=0;
49     dfs(0,0,0);
50     int i,j,k,l,num=0;
51     for(i=0;i<sum;i++){
52         int yy=0;
53         for(j=i+1;j<sum;j++){
54             int y=1;
55             for(k=0;k<6;k++){
56                 for(l=0;l<6;l++){
57                     if(vis[i].dis[k][l]!=vis[j].dis[k][l]){
58                         y=0;
59                         break;
60                     }
61                 }
62                 if(y==0)
63                     break;
64             }
65             if(y==1){
66                 yy=1;
67                 break;
68             }
69         }
70         if(yy==0){
71             for(k=0;k<6;k++){
72                 for(l=0;l<6;l++){
73                     printf("%d ",vis[i].dis[k][l]);
74                 }
75                 printf("\n");
76             }
77             system("pause");
78             num++;
79         }
80     }
81     printf("%d %d %d\n",sum,num,num/2);//sum为所有搜到的结果,num是去重之后的结果,因为num里面还没有考虑到左下和右上对称的情况,所以最后结果应对二取商
82     return 0;
83 }//最后结果是:45

对来有限重组但是只是当字符边角的地方重叠几个像从的验证码,可以用垂直像素直方图的统计方式分割。就是本着各国一个竖条,统计该竖条上起的像素数(当然,前提要是二值化的希冀)

 

还有滴水算法;

新生以网上看看一个大牛写的解题报告,思路要就是是寻觅他的切割线,把他的各个种状况的切割线搜下,虽然方块不是同一画画,但是他的切割线肯定是一个相同笔画画什么(一刀子两快儿

 

),而且各一样种植切割线都见面透过中间的怪点(肯定什么!!(3,3)和(4,4)肯定不以跟一个块儿里面啊~~~所以切割线肯定会经过他们附近的非常点),切割线应该由中心开始搜,而且一旦找到边线(就是都拿方分成两组成部分了)就可以结束,从中间开始搜第一步有四只样子,而且擅自一个方向反转一下还得获任何一个势头的有所情况,所以下边线搜索的结果最后当除以/4,下面是于网上搜到的代码:出自http://blog.csdn.net/y1196645376/article/details/69718192/

http://drops.wooyun.org/tips/141

 1 #include <algorithm>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <stdio.h>
 5 #include <string>
 6 #include <vector>
 7 #include <queue>
 8 #include <map>
 9 #include <set>
10 using namespace std;
11 const int N = 6;
12 int ans = 0;
13 int mpt[N+1][N+1];
14 int dir[4][2] = {0,1,1,0,0,-1,-1,0};
15 void dfs(int x,int y)
16 {
17     if(x == 0 || y == 0 || x == N || y == N){
18         int i,j;
19         ans ++;
20         return;
21     }
22     for(int i = 0 ; i < 4 ; i ++)
23     {
24         int tx = x + dir[i][0];
25         int ty = y + dir[i][1];
26         if(mpt[tx][ty])continue;
27         mpt[tx][ty] = 1;
28         mpt[N-tx][N-ty] = 1;
29         dfs(tx,ty);
30         mpt[tx][ty] = 0;
31         mpt[N-tx][N-ty] = 0;
32     }
33 }
34 int main()
35 {
36     mpt[N/2][N/2] = 1;
37     dfs(N/2,N/2);
38     printf("%d\n",ans/4);
39     return 0;
40 }最后结果 509

直达半有是垂直像素直方图的一样种植直观展示,假如图片宽度为100如从,则将图片切割为100独1像素的竖线,下面的革命部分吗目前x坐标上拥有黑色像从的总和。这么一来可以好易之通过直方图的波峰波谷把4独假名分割开。图片的下半部分是扫描线分隔法,因为干扰线和字符旋转的是,只有M和5直接才起了连的空白部分。

然看看是代码之后也,感觉要多少问题,从中间开始查找,有四只样子,最后结果除以四,但是当各个一个大方向中为会见发生有对称的啊例如下图啊假设同一从头的时刻打着力的点往右走,就好博这点儿种同等不等的分割线(所以倍感要时有发生问题之,有待更新吧,也许是本人着想的物多矣吧):

 

图片 4     图片 5

除却垂直像素直方图,还可以起不同的角度展开倾斜线方向的比如说素数投影,这种措施对于每次全体字符都随意向一个角度旋转的验证码功能很好。

 

 

此外对花的验证码,还足以为此颜色分割

 

作为验证码识别里的难题,分割字符还有特别多种算法,包括笔画分析曲线角度分析等等,不过即便如此,对成的比较厉害的字符还是死麻烦成功的

 

光复随机旋转的字符一般采取的凡转卡壳算法:

 

此算法非常简单,对同一摆放图纸左右各级转30渡过的范围,每次1度过,旋转后之所以扫描线法判断字符的升幅,对于规范的长方形字体,在全垂直的早晚一定是开间最狭窄的。嗯?纳尼?上面的图是高中级的顶窄小?好像真的是如此,不过假如每次转后底结果还同一,对于识别率不见面生影响。

掉还原的算法比较蛋疼,效果呢不怎么样(其实自己不见面),不过要识别算法好之言语,对回的字符只要人数会认下,识别率也得达标近似人类的水准。

 第二片:

    锐化 & 平滑:
 图像平滑往往要图像遭到之分界、轮廓变得模糊,为了削减当下类不利效果的震慑,这虽得运用图像锐化技术,使图像的边缘变的清。图像锐化处理的目的是为要图像的边缘、轮廓线和图像的底细变的一清二楚。

    

  题外话:

    今天编码的时刻起多细节问题,处理不好,一臻亲手即开码字,编了一造译才意识众多图纸序号问题不对,然后各种修改,原本清晰地代码被移之急转直下,哎,岂是一个心累能达的,教训:以后编码之前如果出彩想想一下,细节的拍卖,最好可以形容个大致的框架下,这样避免多细节问题恶化,甚至影响整思路。

相关文章