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

【先上一张效果图】:

 

一、原理:

其实原理很简单:

1.手机投屏到电脑;

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

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

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

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

1.手机投屏:

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

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

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

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

 

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

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

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

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

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

    主窗体打开frmCutter窗体时:

// 新建一个和屏幕大小相同的图片

Bitmap catchBmp = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height);


// 创建一个画板,让我们可以在画板上画图

// 这个画板也就是和屏幕大小一样大的图片

// 我们可以通过Graphics这个类在这个空白图片上画图

Graphics g = Graphics.FromImage(catchBmp);


// 把屏幕图片拷贝到我们创建的空白图片 catchBmp中

g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height));


// 创建截图窗体

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窗体中,写入几个事件:

//点击鼠标右键时,取消设置

private void frmCutter_MouseClick(object sender, MouseEventArgs e)

{

    if (e.Button == MouseButtons.Right)

    {

        this.DialogResult = DialogResult.OK;

        this.Close();

    }

}


//点击鼠标左键时,开始画区域图

private void frmCutter_MouseDown(object sender, MouseEventArgs e)

{

    // 鼠标左键按下是开始画图,也就是截图

    if (e.Button == MouseButtons.Left)

    {

        // 如果捕捉没有开始

        if (!_catchStart && !_catchFinished)

        {

            _catchStart = true;


            // 保存此时鼠标按下坐标

            Point newPoint = new Point(e.X, e.Y);


            _downPoint = newPoint;


            Tools.StartPoint = newPoint;

        }

    }

}


//鼠标移动时,根据移动的鼠标和点击时的第一个点,绘制矩形

private void frmCutter_MouseMove(object sender, MouseEventArgs e)

{

    #region 确保截图开始

    if (_catchStart && !_catchFinished)

    {

        // 新建一个图片对象,让它与屏幕图片相同

        Bitmap copyBmp = (Bitmap)Tools.ScreenShots.Clone();


        // 获取鼠标按下的坐标

        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();

        // 从当前窗体创建新的画板

        Graphics g1 = this.CreateGraphics();


        // 将刚才所画的图片画到截图窗体上

        // 为什么不直接在当前窗体画图呢?

        // 如果自己解决将矩形画在窗体上,会造成图片抖动并且有无数个矩形

        // 这样实现也属于二次缓冲技术

        g1.DrawImage(copyBmp, new Point(0, 0));

        g1.Dispose();

        // 释放拷贝图片,防止内存被大量消耗

        copyBmp.Dispose();

    }

    #endregion

}


//鼠标点击后,弹起来时,完成矩形的绘制

private void frmCutter_MouseUp(object sender, MouseEventArgs e)

{

    if (e.Button == MouseButtons.Left)

    {

        // 如果截图已经开始,鼠标左键弹起设置截图完成

        if (_catchStart)

        {

            Tools.EndPoint = new Point(e.X, e.Y);


            _catchStart = false;

            _catchFinished = true;

        }

    }

}


//双击,确定当前选择的设置

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.设置好截图区域后,每次题目出现时,变对该区域截图:

//截取设置的区域屏幕图片

Bitmap _screenShots = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height);

// 创建一个画板,让我们可以在画板上画图

// 这个画板也就是和屏幕大小一样大的图片

// 我们可以通过Graphics这个类在这个空白图片上画图

Graphics g_screenShots = Graphics.FromImage(_screenShots);

// 把屏幕图片拷贝到我们创建的空白图片 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识别

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

    

    识别图片中的文字,OCR软件和API也不少。以前我用的谷歌tesseract4.0,安装在本机的,没做词库,识别率一般。后来发现百度OCR每天免费调用500次,果断转场!事实证明,正确率还是高很多。

 

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

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

/// <summary>

/// 试题类

/// </summary>

public class QuestionModel

{

    /// <summary>

    /// 问题

    /// </summary>

    public string Question { get; set; }


    /// <summary>

    /// 答案1

    /// </summary>

    public string Answer1 { get; set; }


    /// <summary>

    /// 答案2

    /// </summary>

    public string Answer2 { get; set; }


    /// <summary>

