• 利用OCR文字识别+百度算法搜索,玩转冲顶大会、百万英雄、芝士超人等答题赢奖金游戏


    【先上一张效果图】:

    一、原理:

    其实原理很简单:

    1.手机投屏到电脑;

    2.截取投屏画面的题目部分,进行识别,得到题目和三个答案;

    3.将答案按照一定的算法,进行搜索,得出推荐答案;

    4.添加了一些其他辅助功能,比如:浏览器搜索结果展示、关键字高亮、浏览器可点击等;

    二、二营长,把我的意大利...............代码,呈上来,给友军看看

    1.手机投屏:

        方式很多,这里只列举几个比较常用、且自己感觉简单易用的:

        A.IOS:局域网内,可以利用iTools里的苹果录屏大师(airplay),进行投屏;

        B.安卓:利用连接线,可以用Totall Control,将安卓手机的画面投到电脑上;而且电脑上还能直接操作手机;

        C.模拟器:一般都是安卓模拟器;可以自行下载并安装;

    2.截取画面中的题目和答案

        A.先设置要截图的区域。

        我创建了一个窗体,专门用于设置截图区域,给它取名叫:frmCutter。

        原理:在主窗体打开frmCutter时,就将frmCutter全拼显示。同时截取一张整个屏幕的图片,把它设置成frmCutter窗体的背景图片。

    这样就能在frmCutter上自由地设置了。

        主窗体打开frmCutter窗体时:

    复制代码
     1 // 新建一个和屏幕大小相同的图片
     2 Bitmap catchBmp = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height);
     3 
     4 // 创建一个画板,让我们可以在画板上画图
     5 // 这个画板也就是和屏幕大小一样大的图片
     6 // 我们可以通过Graphics这个类在这个空白图片上画图
     7 Graphics g = Graphics.FromImage(catchBmp);
     8 
     9 // 把屏幕图片拷贝到我们创建的空白图片 catchBmp中
    10 g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height));
    11 
    12 // 创建截图窗体
    13 frmCutter _frmCutter = new frmCutter();
    14 _frmCutter.Tag = this;
    15 
    16 // 指示窗体的背景图片为屏幕图片
    17 _frmCutter.BackgroundImage = catchBmp;
    18 
    19 _frmCutter.Width = Screen.AllScreens[0].Bounds.Width;
    20 _frmCutter.Height = Screen.AllScreens[0].Bounds.Height;
    21 DialogResult dr = _frmCutter.ShowDialog();
    复制代码

        然后再frmCutter窗体中,写入几个事件:

    复制代码
      1 //点击鼠标右键时,取消设置
      2 private void frmCutter_MouseClick(object sender, MouseEventArgs e)
      3 {
      4     if (e.Button == MouseButtons.Right)
      5     {
      6         this.DialogResult = DialogResult.OK;
      7         this.Close();
      8     }
      9 }
     10 
     11 //点击鼠标左键时,开始画区域图
     12 private void frmCutter_MouseDown(object sender, MouseEventArgs e)
     13 {
     14     // 鼠标左键按下是开始画图,也就是截图
     15     if (e.Button == MouseButtons.Left)
     16     {
     17         // 如果捕捉没有开始
     18         if (!_catchStart && !_catchFinished)
     19         {
     20             _catchStart = true;
     21 
     22             // 保存此时鼠标按下坐标
     23             Point newPoint = new Point(e.X, e.Y);
     24 
     25             _downPoint = newPoint;
     26 
     27             Tools.StartPoint = newPoint;
     28         }
     29     }
     30 }
     31 
     32 //鼠标移动时,根据移动的鼠标和点击时的第一个点,绘制矩形
     33 private void frmCutter_MouseMove(object sender, MouseEventArgs e)
     34 {
     35     #region 确保截图开始
     36     if (_catchStart && !_catchFinished)
     37     {
     38         // 新建一个图片对象,让它与屏幕图片相同
     39         Bitmap copyBmp = (Bitmap)Tools.ScreenShots.Clone();
     40 
     41         // 获取鼠标按下的坐标
     42         Point newPoint = new Point(_downPoint.X, _downPoint.Y);
     43 
     44         // 新建画板和画笔
     45         Graphics g = Graphics.FromImage(copyBmp);
     46         Pen p = new Pen(Color.Red, 1);
     47 
     48         // 获取矩形的长宽
     49         int width = Math.Abs(e.X - _downPoint.X);
     50         int height = Math.Abs(e.Y - _downPoint.Y);
     51         if (e.X < _downPoint.X)
     52         {
     53             newPoint.X = e.X;
     54         }
     55         if (e.Y < _downPoint.Y)
     56         {
     57             newPoint.Y = e.Y;
     58         }
     59 
     60         _catchRectangle = new Rectangle(newPoint, new Size(width, height));
     61 
     62         Tools.CatchRectangle = new Rectangle(newPoint, new Size(width, height));
     63         Tools.CatchRectangleSize = new Size(width, height);
     64 
     65 
     66         // 将矩形画在画板上
     67         g.DrawRectangle(p, _catchRectangle);
     68 
     69         // 释放目前的画板
     70         g.Dispose();
     71         p.Dispose();
     72         // 从当前窗体创建新的画板
     73         Graphics g1 = this.CreateGraphics();
     74 
     75         // 将刚才所画的图片画到截图窗体上
     76         // 为什么不直接在当前窗体画图呢?
     77         // 如果自己解决将矩形画在窗体上,会造成图片抖动并且有无数个矩形
     78         // 这样实现也属于二次缓冲技术
     79         g1.DrawImage(copyBmp, new Point(0, 0));
     80         g1.Dispose();
     81         // 释放拷贝图片,防止内存被大量消耗
     82         copyBmp.Dispose();
     83     }
     84     #endregion
     85 }
     86 
     87 //鼠标点击后,弹起来时,完成矩形的绘制
     88 private void frmCutter_MouseUp(object sender, MouseEventArgs e)
     89 {
     90     if (e.Button == MouseButtons.Left)
     91     {
     92         // 如果截图已经开始,鼠标左键弹起设置截图完成
     93         if (_catchStart)
     94         {
     95             Tools.EndPoint = new Point(e.X, e.Y);
     96 
     97             _catchStart = false;
     98             _catchFinished = true;
     99         }
    100     }
    101 }
    102 
    103 //双击,确定当前选择的设置
    104 private void frmCutter_MouseDoubleClick(object sender, MouseEventArgs e)
    105 {
    106     if (e.Button == MouseButtons.Left && _catchFinished)
    107     {
    108         if (this.Tag != null)
    109         {
    110             frmMain _frmMain = (frmMain)this.Tag;
    111             if (_frmMain != null)
    112             {
    113                 //_frmMain.btnRead.Focus();
    114                 _frmMain.ReadImageResult();
    115             }
    116         }
    117 
    118         this.DialogResult = DialogResult.OK;
    119         this.Close();
    120     }
    121 }
    复制代码

        B.设置好截图区域后,每次题目出现时,变对该区域截图:

    复制代码
     1 //截取设置的区域屏幕图片
     2 Bitmap _screenShots = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height);
     3 // 创建一个画板,让我们可以在画板上画图
     4 // 这个画板也就是和屏幕大小一样大的图片
     5 // 我们可以通过Graphics这个类在这个空白图片上画图
     6 Graphics g_screenShots = Graphics.FromImage(_screenShots);
     7 // 把屏幕图片拷贝到我们创建的空白图片 CatchBmp中
     8 g_screenShots.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(Screen.AllScreens[0].Bounds.Width, 
      Screen.AllScreens[0].Bounds.Height)); 9 10 //剪切的图片 11 _catchBmp = new Bitmap(Tools.CatchRectangleSize.Width, Tools.CatchRectangleSize.Height); 12 Graphics g = Graphics.FromImage(_catchBmp); 13 g.DrawImage(_screenShots, new Rectangle(0, 0, Tools.CatchRectangleSize.Width, Tools.CatchRectangleSize.Height),
      Tools.CatchRectangle, GraphicsUnit.Pixel);
    14 g.Dispose(); 15 g_screenShots.Dispose(); 16 17 //显示图像 18 this.imgCut.BackgroundImage = (Image)_catchBmp;
    复制代码

        C.将截到的问题和答案图片,用OCR识别

        比如,我现在设置并截取到了这张图片:

        

        识别图片中的文字,OCR软件和API也不少。以前我用的谷歌tesseract4.0,安装在本机的,没做词库,识别率一般。

    后来发现百度OCR每天免费调用500次,果断转场!事实证明,正确率还是高很多。

        D.得到识别结果,将识别结果处理后,进行百度搜索:

        创建了一个试题实体,后面用起来就方便了:

    复制代码
     1 /// <summary>
     2 /// 试题类
     3 /// </summary>
     4 public class QuestionModel
     5 {
     6     /// <summary>
     7     /// 问题
     8     /// </summary>
     9     public string Question { get; set; }
    10 
    11     /// <summary>
    12     /// 答案1
    13     /// </summary>
    14     public string Answer1 { get; set; }
    15 
    16     /// <summary>
    17     /// 答案2
    18     /// </summary>
    19     public string Answer2 { get; set; }
    20 
    21     /// <summary>
    22     /// 答案3
    23     /// </summary>
    24     public string Answer3 { get; set; }
    25 }
    复制代码

        E.百度搜索,并显示参考答案:

        a).算法搜索:

        1.用题目去百度搜索。在搜索的结果中,查询答案出现的次数。

        2.用题目+答案去搜索。得到每个组合的百度结果个数。

        然后将上述两种方法,根据权重权衡,用户可以自行决定偏向于哪种结果。

        b).辅助搜索:

        右边还放了一个浏览器,可以在得到识别结果的第一时间,呈现出根据题目搜索百度的结果;并且在里面高亮显示3个答案关键字。

    三、坐等吃鸡!

        自动截图、自动识别、自动搜索、自动给出参考答案、自动展现出搜索页面并高亮显示关键字……

        多了一系列的辅助功能,想不吃鸡都难啊~

    (PS:热烈欢迎广大道友一起交流、指点,大家一起更上一层楼!)

    出处:https://www.cnblogs.com/donkeysmall/p/8319792.html

  • 相关阅读:
    C# 从服务器下载文件
    不能使用联机NuGet 程序包
    NPOI之Excel——合并单元格、设置样式、输入公式
    jquery hover事件中 fadeIn和fadeOut 效果不能及时停止
    UVA 10519 !! Really Strange !!
    UVA 10359 Tiling
    UVA 10940 Throwing cards away II
    UVA 10079 Pizze Cutting
    UVA 763 Fibinary Numbers
    UVA 10229 Modular Fibonacci
  • 原文地址:https://www.cnblogs.com/mq0036/p/8350744.html
Copyright © 2020-2023  润新知