Разгадываем капчу в qt — 4 (метод начала и конца)

Данная статья является продолжением статьи  Разгадываем капчу в qt — 3 (метод дырки)  в прошлой статье мы без шаблонов разгадывали числа с дырками, 0 9 8 4 6, теперь без шаблонов разгадаем остальные числа 1 2 3 5 7, статья будет очень короткой так как алгоритм простой и использует лишь одну новую функцию.

Что такое метод начала и конца? — когда мы пишем цифру ручкой на листке бумаге мы где-то начинаем ее писать — где то заканчиваем, тоесть у нее есть начало и конец.

Первое что нам нужно это найти начало и конец цифры(код будет ниже) а дальше делим их по полам

startend235

2 — начало с лева, конец с права

3 — начало и конец с лева

5 — начало с права, конец с лева

элементарно)) и не нужно никаких шаблонов для сравнения

проблема у нас только с 1 и 7,  тут метод начала и конца не применишь, но отличить их можно так, у единицы ширина всегда меньше высоты\2 у семерки берем ее нижнею часть и сравниваем также как и с единицой.

И так, метод дырки+метод начала и конца, результат, я нашел только 1 ошибку но на относится к перед идущему методу, 4 назвал девяткой, тоесть можно ставить качество распознания 90% и идти улучшать алгоритм))

startend_plus_hole

Метод который ищет начало и конце, смысл такой, ищем первый попавшийся черный пиксель закрашиваем в красный, и ищем дальше, пока они не закончатся — тоесть нашли конец, после с конца закрашиваем обратно в черный, и так до конца — найдем начало.


void CapMonster::FindEndAndStart(const QImage& _img ,QPoint& start,QPoint& end){

QImage img = _img;
QColor color;
QRgb rgbRed;
QRgb rgbBlack;
color.setRgb(0,0,0);
rgbBlack = color.rgb();
color.setRgb(255,0,0);
rgbRed = color.rgb();

QList<QPoint> spt;
QSet<QPair<int,int>> uCopy;
int uCopySize;

QPoint lastTmp;

if(!FindHoleByColor(img,rgbBlack,lastTmp)){
return;
}

spt.append(lastTmp);
uCopy.insert(qMakePair(lastTmp.x(),lastTmp.y()));

//========================================
for(int i = 0;i<spt.size();i++)
{
QPoint const tmp = spt[i];
img.setPixel(tmp, rgbRed);
if(i == spt.size()-1){
lastTmp = tmp;
}
if((tmp.x() + 1) < img.width())
{
QPoint npt(tmp.x() + 1, tmp.y());

if(img.pixel(npt) == rgbBlack)
{
uCopySize = uCopy.size();

uCopy.insert(qMakePair(npt.x(),npt.y()));
if(uCopySize < uCopy.size()){
spt.append(npt);
}
}
}
if((tmp.x() - 1) > -1)
{
QPoint npt(tmp.x() - 1, tmp.y());

if(img.pixel(npt) == rgbBlack)
{
uCopySize = uCopy.size();

uCopy.insert(qMakePair(npt.x(),npt.y()));
if(uCopySize < uCopy.size()){
spt.append(npt);
}
}
}
if((tmp.y() + 1) < img.height())
{
QPoint npt(tmp.x(), tmp.y() + 1);

if(img.pixel(npt) == rgbBlack)
{
uCopySize = uCopy.size();

uCopy.insert(qMakePair(npt.x(),npt.y()));
if(uCopySize < uCopy.size()){
spt.append(npt);
}
}
}
if((tmp.y() - 1) > -1)
{
QPoint npt(tmp.x(), tmp.y() - 1);

if(img.pixel(npt) == rgbBlack)
{
uCopySize = uCopy.size();

uCopy.insert(qMakePair(npt.x(),npt.y()));
if(uCopySize < uCopy.size()){
spt.append(npt);
}
}
}
}
end = lastTmp;
//========================================
spt.clear();
uCopy.clear();
uCopySize = 0;
spt.append(lastTmp);
uCopy.insert(qMakePair(lastTmp.x(),lastTmp.y()));

for(int i = 0;i<spt.size();i++)
{
QPoint const tmp = spt[i];
img.setPixel(tmp, rgbBlack);
if(i == spt.size()-1){
lastTmp = tmp;
}

if((tmp.x() + 1) < img.width())
{
QPoint npt(tmp.x() + 1, tmp.y());

if(img.pixel(npt) == rgbRed)
{
uCopySize = uCopy.size();

uCopy.insert(qMakePair(npt.x(),npt.y()));
if(uCopySize < uCopy.size()){
spt.append(npt);
}
}
}
if((tmp.x() - 1) > -1)
{
QPoint npt(tmp.x() - 1, tmp.y());

if(img.pixel(npt) == rgbRed)
{
uCopySize = uCopy.size();

uCopy.insert(qMakePair(npt.x(),npt.y()));
if(uCopySize < uCopy.size()){
spt.append(npt);
}
}
}
if((tmp.y() + 1) < img.height())
{
QPoint npt(tmp.x(), tmp.y() + 1);

if(img.pixel(npt) == rgbRed)
{
uCopySize = uCopy.size();

uCopy.insert(qMakePair(npt.x(),npt.y()));
if(uCopySize < uCopy.size()){
spt.append(npt);
}
}
}
if((tmp.y() - 1) > -1)
{
QPoint npt(tmp.x(), tmp.y() - 1);

if(img.pixel(npt) == rgbRed)
{
uCopySize = uCopy.size();

uCopy.insert(qMakePair(npt.x(),npt.y()));
if(uCopySize < uCopy.size()){
spt.append(npt);
}
}
}
}
start = lastTmp;
}

Ну и функция для сравнения результата.


int CapMonster::StartEndMethod(const QImage& img){

if(img.width()<img.height()/2){
return 1;
}

QImage seven;
seven = img.copy(0,img.height()/3,img.width(),img.height()-img.height()/3);
seven = CropImage(seven);

if(seven.width() < img.width()/2){
return 7;
}

QPoint start,end;
FindEndAndStart(img,start,end);
int resultNumber = 5;
bool startLeftRight = 0,endLeftRight = 0;
if( start.rx() > (img.width()/2)){
startLeftRight = 1;
}
if( end.rx() > (img.width()/2)){
endLeftRight = 1;
}

if(!startLeftRight && !endLeftRight){
resultNumber = 3;
}
if(!startLeftRight && endLeftRight){
resultNumber = 2;
}
if(startLeftRight && !endLeftRight){
resultNumber = 5;
}

return resultNumber;
}

Проголосовать за статью

5 thoughts on “Разгадываем капчу в qt — 4 (метод начала и конца)

  1. Честно говоря ничего не поняла. Можно подробнее. первод у вас желает лучшего. Я скачала и не знаю что дальше делать

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *