You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dianshang-qianduan/src/views/digitalMarketTech/artificialIntelligence/components/article-identification.vue

401 lines
16 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="app-container4">
<div class="text-centent">
<div class="left">
<el-scrollbar height="640px" style="height:94%;padding: 0 15px;">
<el-row>
<el-col :span="24">
<div class="title-back">
<span>任务背景</span>
</div>
</el-col>
</el-row>
<p>
小张在写期末课程小论文的时候,上网查资料发现一篇文章特别有参考价值,但是这篇文章无法复制,小张要怎么做才能获得这篇文章的电子版呢?
</p>
<div class="Step" v-for="item in Step1" :key="item">
<div class="Ellipse">
<div class="Step-item">步骤一</div>
<span >{{ item.stemContent }}</span>
</div>
<!-- <span v-if="item.studentAnswer!==''"><span v-if="!item.correctAnswer.includes(item.studentAnswer)">正确答案:{{ item.correctAnswer }}</span></span> -->
<p><el-radio label="A" size="large" v-model="item.studentAnswer" >A. {{ item.optionA }}</el-radio></p>
<p><el-radio label="B" size="large" v-model="item.studentAnswer" >B. {{ item.optionB }}</el-radio></p>
<div class="footer">
<el-button class="--primary" type="primary" round plain size="large" @click="stepOneanswer" >提交任务</el-button>
<el-button class="--primary " type="primary" round plain size="large" @click="downloadArticle" >点击下载文章图片</el-button>
</div>
</div>
<el-divider />
<div class="Step2 Step" v-for="item1 in Step2" :key="item">
<div class="Ellipse">
<div class="Step-item">步骤二</div>
<span>{{ item1.stemContent }}</span>
</div>
<p><el-checkbox label="A" size="large" v-model="item1.studentAnswer" >A. {{ item1.optionA }}</el-checkbox></p>
<p><el-checkbox label="B" size="large" v-model="item1.studentAnswer" >B. {{ item1.optionB }}</el-checkbox></p>
<p><el-checkbox label="C" size="large" v-model="item1.studentAnswer" >C. {{ item1.optionC }}</el-checkbox></p>
<p><el-checkbox label="D" size="large" v-model="item1.studentAnswer" >D. {{ item1.optionD }}</el-checkbox></p>
<p><el-checkbox label="E" size="large" v-model="item1.studentAnswer" >E. {{ item1.optionF }}</el-checkbox></p>
<div class="footer">
<el-button class="--primary" type="primary" round plain size="large" @click="stepTwoanswer">提交任务</el-button>
</div>
</div>
<el-divider />
<div class="Step3 Step">
<div class="Ellipse">
<div class="Step-item">步骤三</div>
<span>识别字符</span>
</div>
<div class="Identify">
<div class="title"><span>请用手机上的文字识别工具对步骤一下载的图片进行文字识别,识别的文字内容请复制在下方文本框中。</span></div>
<el-input v-model="textarea" :rows="2" type="textarea" />
<div class="footer">
<el-button class="--primary" type="primary" round plain size="large" @click="identifyText" >提交任务</el-button>
</div>
</div>
</div>
</el-scrollbar>
<div class="dialog-footer" style="margin-top:5px">
<el-button type="primary" class="tj" size="large" @click="submit">提交任务</el-button>
<el-button type="primary" class="cxks" size="large" @click='reStart'>重新开始</el-button>
</div>
</div>
<div class="right">
<span @click="textDialogVisible=true"></span>
</div>
<el-dialog
custom-class="gdialog"
v-model="textDialogVisible"
title="文字识别OCR"
width="70%">
<el-scrollbar height="666px">
<p> OCR是一个简称,全称叫Optical CharacterRecognition,中文是:光学字符识别。</p>
<p>它的本质是:把图像形状转变为文本字符。</p>
<p>下面说一下,我在教育行业是如何应用OCR的</p>
<p>信息化教学越来越普及,很多教学素材都要搬到信息化平台,比如试卷试题。那么,纸质的试卷要电子化,就会用到OCR识别技术</p>
<p><img src="@/assets/images/szjj/u852.png" alt=""></p>
<p>这么一张图,需要识别成结构化(图片、文字、公式、表格可独立提取出来)的数据,识别结果如下所示:</p>
<p><img src="@/assets/images/szjj/u853.png" alt=""></p>
<p>而且,识别结果还可以下载成word文档,便于老师校对并进行二次编辑.</p>
<p>除此之外,我们常见的各种证件识别、名片识别、车牌识别等,也涉及OCR技术。</p>
<p>OCR技术的实现,总体上可以分为五步:预处理图片、切割字符、识别字符、恢复版面、后处理文字。</p>
<p><img src="@/assets/images/szjj/u856.png" alt=""></p>
<span class="headline">1.预处理图片</span>
<p>我们买回来水果,需要洗一下再吃。如果运气不好的话,还需要挖掉虫眼和糙皮才能吃。我们把吃水果前的这些步骤,叫做CSG(吃水果)的预处理。</p>
<p>在进行OCR之前,也需要对图片进行预处理。因为,一般待识别的图片千奇百怪,来源复杂:有拍照、有扫描、有截图。</p>
<p>拿拍照来说,有夏至那天中午头儿,在阳光直射下拍的;也有人在傍晚,拿着大顶转着圈儿拍的。如果不进行预处理,OCR会很为难,因此需要进行灰度化,二值化,噪声去除,倾斜矫正等预处理过程。 </p>
<p><img src="@/assets/images/szjj/u869.png" alt=""></p>
<span class="headline">2.切割字符</span>
<p>假设,通过了预处理,我们的图片都变得很规范,于是,我们需要切割字符,把每一个字都给他挖出来。</p>
<p><img src="@/assets/images/szjj/u859.png" alt=""></p>
<p>并且,还需要对每个字符做好标记,因为识别完了,还得还原回去。识别完了,结果是一堆单蹦的“1”、“2”、“3”、“+”、“-”字符。我们需要根据它们的相对<br/>位置,还原成“8-7=1”。所以,我们就知道了,哪个题目做对了,做错了,从而给出批改结果。</p>
<span class="headline">3.识别字符</span>
<p>图片究竟是怎么变为字符的?它还能自己学习。计算机通过学习一些样本之后,遇到一些从未遇到过的同类样本,也能正确地识别出结果,原理如下:<br/>
我带着孩子去公园,公园门口有一对大狮子。孩子指着狮子说,狗!我说,哦,那不是狗,那是狮子,跟狗有点像是不是。又走了一段路,公园里又出现一个麒麟的雕塑。孩子指着它说,狮子!我说,那不是狮子。<br/>
孩子说,是狗。我说也不是狗,它叫:麒麟。我感觉到,孩子的大脑在反向矫正信息,这就是监督学习。<br/>
当我给他看狗的图片时,我告诉她这是狗。<br/>
她根据自己的认知,找了几个特征,构建了一个模型:长嘴+尖牙=狗。<br/>
虽然只是看过图片,但是出门遇到真狗,她根据这个模型也认识对了。<br/>
后来,她遇到了狮子,她修改了模型:长嘴+尖牙+鬃毛≠狗=狮子。<br/>
后来,又遇到了麒麟,这个公式变得越来越复杂……决策项越来越多。<br/>
人工智能,就是模拟的人类的神经元,构建神经网络来尝试寻找特征和结果的关系。如果对了,就给这个特征加分。如果,错了,就给这个特征减分。<br/>
识别数字,也是一样。<br/>
比如在学习识别数字6的时候,它随机认为只要有一个圈圈特征,就是数字6。<br/>
验证其他样本时,发现这个随机特征是对的(不对就再换一个特征再试)。于是,它建立了一个模型:只要有圈这个特征,就是6。<br/>
后来,这个模型遇到了数字0。加入新样本后,人工智能发现,0也有圈,但它不是6,也有可能是0。得再找一个特征,于是,新增一条,有勾就是6。后来,它又遇到了9。那勾在上面的就是6。后来,它又遇到了字<br/>
母b……反正计算机有的是算力,能在很短的时间内完成这些学习。上面我是搂着说的,其实即便在32*32像素的小图片上,它随机上几十个特征去做验证,一点都不吃力。<br/>
这就是识别字符的原理。OCR字符的识别从来不难。难的是两头,比如开头的预处理,以及下面要说的后处理。<br/>
</p>
<span class="headline">4.恢复版面</span>
<p>识别出了字符,意义不大,有效地连接起来才能发挥作用。</p>
<p>我们期望的拆分和还原应该是下面这样:</p>
<p><img src="@/assets/images/szjj/u866.png" alt=""></p>
<p>“10+2= 4-3= 5+6=11”这些文本从数据结构上应该是一行。而且,“10+2=”从数据结构上是一个基本单位。因为,我们要对基本单位做运算和批改。这才叫还原,其实并不简单。</p>
<span class="headline">5.后处理文字</span>
<p>
OCR识别的最终目的,是要获得一份准确的、结构化的文本内容。<br/>
单个字符识别,其实是各自为战,前后不商量。<br/>
就比如,遇到一个圆圈形状的字符图片。OCR识别就犯了难,它是数字“0”?汉字“〇”?大写字母“O”?小写字母“o”?中文句号“。”?还是“Q”忘了加尾巴……<br/>
啥都对,啥都不对。<br/>
所以,需要矫正……校正。这两个词,都是高频词,尤其拼音打字jiaozheng,容易出错。其实,也好分辨。看语境,如果我前后提到了“文稿”,那么是“校正”的可能性就大。如果我刚刚说了“牙齿”、“视力”、“角度”啥的,那么基本上就应该是“矫正”了。
OCR识别的最后一步校正也是一样。如果无法确定是数字“0”还是字母“o”,可以观察它相邻的几个字符,下面一图胜千言<br/>
</p>
<p><img src="@/assets/images/szjj/u868.png" alt=""></p>
</el-scrollbar>
</el-dialog>
</div>
</div>
</template>
<script setup>
import {getToken,getUserInfo} from "@/utils/auth.js";
import * as commonality from "@/api/commonality.js";
const { proxy } = getCurrentInstance()
const textDialogVisible = ref(false);
const downloadShow = ref(false);
// 答题记录
const errorCount = ref(0);
const answerRecord=ref(0)
// 步骤一题目
const Step1 = ref([]);
const Step2 = ref([]);
const CharacterRecognitionCase=()=>{
commonality.getTextList({userId:JSON.parse(getUserInfo()).userId,model:'文字识别OCR'}).then(res=>{
if(Step1.value.length<1&&Step2.value.length<1){
Step1.value.push(res.data[0])
Step2.value.push(res.data[1])
}
Step1.value.forEach(item=>{
if(item.optionF!==null||item.optionF!==''){
textarea.value=item.optionF
}
if(item.studentAnswer!==''||item.studentAnswer!==null){
answerRecord.value=1
}
if(item.studentAnswer==null){
downloadShow.value=false
return
}
if(item.studentAnswer === item.correctAnswer){
downloadShow.value=true
}
})
Step2.value.forEach(item=>{
answerRecord.value=3
if(item.studentAnswer !== null){
item.studentAnswer=item.studentAnswer.split(',')
}else{
item.studentAnswer=[]
console.log( item.studentAnswer," item.studentAnswer");
}
})
})
}
// submitStepOne
const stepOneanswer=()=>{
answerRecord.value=1
commonality.submitStepOne({userId:JSON.parse(getUserInfo()).userId,answer:Step1.value[0].studentAnswer}).then(res=>{
if(res.msg.includes('错误')){
errorCount.value=1
proxy.$modal.msgError(res.msg);
}else{
proxy.$modal.msgSuccess('提交成功');
downloadShow.value=true
}
}).catch(error=>{
errorCount.value=1
})
}
const stepTwoanswer=()=>{
if(answerRecord.value<1){
return proxy.$modal.msgWarning("请先完成步骤一")
}else if(answerRecord.value < 2){
return proxy.$modal.msgWarning("请先下载文章图片再进行此操作")
}
answerRecord.value=3
commonality.submitStepTwo({userId:JSON.parse(getUserInfo()).userId,answer:Step2.value[0].studentAnswer.join(',')}).then(res=>{
if(res.msg.includes('错误')){
errorCount.value=2
proxy.$modal.msgError(res.msg);
}else{
proxy.$modal.msgSuccess('提交成功');
}
}).catch(err=>{
errorCount.value=2
})
}
// 下载文章
const downloadArticle=()=>{
if(answerRecord.value<1){
return proxy.$modal.msgWarning("请先完成上一步")
}
answerRecord.value=2
window.open(`http://118.31.7.2:9868/api/stu/experimental/downloadImg?userId=${JSON.parse(getUserInfo()).userId}&TOKEN=${getToken()}`)
}
// 识别文字
const textarea=ref('')
// 识别文字函数
const identifyText=()=>{
const params={
userId:JSON.parse(getUserInfo()).userId,
context:textarea.value
}
if(answerRecord.value<3){
return proxy.$modal.msgWarning("请先完成前面的题目再进行此操作")
}
answerRecord.value=4
commonality.submitStepThree(params).then(res=>{
proxy.$modal.msgSuccess(res.msg);
}).catch(err=>{
errorCount.value=3
})
}
const submit = () => {
if( textarea.value!==''&& answerRecord.value>2){
answerRecord.value=4
}
if(answerRecord.value < 4){
return proxy.$modal.msgWarning("请先完成实训")
}
commonality
.submitTask({module:'文字识别',numberOfErrors:errorCount.value>10?10:errorCount.value,taskName:'文字识别',userId:JSON.parse(getUserInfo()).userId})
.then((response) => {
proxy.$modal.msgSuccess("提交成功");
textDialogVisible.value=false
})
.catch((error) => {
});
};
// 重新开始
const reStart=()=>{
textarea.value=''
Step1.value.forEach(item=>{
item.studentAnswer=''
})
Step2.value.forEach(item=>{
item.studentAnswer=[]
})
answerRecord.value=0
downloadShow.value=false
}
CharacterRecognitionCase()
</script>
<style lang="scss" scoped>
.text-centent {
display: flex;
.left {
position: relative;
width: 100%;
}
.right {
position: absolute;
right: 30px;
top: 180px;
width: 216px;
padding-left: 60px;
span {
display: inline-block;
width: 110px;
height: 143px;
background: url("@/assets/images/szjj/案例任务.png") no-repeat;
background-size: 100% 100%;
}
}
}
div {
// p {
// font-size: 12px;
// }
.title-back {
width: 182px;
height: 66px;
line-height: 66px;
text-align: center;
background: url("@/assets/images/szjj/任务背景.png") no-repeat;
background-size: 100% 100%;
font-size: 20px;
font-family: Source Han Sans CN;
font-weight: bold;
}
.Step {
margin-bottom: 34px;
.Ellipse{
display: flex;
align-items: center;
.Step-item {
width: 52px;
height: 25px;
color: #ffffff;
background: #5621f8;
border-radius: 13px;
font-size: 12px;
text-align: center;
line-height: 25px;
}
span {
display: inline-block;
margin-left: 10px !important;
font-size: 15px;
font-family: Source Han Sans CN;
font-weight: 600;
color: #000000;
}
}
p {
width: calc(100% - 30%);
padding-left: 22px;
height: 36px;
background: #e9ebfc;
border-radius: 4px;
}
}
.--primary {
font-size: 12px;
padding-left: 40px;
padding-right: 34px;
border: none;
color: #ffffff;
background: url("@/assets/images/szjj/提交任务.png") no-repeat !important;
background-size: 100% 100%;
}
// .el-button--primary:nth-child(2) {
// width: 140px !important;
// padding-left: 60px;
// background: url("@/assets/images/szjj/重新开始.png") no-repeat !important;
// background-size:cover;
// }
.Identify {
margin-top: 20px;
width: calc(100% - 20%);
height: 420px;
background: #f7f7f7;
border: 1px solid #dcdcdc;
border-radius: 4px;
padding: 0px 18px;
.title {
height: 54px;
line-height: 54px;
span{
font-size: 12px;
font-family: Source Han Sans CN;
font-weight: 500;
line-height: 20px;
}
}
:deep(.el-textarea__inner) {
min-height: 282px !important;
}
.footer {
margin-top: 18px;
}
}
.foo_ter {
display: flex;
align-items: center;
justify-content: center;
}
.dis{
display: none !important;
}
// .btn{
// // margin-left: 20px;
// }
}
.tj{
width: 136px;
height: 40px;
color: #000000 !important;
}
.cxks{
width: 136px;
height: 40px;
color: #000000 !important;
}
</style>