AI提取图片里包含的文字信息-解决文字无法复制的痛点

Posted DS小龙哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AI提取图片里包含的文字信息-解决文字无法复制的痛点相关的知识,希望对你有一定的参考价值。

1. 前言

平时工作中编写开发技术文档,或者学生在编写论文时,经常会上网搜索一些参考文献、文档。

比如: 上网搜索相似的内容参考一下或者引用别人的一段文字,有时候看到一篇较好的内容想要保存等等。

这个过程中会发现,很多网站的提供的页面都是不能复制粘贴的,或者直接是图片形式提供,为了方便能获取这些文字,当前就利用华为云提供的 通用文字识别接口,识别图片里的文本内容,方便复制文字。这个功能QQ上也集成了,使用很方便,这里利用华为云的接口实现一个与QQ类似的功能,截图之后识别图片里包含的文本内容。

这个文字识别接口里不仅仅有通用文字识别功能,还支持很多其他功能:比如身份证、驾驶证、保险单、手写文本、火车票,行驶证…等等功能。还支持用户自定义识别模板,指定需要识别的关键字段,实现用户特定格式图片的自动识别和结构化提取。

2. 文本识别接口使用介绍

2.1 开通服务

地址: https://console.huaweicloud.com/ocr/?region=cn-north-4#/ocr/overview

这个文字识别服务是按调用次数计费的,每个用户每月有1000次的免费调用次数,开通服务后就可以使用。

2.2 接口地址

官网帮助文档: https://support.huaweicloud.com/api-ocr/ocr_03_0042.html

POST https://endpoint/v2/project_id/ocr/general-text

示例:
https://ocr.cn-north-4.myhuaweicloud.com/v2/0e5957be8a00f53c2fa7c0045e4d8fbf/ocr/general-text

请求头:

 "X-Auth-Token": "******",
 "Content-Type": "application/json;charset=UTF-8"


请求体:

 "image": ----这是图片的bas64编码


响应结果:

 "result": 
  "words_block_count": 13,
  "words_block_list": [
   
    "words": "撤,还是不撤?",
    "location": [
     [
      43,
      39
     ],
     [
      161,
      39
     ],
     [
      161,
      60
     ],
     [
      43,
      60
     ]
    ]
   ,
   
    "words": "让我更骄傲的是公司在大灾面前的表现。",
    "location": [
     [
      72,
      95
     ],
     [
      332,
      95
     ],
     [
      332,
      113
     ],
     [
      72,
      113
     ]
    ]
   ,
   
    "words": "2011年3月11日14时46分,日本东北部海域发生里氏9.0级",
    "location": [
     [
      71,
      122
     ],
     [
      482,
      122
     ],
     [
      482,
      142
     ],
     [
      71,
      142
     ]
    ]
   ,
   
    "words": "地震并引发海啸。那一刻,我们正在距离东京100公里的热海开会,",
    "location": [
     [
      41,
      149
     ],
     [
      481,
      149
     ],
     [
      481,
      171
     ],
     [
      41,
      171
     ]
    ]
   ,
   
    "words": "感觉“咚”",
    "location": [
     [
      42,
      180
     ],
     [
      114,
      180
     ],
     [
      114,
      199
     ],
     [
      42,
      199
     ]
    ]
   ,
   
    "words": "地被震了一下。面对地震,",
    "location": [
     [
      115,
      178
     ],
     [
      296,
      178
     ],
     [
      296,
      199
     ],
     [
      115,
      199
     ]
    ]
   ,
   
    "words": "大家都很镇定,",
    "location": [
     [
      300,
      179
     ],
     [
      400,
      179
     ],
     [
      400,
      197
     ],
     [
      300,
      197
     ]
    ]
   ,
   
    "words": "直到看到电",
    "location": [
     [
      405,
      179
     ],
     [
      483,
      179
     ],
     [
      483,
      196
     ],
     [
      405,
      196
     ]
    ]
   ,
   
    "words": "视上触目惊心的画面:15时 25 分,海啸到达陆前高田市海岸;15时",
    "location": [
     [
      41,
      206
     ],
     [
      485,
      206
     ],
     [
      485,
      228
     ],
     [
      41,
      228
     ]
    ]
   ,
   
    "words": "26分,海啸到达陆前高田市中心;15时43分,陆前高田市依稀只能",
    "location": [
     [
      40,
      234
     ],
     [
      486,
      234
     ],
     [
      486,
      258
     ],
     [
      40,
      258
     ]
    ]
   ,
   
    "words": "看到四层高的市府大楼的屋顶,一瞬间,城镇就变成了汪洋……对",
    "location": [
     [
      40,
      262
     ],
     [
      487,
      262
     ],
     [
      487,
      287
     ],
     [
      40,
      287
     ]
    ]
   ,
   
    "words": "我来说,地震跟家常便饭一样,可眼前的灾难比以往任何一次都要",
    "location": [
     [
      40,
      292
     ],
     [
      487,
      292
     ],
     [
      487,
      317
     ],
     [
      40,
      317
     ]
    ]
   ,
   
    "words": "惨烈,完全超出了我的预期。",
    "location": [
     [
      41,
      326
     ],
     [
      231,
      326
     ],
     [
      231,
      345
     ],
     [
      41,
      345
     ]
    ]
   
  ],
  "direction": -1
 