    /// 答案3

    /// </summary>

    public string Answer3 { get; set; }

}

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

    a).算法搜索:

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

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

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

    b).辅助搜索:

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

 

三、坐等吃鸡!

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

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

原文地址:https://www.cnblogs.com/donkeysmall/p/8319792.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/322243.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Sentinel(二十)之Envoy RLS Token Server

转载自 Envoy RLS Token Server Sentinel 提供了一个 Envoy Global Rate Limiting gRPC Service 的实现 sentinel-cluster-server-envoy-rls&#xff0c;借助集群限流 token server 来为 Envoy 服务网格提供集群流量控制的能力。 Note: You can refer to here for the Englis…

g4e基础篇#5 创建分支和保存代码

使用版本控制系统最常见的工作流程就是修改代码&#xff0c;保存代码&#xff0c;共享代码。Git提供了一个简单的3步工作流&#xff0c;让你方便的完成这些操作。1. 新建工作分支2. 提交更改3. 推送分支到中心存储库与团队成员共享Git 工作流按照以上3步操作&#xff0c;我们就…

P3952-时间复杂度【模拟】

正题 题目链接:https://www.luogu.org/problemnew/show/P3952 题目大意 比较复杂就直接给截图了 解题思路 开一个栈来维护序列&#xff0c;因为它保证合法的程序中一个变量不会相互嵌套所以就拿变量的字母当做每个循环的下标即可。然后对于输入的x,yx,yx,y有五种情况 xN,yN…

一步步部署基于Windows系统的Jenkins持续集成环境

如题&#xff1a;本文将介绍如何在Windows环境下运用Jenkins部署持续集成环境。之所以写本文&#xff0c;是因为在最近工作当中&#xff0c;学习使用Jenkins时&#xff0c;确实遇到了一些问题&#xff0c;而大多数教程文档都是基于Mac或是Linux平台。为此很是头疼&#xff0c;经…

Sentinel(二十二)之使用Nacos存储规则

转载自 Spring Cloud Alibaba基础教程&#xff1a;Sentinel使用Nacos存储规则 通过上一篇《使用Sentinel实现接口限流》的介绍&#xff0c;相信大家对Sentinel已经有了初步的认识。在Spring Cloud Alibaba的整合封装之下&#xff0c;接口限流这件事情可以非常轻易的整合到我们…

vue 开发2017年变化回顾及2018年展望

vue.js 变化从 github 的发布记录我们可以看到2017年 vue.js 的第一个发布为 v2.1.9&#xff0c;最后一个为 v2.5.13&#xff0c;主要发布小版本 2.2~2.5。这些发布提升了vue 与 TypeScript 的结合、改进了对服务端渲染&#xff08;SSR&#xff09;和 native 渲染的支持、提供了…

Sentinel(二十三)之使用Apollo存储规则

转载自 Spring Cloud Alibaba基础教程&#xff1a;Sentinel使用Apollo存储规则 上一篇我们介绍了如何通过Nacos的配置功能来存储限流规则。Apollo是国内用户非常多的配置中心&#xff0c;所以&#xff0c;今天我们继续说说Spring Cloud Alibaba Sentinel中如何将流控规则存储…

Quartz.Net分布式任务管理平台

前言&#xff1a;我相信大多数人公司的业务上都有定时任务这么个功能&#xff0c;我们公司也不例外&#xff0c;刚来公司的时候使用Quartz.Net为我们组做了第一个任务&#xff0c;大致流程是&#xff1a;新建一个控制台程序&#xff0c;引用需要的程序集&#xff0c;Execute方法…

Sentinel(二十四)之Sentinel Dashboard中修改规则同步到ZooKeeper

转载自 Springboot使用Sentinel限流&#xff0c;集成zookeeper完成规则的持久化 上一篇简单介绍了sentinel限流的基本配置和使用&#xff0c;这一篇我们来稍微深入一点&#xff0c;看看如何将zookeeper继承进来&#xff0c;用以保存添加的流控规则。 上一篇中我们启动了dash…

微软Azure AspNetCore微服务实战第2期(内附PPT下载)

