1. 程式人生 > >【程序員的吃雞大法】利用OCR文字識別+百度算法搜索,玩轉沖頂大會、百萬英雄、芝士超人等答題贏獎金遊戲

【程序員的吃雞大法】利用OCR文字識別+百度算法搜索,玩轉沖頂大會、百萬英雄、芝士超人等答題贏獎金遊戲

amp lec ios 結果 round 去百度 方式 英雄 oid

【先上一張效果圖】:

技術分享圖片

一、原理:

其實原理很簡單:

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:熱烈歡迎廣大道友一起交流、指點,大家一起更上一層樓!)

2018.01.25.

【程序員的吃雞大法】利用OCR文字識別+百度算法搜索,玩轉沖頂大會、百萬英雄、芝士超人等答題贏獎金遊戲