這篇文章主要講解了“如何利用OCR文字識別各種圖文”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“如何利用OCR文字識別各種圖文”吧!
創(chuàng)新互聯(lián)公司是一家專業(yè)提供上海企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站建設(shè)、H5網(wǎng)站設(shè)計(jì)、小程序制作等業(yè)務(wù)。10年已為上海眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)絡(luò)公司優(yōu)惠進(jìn)行中。
【先上一張效果圖】:
一、原理:
其實(shí)原理很簡單:
1.手機(jī)投屏到電腦;
2.截取投屏畫面的題目部分,進(jìn)行識別,得到題目和三個答案;
3.將答案按照一定的算法,進(jìn)行搜索,得出推薦答案;
4.添加了一些其他輔助功能,比如:瀏覽器搜索結(jié)果展示、關(guān)鍵字高亮、瀏覽器可點(diǎn)擊等;
二、二營長,把我的意大利...............代碼,呈上來,給友軍看看
1.手機(jī)投屏:
方式很多,這里只列舉幾個比較常用、且自己感覺簡單易用的:
A.IOS:局域網(wǎng)內(nèi),可以利用iTools里的蘋果錄屏大師(airplay),進(jìn)行投屏;
B.安卓:利用連接線,可以用Totall Control,將安卓手機(jī)的畫面投到電腦上;而且電腦上還能直接操作手機(jī);
C.模擬器:一般都是安卓模擬器;可以自行下載并安裝;
2.截取畫面中的題目和答案
A.先設(shè)置要截圖的區(qū)域。
我創(chuàng)建了一個窗體,專門用于設(shè)置截圖區(qū)域,給它取名叫:frmCutter。
原理:在主窗體打開frmCutter時,就將frmCutter全拼顯示。同時截取一張整個屏幕的圖片,把它設(shè)置成frmCutter窗體的背景圖片。
這樣就能在frmCutter上自由地設(shè)置了。
主窗體打開frmCutter窗體時:
// 新建一個和屏幕大小相同的圖片
Bitmap catchBmp = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height);
// 創(chuàng)建一個畫板,讓我們可以在畫板上畫圖
// 這個畫板也就是和屏幕大小一樣大的圖片
// 我們可以通過Graphics這個類在這個空白圖片上畫圖
Graphics g = Graphics.FromImage(catchBmp);
// 把屏幕圖片拷貝到我們創(chuàng)建的空白圖片 catchBmp中
g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height));
// 創(chuàng)建截圖窗體
frmCutter _frmCutter = new frmCutter();
_frmCutter.Tag = this;
// 指示窗體的背景圖片為屏幕圖片
_frmCutter.BackgroundImage = catchBmp;
_frmCutter.Width = Screen.AllScreens[0].Bounds.Width;
_frmCutter.Height = Screen.AllScreens[0].Bounds.Height;
DialogResult dr = _frmCutter.ShowDialog();
然后再frmCutter窗體中,寫入幾個事件:
//點(diǎn)擊鼠標(biāo)右鍵時,取消設(shè)置
private void frmCutter_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
this.DialogResult = DialogResult.OK;
this.Close();
}
}
//點(diǎn)擊鼠標(biāo)左鍵時,開始畫區(qū)域圖
private void frmCutter_MouseDown(object sender, MouseEventArgs e)
{
// 鼠標(biāo)左鍵按下是開始畫圖,也就是截圖
if (e.Button == MouseButtons.Left)
{
// 如果捕捉?jīng)]有開始
if (!_catchStart && !_catchFinished)
{
_catchStart = true;
// 保存此時鼠標(biāo)按下坐標(biāo)
Point newPoint = new Point(e.X, e.Y);
_downPoint = newPoint;
Tools.StartPoint = newPoint;
}
}
}
//鼠標(biāo)移動時,根據(jù)移動的鼠標(biāo)和點(diǎn)擊時的第一個點(diǎn),繪制矩形
private void frmCutter_MouseMove(object sender, MouseEventArgs e)
{
#region 確保截圖開始
if (_catchStart && !_catchFinished)
{
// 新建一個圖片對象,讓它與屏幕圖片相同
Bitmap copyBmp = (Bitmap)Tools.ScreenShots.Clone();
// 獲取鼠標(biāo)按下的坐標(biāo)
Point newPoint = new Point(_downPoint.X, _downPoint.Y);
// 新建畫板和畫筆
Graphics g = Graphics.FromImage(copyBmp);
Pen p = new Pen(Color.Red, 1);
// 獲取矩形的長寬
int width = Math.Abs(e.X - _downPoint.X);
int height = Math.Abs(e.Y - _downPoint.Y);
if (e.X < _downPoint.X)
{
newPoint.X = e.X;
}
if (e.Y < _downPoint.Y)
{
newPoint.Y = e.Y;
}
_catchRectangle = new Rectangle(newPoint, new Size(width, height));
Tools.CatchRectangle = new Rectangle(newPoint, new Size(width, height));
Tools.CatchRectangleSize = new Size(width, height);
// 將矩形畫在畫板上
g.DrawRectangle(p, _catchRectangle);
// 釋放目前的畫板
g.Dispose();
p.Dispose();
// 從當(dāng)前窗體創(chuàng)建新的畫板
Graphics g1 = this.CreateGraphics();
// 將剛才所畫的圖片畫到截圖窗體上
// 為什么不直接在當(dāng)前窗體畫圖呢?
// 如果自己解決將矩形畫在窗體上,會造成圖片抖動并且有無數(shù)個矩形
// 這樣實(shí)現(xiàn)也屬于二次緩沖技術(shù)
g1.DrawImage(copyBmp, new Point(0, 0));
g1.Dispose();
// 釋放拷貝圖片,防止內(nèi)存被大量消耗
copyBmp.Dispose();
}
#endregion
}
//鼠標(biāo)點(diǎn)擊后,彈起來時,完成矩形的繪制
private void frmCutter_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
// 如果截圖已經(jīng)開始,鼠標(biāo)左鍵彈起設(shè)置截圖完成
if (_catchStart)
{
Tools.EndPoint = new Point(e.X, e.Y);
_catchStart = false;
_catchFinished = true;
}
}
}
//雙擊,確定當(dāng)前選擇的設(shè)置
private void frmCutter_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && _catchFinished)
{
if (this.Tag != null)
{
frmMain _frmMain = (frmMain)this.Tag;
if (_frmMain != null)
{
//_frmMain.btnRead.Focus();
_frmMain.ReadImageResult();
}
}
this.DialogResult = DialogResult.OK;
this.Close();
}
}
B.設(shè)置好截圖區(qū)域后,每次題目出現(xiàn)時,變對該區(qū)域截圖:
//截取設(shè)置的區(qū)域屏幕圖片
Bitmap _screenShots = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height);
// 創(chuàng)建一個畫板,讓我們可以在畫板上畫圖
// 這個畫板也就是和屏幕大小一樣大的圖片
// 我們可以通過Graphics這個類在這個空白圖片上畫圖
Graphics g_screenShots = Graphics.FromImage(_screenShots);
// 把屏幕圖片拷貝到我們創(chuàng)建的空白圖片 CatchBmp中
g_screenShots.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(Screen.AllScreens[0].Bounds.Width,
Screen.AllScreens[0].Bounds.Height));
//剪切的圖片
_catchBmp = new Bitmap(Tools.CatchRectangleSize.Width, Tools.CatchRectangleSize.Height);
Graphics g = Graphics.FromImage(_catchBmp);
g.DrawImage(_screenShots, new Rectangle(0, 0, Tools.CatchRectangleSize.Width, Tools.CatchRectangleSize.Height),
Tools.CatchRectangle, GraphicsUnit.Pixel);
g.Dispose();
g_screenShots.Dispose();
//顯示圖像
this.imgCut.BackgroundImage = (Image)_catchBmp;
C.將截到的問題和答案圖片,用OCR識別
比如,我現(xiàn)在設(shè)置并截取到了這張圖片:
識別圖片中的文字,OCR軟件和API也不少。以前我用的谷歌tesseract4.0,安裝在本機(jī)的,沒做詞庫,識別率一般。后來發(fā)現(xiàn)百度OCR每天免費(fèi)調(diào)用500次,果斷轉(zhuǎn)場!事實(shí)證明,正確率還是高很多。
D.得到識別結(jié)果,將識別結(jié)果處理后,進(jìn)行百度搜索:
創(chuàng)建了一個試題實(shí)體,后面用起來就方便了:
///
/// 試題類
///
public class QuestionModel
{
///
/// 問題
///
public string Question { get; set; }
///
/// 答案1
///
public string Answer1 { get; set; }
///
/// 答案2
///
public string Answer2 { get; set; }
///
/// 答案3
///
public string Answer3 { get; set; }
}
E.百度搜索,并顯示參考答案:
a).算法搜索:
1.用題目去百度搜索。在搜索的結(jié)果中,查詢答案出現(xiàn)的次數(shù)。
2.用題目+答案去搜索。得到每個組合的百度結(jié)果個數(shù)。
然后將上述兩種方法,根據(jù)權(quán)重權(quán)衡,用戶可以自行決定偏向于哪種結(jié)果。
b).輔助搜索:
右邊還放了一個瀏覽器,可以在得到識別結(jié)果的第一時間,呈現(xiàn)出根據(jù)題目搜索百度的結(jié)果;并且在里面高亮顯示3個答案關(guān)鍵字。
三、坐等吃雞!
自動截圖、自動識別、自動搜索、自動給出參考答案、自動展現(xiàn)出搜索頁面并高亮顯示關(guān)鍵字……
多了一系列的輔助功能,想不吃雞都難啊~
感謝各位的閱讀,以上就是“如何利用OCR文字識別各種圖文”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對如何利用OCR文字識別各種圖文這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!