在请求参数里的X-Auth-Token参数比较重要,调用华为云的任何API接口都需要这个参数,获取方式可以看前面的文章。比如这篇文章: https://support.huaweicloud.com/api-ocr/ocr_03_0005.html

2.3 在线调试接口

地址: https://apiexplorer.developer.huaweicloud.com/apiexplorer/debug?product=OCR&api=RecognizeGeneralText

使用调试接口想体验识别效果,图片的数据支持base64编码、http网络图片地址传入,测试非常方便。

关于获取图片base64编码的方式,在文档里也有介绍,直接通过浏览器获取。

3. 实现代码

代码采用QT编写的,请求API接口实现调用。其他语言方法是一样的。

3.1 实现效果

3.2 核心代码

//解析反馈结果
void Widget::replyFinished(QNetworkReply *reply)

    QString displayInfo="";
    int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

    //读取所有数据
    QByteArray replyData = reply->readAll();

    qDebug()<<"状态码:"<<statusCode;
    qDebug()<<"反馈的数据:"<<QString(replyData);

    //更新token
    if(function_select==3)
    
        displayInfo="token 更新失败.";
        //读取HTTP响应头的数据
        QList<QNetworkReply::RawHeaderPair> RawHeader=reply->rawHeaderPairs();
        qDebug()<<"HTTP响应头数量:"<<RawHeader.size();
        for(int i=0;i<RawHeader.size();i++)
        
            QString first=RawHeader.at(i).first;
            QString second=RawHeader.at(i).second;
            if(first=="X-Subject-Token")
            
                Token=second.toUtf8();
                displayInfo="token 更新成功.";

                //保存到文件
                SaveDataToFile(Token);
                break;
            
        
        QMessageBox::information(this,"提示",displayInfo,QMessageBox::Ok,QMessageBox::Ok);
        return;
    

    //判断状态码
    if(200 != statusCode)
    
        //解析数据
        QJsonParseError json_error;
        QJsonDocument document = QJsonDocument::fromJson(replyData, &json_error);
        if(json_error.error == QJsonParseError::NoError)
        
            //判断是否是对象,然后开始解析数据
            if(document.isObject())
            
                QString error_str="";
                QJsonObject obj = document.object();
                QString error_code;
                //解析错误代码
                if(obj.contains("error_code"))
                
                    error_code=obj.take("error_code").toString();
                    error_str+="错误代码:";
                    error_str+=error_code;
                    error_str+="\\n";
                
                if(obj.contains("error_msg"))
                
                    error_str+="错误消息:";
                    error_str+=obj.take("error_msg").toString();
                    error_str+="\\n";
                

                //显示错误代码
                QMessageBox::information(this,"提示",error_str,QMessageBox::Ok,QMessageBox::Ok);
            
         
        return;
    

    //结果返回
    if(function_select==1)
    
        //解析数据
        QJsonParseError json_error;
        QJsonDocument document = QJsonDocument::fromJson(replyData, &json_error);
        if(json_error.error == QJsonParseError::NoError)
        
            //判断是否是对象,然后开始解析数据
            if(document.isObject())
            
                QJsonObject obj = document.object();
                QString error_code;
                //解析
                if(obj.contains("result"))
                
                    QJsonObject obj1=obj.take("result").toObject();

                    QString bank_name;
                    QString card_number;
                    QString type;

                    QString text;
                    if(obj1.contains("bank_name"))
                    
                        bank_name=obj1.take("bank_name").toString();
                    
                    if(obj1.contains("card_number"))
                    
                        card_number=obj1.take("card_number").toString();
                    
                    if(obj1.contains("type"))
                    
                        type=obj1.take("type").toString();
                    


                    text="发卡行:"+bank_name+"\\n";
                    text+="卡号:"+card_number+"\\n";
                    text+="卡类型:"+type+"\\n";

                    ui->plainTextEdit->setPlainText(text);
                
            
        
    

    //结果返回
    if(function_select==2)
    
        //解析数据
        QJsonParseError json_error;
        QJsonDocument document = QJsonDocument::fromJson(replyData, &json_error);
        if(json_error.error == QJsonParseError::NoError)
        
            //判断是否是对象,然后开始解析数据
            if(document.isObject())
            
                QJsonObject obj = document.object();
                QString error_code;
                //解析
                if(obj.contains("result"))
                
                    QJsonObject obj1=obj.take("result").toObject();

                    int words_block_count;
                    QString text="";
                    if(obj1.contains("words_block_count"))
                    
                        words_block_count=obj1.take("words_block_count").toInt();

                       // text=QString("识别到%1行文本.\\n").arg(words_block_count);
                    

                    if(obj1.contains("words_block_list"))
                    
                        QJsonArray array=obj1.take("words_block_list").toArray();
                        for(int i=0;i<array.size();i++)
                        
                            QJsonObject obj2=array.at(i).toObject();
                            if(obj2.contains("words"))
                            
                                text+=obj2.take("words").toString();
                                text+="\\n";
                            
                        
                    

                    ui->plainTextEdit->setPlainText(text);
                
            
        
    


