Создание помощника в преферанс. Этап второй: распознавание достоинства


Список статей цикла:
  1. Этап первый: план разработки
  2. Этап второй: распознавание достоинства
  3. Этап третий: распознавание масти
Итак, сегодня мы научимся определять достоинство карты. Как я уже писал в предыдущей статье, для распознавания используем библиотеку tessnet2. Однако, перед тем как распознать карту, надо сначала получить её изображение. Метод scr снимает скриншот экрана и сохраняет изображение в случайный файл.

public void scr()
    {
        Bitmap prt = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
        Graphics graphics = Graphics.FromImage(prt as Image);
        graphics.CopyFromScreen(0, 0, 0, 0, prt.Size);
        Random rnd = new Random();
        int rr = rnd.Next(100000);
        sk = Convert.ToInt32(DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds)+rr;
        prt.Save(path + sk + ".png", System.Drawing.Imaging.ImageFormat.Png);
    }
Весь код в методе стандартный, комментировать что-то нет смысла. Единственно, на что обращу ваше внимание, так это на то, что используем для сохранения изображения формат именно png - так получается качественная и четкая картинка. Сначала я как-то не обратил внимания на это и сохранял в jpg - в результате получались скриншоты экрана даже с идентичными картами в разных цветах, с размытыми границами - в общем, не самого лучшего качества. Переменная path - это путь, где будут ваши скрины.

скриншот экрана для помощника в преферанс
рис 1: скриншот экрана для помощника в преферанс

Также нам потребуется метод, обрезающий скриншот по заданным координатам. Почему бы не обрезать сразу в методе создания скрина, спросите вы? Потому, что скрин нужен нам не один раз, отвечу я.

private static Image cropImage(Image img, Rectangle cropArea)
     {
        Bitmap bmpImage = new Bitmap(img);
        return bmpImage.Clone(cropArea, bmpImage.PixelFormat);
    }
обрезанная десятка
рис 2: обрезанная десятка

Вот теперь можно перейти и непосредственно к распознаванию. Метод для первой карты:

private void otob()
    {
        scr();//получаем скриншот
        Image im = Image.FromFile(path + sk + ".png");//инициализируем файл изображения
        int x = 12, y = 528, wid = 14, hey = 22;//задаем координаты для обрезки
        Image im2 = cropImage(im, new Rectangle(x, y, wid, hey));//обрезаем
        im2.Save(path + sk + "-m.png", System.Drawing.Imaging.ImageFormat.Png);//сохраняем новое обрезанное
        
		//работа по распознаванию
		Ocr ocr = new Ocr();
        Bitmap bmpImage = new Bitmap(path + sk + "-m.png");
        tessnet2.Tesseract tessocr = new tessnet2.Tesseract();
        tessocr.SetVariable("tessedit_char_whitelist", "01789AJKQ");
        tessocr.Init(null, "eng", false);
        List<tessnet2.Word> text = ocr.DoOCRNormal((Bitmap)bmpImage, "eng");
        
		//далее идет обработка и отображение, мы работаем с text[0].Text
        string zn = text[0].Text;
        if (zn!="10") zn = zn.Substring(0, 1);
        if (zn == "J") zn = "В";
        if (zn == "Q") zn = "Д";
        if (zn == "K") zn = "К";
        if (zn == "A") zn = "Т";

        string ms = mast(10, 549, 15, 15, false, pictureBox10); //определяем масть
        soot(ms, zn, 1); //соответствие
        pokazvishedshih(1);//вывод на экран
        }
Собственно, ничего сложного в этом методе и нет - комментарии довольно подробные. Подключаем белый список из некоторых цифр и букв, а затем переводим в русские. Вот исходный код класса Ocr:

public class Ocr
    {
        public List<tessnet2.Word> DoOCRNormal(Bitmap image, string lang)
        {
            tessnet2.Tesseract ocr = new tessnet2.Tesseract();
            ocr.Init(null, lang, false);
            List<tessnet2.Word> result = ocr.DoOCR(image, Rectangle.Empty);
            return result;
        }
    }	
Некоторые карты необходимо переворачивать перед распознаванием, так как верхняя часть с достоинством закрывается другой.

перевернутая семерка
рис 3: перевернутая семерка

Никаких проблем это нам не доставит, просто в метод otob для таких карт добавим строчку, переворачивающую изображение на 180 градусов:

bmpImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
Не забываем подключить ссылку на tessnet2_64.dll в обозревателе решений. Напомню, что работу мы ведем в Microsoft Visual C# 2010. В заключение этой статьи отмечу, что dll для 32-х и 64-х разрядных систем отличаются - следует подключать именно ту tessnet2, которая подходит для вашей системы. В следующих статьях мы определим масть и сделаем еще кое-что.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегистатьи IT, распознавание, карты, tessnet2, преферанс




Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.




Работа с джойстиком в C#: часть 1
Разница между PHP и С#
Урок 32. Функции JavaScript: return