2018年1月28日&#xff0c;虽然上海的大雪在城区已经见不到踪影&#xff0c;但还是很冷。不过天气再冷&#xff0c;也阻止不了小伙伴参加活动的热情。感谢王振&#xff0c;苏老师以及微软Azure API Management的产品经理Alvin&#xff0c;给大家带来微服务实战&#xff0c;企业…

Sentinel(二十五)之Sentinel Dashboard同步Apollo存储规则

转载自 Spring Cloud Alibaba基础教程&#xff1a;Sentinel Dashboard同步Apollo存储规则 在之前的两篇教程中我们分别介绍了如何将Sentinel的限流规则存储到Nacos和Apollo中。同时&#xff0c;在文末的思考中&#xff0c;我都指出了这两套整合方案都存在一个不足之处&#…

为什么选择.NETCore?

为什么选择.NETCore&#xff1f;在开展话题之前先出一张ASP.NETCore VS Node.js的性能对比图 ASP.NET Core VS node.js&#xff1a;继续正文&#xff1a;学习新的开发框架是一项巨大的投资。您需要学习如何在新框架中编写&#xff0c;构建&#xff0c;测试&#xff0c;部署…

欢乐纪中某A组赛【2019.7.10】

前言 好烦我最后写对了T1T1T1的808080分结果交错题导致T2T2T2的404040分没了T1T1T1也没拿多那些分。 话说好像ZDYZDYZDY比我还惨 成绩 这里还是按OJOJOJ上的分数排名 JJJ表示初中&#xff0c;HHH表示高中后面加的是几年级 RankRankRankPersonPersonPersonScoreScoreScoreAAA…

用C#编写Linux守护进程

如果要在Red Hat Enterprise Linux上将.NET Core进程作为后台进程运行&#xff0c;则可以创建自定义systemd单元。今天我将为.NET Core编写两个自定义系统单元的例子。一个是运行.NET Core控制台应用程序的一种类型&#xff0c;另一个是运行ASP.NET Core Web应用程序的简单类型…

AWS Lambda现已支持.NET Core 2.0

Amazon宣称.NET Core 2.0现在已经支持AWS Lambda以及无服务器应用程序了。开发者们现在可以使用C#和.NET Core 2.0来为AWS Lambda编写代码和编写运行于AWS的无服务器应用程序了。自2017年2月Amazon开始了对C#编程语言的支持&#xff0c;这使得.NET开发者能够使用.NET Core 1.0运…

Nacos(一)之简介

转载自 什么是 Nacos Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集&#xff0c;帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。 Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现…

开源纯C#工控网关+组态软件(八)表达式编译器

一、 引子监控画面的主要功能之一就是跟踪下位机变量变化&#xff0c;并将这些变化展现为动画。大部分时候&#xff0c;界面上一个图元组件的某个状态&#xff0c;与单一变量Tag绑定&#xff0c;比如电机的运行态&#xff0c;绑定一个MotorRunning信号&#xff1b;但有些时候…

g4e基础篇#6 了解Git历史记录

Git的版本历史记录采用了与传统集中式版本管理系统完全不同的方式进行组织&#xff0c;在刚开始使用Git的时候我们往往会不知所措&#xff0c;比如看到这样的历史记录。看到这个七拐八拐的图形&#xff0c;你可能完全不知道它代表了什么。其实这正是Git的特别之处&#xff0c;G…

Ray框架QA

Orleans与Akka对比&#xff0c;为什么选用Orleans&#xff1f;答: Akka对参与开发的人员要求更高一些&#xff0c;普遍是专家级别&#xff0c;Orleans框架进一步抽象了一层&#xff0c;结合C#语言特性&#xff0c;能普遍降低开发难度。下面是知乎网友的答案&#xff0c;可以参考…

Nacos(三)之架构

转载自 Nacos 架构 基本架构及概念 服务 (Service) 服务是指一个或一组软件功能&#xff08;例如特定信息的检索或一组操作的执行&#xff09;&#xff0c;其目的是不同的客户端可以为不同的目的重用&#xff08;例如通过跨进程的网络调用&#xff09;。Nacos 支持主流的服务…