/*
功能: 获取token
*/
void Widget::GetToken()

    //表示获取token
    function_select=3;

    QString requestUrl;
    QNetworkRequest request;

    //设置请求地址
    QUrl url;

    //获取token请求地址
    requestUrl = QString("https://iam.%1.myhuaweicloud.com/v3/auth/tokens")
                 .arg(SERVER_ID);

    //自己创建的TCP服务器,测试用
    //requestUrl="http://10.0.0.6:8080";

    //设置数据提交格式
    request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json;charset=UTF-8"));

    //构造请求
    url.setUrl(requestUrl);

    request.setUrl(url);

    QString text =QString("\\"auth\\":\\"identity\\":\\"methods\\":[\\"password\\"],\\"password\\":"
    "\\"user\\":\\"domain\\": "
    "\\"name\\":\\"%1\\",\\"name\\": \\"%2\\",\\"password\\": \\"%3\\","
    "\\"scope\\":\\"project\\":\\"name\\":\\"%4\\"")
            .arg(MAIN_USER)
            .arg(IAM_USER)
            .arg(IAM_PASSWORD)
            .arg(SERVER_ID);

    //发送请求
    manager->post(request, text.toUtf8());


//粘贴图片
void Widget::on_pushButton_copy_clicked()

    QClipboard *clipboard = QApplication::clipboard();
    const QMimeData *mimeData = clipboard->mimeData();
    if (mimeData->hasImage())
    
        //将图片数据转为QImage
        QImage img = qvariant_cast<QImage>(mimeData->imageData());
        if(!img.isNull())
        
           ui->widget->SetImage(img);
        
    


//获取图片里的文字信息
void  Widget::getTextInfo(QImage image)

    function_select=2;
    QString requestUrl;
    QNetworkRequest request;

    //存放图片BASE64编码
    QString imgData;

    //设置请求地址
    QUrl url;

    //人脸搜索请求地址
    requestUrl = QString("https://ocr.%1.myhuaweicloud.com/v2/%2/ocr/general-text")
            .arg(SERVER_ID)
            .arg(PROJECT_ID);

    //设置数据提交格式
    request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json;charset=UTF-8"));

    //将图片进行Base64编码
    imgData = QString(toBase64(image)); //编码后的图片大小不超过2M
    //设置token
    request.setRawHeader("X-Auth-Token",Token);

    //构造请求
    url.setUrl(requestUrl);
    request.setUrl(url);<

以上是关于AI提取图片里包含的文字信息-解决文字无法复制的痛点的主要内容,如果未能解决你的问题,请参考以下文章

java通过百度AI开发平台提取身份证图片中的文字信息

请问有没有能把图片里的文字和表格直接提取出来的软件?

word文字怎么转到ae里面

怎么用手机提取图片中的文字

C# 10分钟完成百度图片提取文字(文字识别)——入门篇

ai怎么把图片文字画出路径 提取出来