分割验证码有啥好的方法吗
Closed this issue · 5 comments
😂😂参照你的代码写了一个golang版本的,识别一次大概200ms,只是还没想好怎么分割比较好
Wow!Cool!
以这个举例吧
◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◇◇◇◇◇◇◇◇◇◇◇◇◆◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◇◇◇◇◇◇◇◇◇◇◇◇◆◆◆◇◇◇◇◇◇◆◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◆◆◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◇◇◇◇◇◇◆◆◆◇◇◇◆◆◆◇◇◇◆◆◆◆◆◆◇◇◇◇◆◆◆◆◆◆◆◆◇◇◇◇◇◇◆◆◆◆◆◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◇◇◇◇◇◇◆◆◆◆◇◇◆◆◆◇◇◇◆◆◆◆◇◇◇◇◇◇◆◆◆◆◆◆◆◆◆◇◇◇◇◆◆◆◇◇◆◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◆◆◆◇◇◇◆◆◆◆◆◇◆◆◆◇◇◇◆◆◆◇◇◇◇◇◇◇◆◆◆◇◇◇◆◆◆◇◇◇◆◆◆◇◇◇◇◆◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◆◆◆◇◇◇◆◆◆◆◆◇◇◆◆◇◇◇◆◆◆◇◇◇◇◇◇◆◆◆◇◇◇◇◇◆◆◆◇◇◆◆◆◇◇◇◇◆◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◇◆◆◆◇◇◆◆◆◆◆◆◇◆◆◇◇◇◇◆◆◆◇◇◇◇◇◆◆◆◇◇◇◇◇◆◆◆◇◆◆◆◆◆◆◆◆◆◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◇◇◆◆◆◇◆◆◆◇◆◆◆◆◆◇◇◇◇◆◆◆◇◇◇◇◇◆◆◆◇◇◇◇◇◆◆◆◇◇◆◆◆◆◆◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◇◇◆◆◆◆◆◆◆◇◆◆◆◆◆◇◇◇◇◆◆◆◇◇◇◇◇◆◆◆◇◇◇◇◇◆◆◆◇◇◆◆◆◇◇◇◇◇◆◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◇◇◇◆◆◆◆◆◆◇◇◆◆◆◆◇◇◇◇◆◆◆◇◇◇◇◇◆◆◆◇◇◇◇◆◆◆◆◇◇◇◆◆◆◇◇◇◇◆◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◇◇◇◇◆◆◆◆◆◇◇◇◆◆◆◇◇◇◇◇◆◆◆◇◇◇◇◆◆◆◆◇◇◇◆◆◆◇◇◇◇◆◆◆◆◇◆◆◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◇◇◇◇◇◆◆◆◆◇◇◇◇◇◇◇◇◇◇◇◆◆◆◇◇◇◇◆◆◇◆◆◆◆◆◆◆◇◇◇◇◇◆◆◆◆◆◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◇◇◇◇◇◆◆◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◆◆◆◆◇◆◆◆◆◆◇◇◇◇◇◇◇◆◆◆◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◇◇◇◇◇◇◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◆◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◆◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◆◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
我觉得这里切割也处理的不是特别好,方正这边字母会旋转,切割处理不好会影响后面的识别率
程序他会把上面二值化的结果以1(有像素点),0(无像素点)存到二维数组中,首先如果数组一列的和为0那么就是空行,他从左向右切割,从上到下检查,首先从左到右,找到第一个字母的左端横坐标(也就是第一次数组一列不为零的横坐标),然后继续向右寻找第一个字母的右端横坐标,从上往下三个IF,
-
第一个是用来判断到达一个阈值以后是否应该继续向后截取(防止粘连时将两个字母当一个字母截了,)那个Estimate函数应该是用来判断向右看几格,如果几格之内找不到一个空列,就在当前位置强行截断,并记录横坐标值,
-
第二个是用来应对如果两个字母中间有一些没去掉的噪点,或者一两个点的时候,如果单纯用有没有空列判断,他会把这两个字母当一个字母截了。。。或者像1的if里面强行截断,截散了,所以这里如果字母宽度大于9了,且这一列只有两个点,就可以截断了
-
第三个是应对i和j这类,如果大于2而且出现空列,就可以直接截了
截取里面写了这三个判断,感觉自己上面说的也有些不清不楚的(早上没睡醒TAT),如果有哪里没明白可以提出来再继续讨论哈~ : P
//切割第一个字母的后竖线
`
for ($x = $tmp_x; $x < $width; ++$x) {
$num = 0;
for ($y = 0; $y < $height; ++$y) {
$num += $all[$y][$x];
}
if ($x - $tmp_x > $yz) {
if (!Estimate($x, $y, 'vertical', $all, $height)) {//判断是否应该继续截取
//如果判断向后是无法找到可以停止的参照,那么就在阈值处截断,
$end_x1 = $x;
$tmp_x = $x;
break;
}
}
if ($num <= 2 && $x - $tmp_x > 9) {//在截取的位置宽度大于9以后如果有一行只有两个点或一个点则截断
$end_x1 = $x + 1;
$tmp_x = $x + 1;
break;
}
if ($num == 0 && $x - $tmp_x > 2) {//有空行,且截取的宽度>2
$end_x1 = $x;
$tmp_x = $x;
break;
}
}
`
是的看你代码是这样的
- 1.y轴投影为0,有空隙,直接截取
- 2.大于宽度小于阈值选择附近比较稀疏的列截取
- 3.直接在阈值处截取
👍
对了,你的字典是训练出的,还是各个角度模拟出的 ⚡️
自己当人肉打码工手动调教添加的(上课拿着台电脑在那打码2333),可以看下AddDictionary.php
这个文件,比较方便的手动添加字典。
不过如果能从各种角度模拟,更有针对性的去训练它的话,可能效果更好也说不定,因为现在的字典里可能有一些冗余的数据
哦抱歉,我可能理解错你的意思,就切割这块的其他想法的话,因为也比较久了,想法上也忘得差不多了,可能给不了太多的建议,抱歉哈
不过这两天看了swoole以后我也在考虑是不是可以四个字母的对比识别用多线程并行,这样效率可能会高些吧,缩短时间
原来如此!
多线程确实可以节约3/4时间。