由于非常熟悉native C开发,学习Python的过程中还老是忘不了Qt, 准备用Qt产生训练样本。而后,使用Qt的GUI在后台调用python进行实验。当然,这个路子已经Out了,现在不少人转去pytorch, 还有朋友在用PaddlePaddle飞桨做实验。不过对比了类似的API,我认为Tensorflow 2作为一个实验工具也是足够用。
1. 生成训练样本
使用Qt QImage直接进行验证码绘图。相关代码见
/coloreaglestdio/qtfnn_kits/-/tree/master/mixnn_example
QImage img(pic_width,pic_height,QImage::Format_RGB888);//QColor cBk(rand()%32+168,rand()%64+128,rand()%54+128);QColor cBk(255,255,255);img.fill(cBk);QPainter painter(&img);//产生干扰图象QVector<QRectF> bounds;QVector<int> charids;const int lines = rand()%64+1;for (int j=0;j<lines;j++){QPen pl = QPen(QBrush(QColor(rand()%64+128,rand()%64+128,rand()%16+16,192)),rand()%4);painter.setPen(pl);const int x1 = rand()% pic_width;const int y1 = rand()% pic_height;const int x2 = x1 + rand()% 64 - 32;const int y2 = y1 + rand()% 64 - 32;if (j<4)painter.drawLine(x1,y1,x2,y2);elsepainter.drawPoint(x1,y1);}//绘制文字for (int j=0;j<char_words;++j){const char * fontfm[] = {"DejaVu Serif","Microsoft Sans Serif","Courier New","Trebuchet MS"};QFont serifFont(fontfm[rand()%4], rand()%12+20, QFont::Normal);painter.setFont(serifFont);painter.setPen(QColor(rand()%32+32,rand()%64,rand()%64));QString str;const int cid = rand() % total_chars;charids.push_back(cid);str.push_back(vch[cid]);const double seed = pic_width / (char_words+0.3);//计算中心const int center_x = j*seed+seed*0.75+rand() % 20 - 10, center_y = pic_height/2 + rand() % 8 -4;painter.translate(center_x,center_y);painter.rotate(rand() % 30 - 15); // 第2步: 旋转一定角度QRectF brec;painter.drawText(QRectF(-seed/2,-pic_height/2,seed,pic_height), Qt::AlignCenter, str,&brec);// 第3步: 绘制文字painter.resetTransform(); // 第4步: 恢复坐标旋转painter.setBrush(Qt::NoBrush);brec.setX(brec.x()-4);brec.setWidth(brec.width()+2);brec.translate(center_x,center_y);painter.drawRect(brec);bounds.push_back(brec);}img.save(fm_split+".png");
输入Trainning Feature Dir, 并勾选“Also make chars”同时生成字符的训练样本。在Make Samples里输入要生成的样本个数,start里选择样本起点,可以不断增加样本。点击按Make开始生成。
这样生成的样本图片类似(已经框选了文字的外接矩形):
为训练准备十万组样本,为测试准备1000组。
2. 识别原理
使用两个模型来完成识别。模型1用来切割锁定5个字符的外接矩形,输出每个字符的坐标。模型2用于对字符进行识别。
模型1的结构定义
模型2的结构定义
模型可以直接使用minxx_gui加载。
3.训练过程
在训练界面里,选择与模型对应的样本文件夹,而后直接训练。
十万组数据,进行模型1 训练。这里注意因为不是分类,而是坐标输出,所以只看loss就可以了。
34/40 [========================>.....] - ETA: 0s - loss: 2.7917e-04 - accuracy: 0.797835/40 [=========================>....] - ETA: 0s - loss: 2.8035e-04 - accuracy: 0.799136/40 [==========================>...] - ETA: 0s - loss: 2.7921e-04 - accuracy: 0.801237/40 [==========================>...] - ETA: 0s - loss: 2.7967e-04 - accuracy: 0.804138/40 [===========================>..] - ETA: 0s - loss: 2.7937e-04 - accuracy: 0.802639/40 [============================>.] - ETA: 0s - loss: 2.7858e-04 - accuracy: 0.802940/40 [==============================] - ETA: 0s - loss: 2.7870e-04 - accuracy: 0.806240/40 [==============================] - 5s 125ms/step - loss: 2.7870e-04 - accuracy: 0.8062Save Model to code_rect_Saved/Model/weights.ckpt
再对模型2进行训练
28/32 [=========================>....] - ETA: 0s - loss: 7.4408e-05 - accuracy: 1.000029/32 [==========================>...] - ETA: 0s - loss: 7.5170e-05 - accuracy: 1.000030/32 [===========================>..] - ETA: 0s - loss: 7.5220e-05 - accuracy: 1.000031/32 [============================>.] - ETA: 0s - loss: 7.5259e-05 - accuracy: 1.000032/32 [==============================] - ETA: 0s - loss: 7.4850e-05 - accuracy: 1.000032/32 [==============================] - 2s 78ms/step - loss: 7.4850e-05 - accuracy: 1.0000Save Model to code_char_Saved/Model/weights.ckpt
4. 应用效果
在模型收敛后,直接测试识别分割、分类效果。可见,模型正确识别了 VRI64的字符。
5. 后续
后续我们准备尝试PyTorch、飞桨等不同的平台,以及CNN之外的模型,如进行句法的识别。
如果觉得《机器学习小试(11)验证码识别测试-使用Qt与Tensorflow2进行深度学习实验》对你有帮助,请点赞、收藏,并留下你的观点哦!