zoukankan      html  css  js  c++  java
  • 安卓开发 利用百度识图api进行物体识别

    前文

    之前的随笔中,已经通过相机或相册获取到了我们想要的图片,接下来进行识图api的配置工作。我使用的是百度的api,利用python获取信息,并在MainActivity中进行调用来输出信息。

    一、首先我们需要申请创建一个应用(管理控制台->产品服务->图像识别),百度智能云,得到api keysecret key

    利用百度api进行识图的python代码,因为我们一会需要在as中调用函数,所以不需要写主函数了

    # coding=utf-8
    
    import sys
    import json
    import base64
    
    # 保证兼容python2以及python3
    IS_PY3 = sys.version_info.major == 3
    if IS_PY3:
        from urllib.request import urlopen
        from urllib.request import Request
        from urllib.error import URLError
        from urllib.parse import urlencode
        from urllib.parse import quote_plus
    else:
        import urllib2
        from urllib import quote_plus
        from urllib2 import urlopen
        from urllib2 import Request
        from urllib2 import URLError
        from urllib import urlencode
    
    # 防止https证书校验不正确
    import ssl
    ssl._create_default_https_context = ssl._create_unverified_context
    
    API_KEY = '你的API Key'
    
    SECRET_KEY = '你的Secret Key'
    
    
    IMAGE_RECOGNIZE_URL = "https://aip.baidubce.com/rest/2.0/image-classify/v2/advanced_general"
    
    """  TOKEN start """
    TOKEN_URL = 'https://aip.baidubce.com/oauth/2.0/token'
    
    """
        获取token
    """
    def fetch_token():
        params = {'grant_type': 'client_credentials',
                  'client_id': API_KEY,
                  'client_secret': SECRET_KEY}
        post_data = urlencode(params)
        if (IS_PY3):
            post_data = post_data.encode('utf-8')
        req = Request(TOKEN_URL, post_data)
        try:
            f = urlopen(req, timeout=5)
            result_str = f.read()
        except URLError as err:
            print(err)
        if (IS_PY3):
            result_str = result_str.decode()
    
        result = json.loads(result_str)
    
        if ('access_token' in result.keys() and 'scope' in result.keys()):
            if not 'brain_all_scope' in result['scope'].split(' '):
                print ('please ensure has check the  ability')
                exit()
            return result['access_token']
        else:
            print ('please overwrite the correct API_KEY and SECRET_KEY')
            exit()
    
    """
        读取文件
    """
    def read_file(image_path):
        f = None
        try:
            f = open(image_path, 'rb')
            return f.read()
        except:
            print('read image file fail')
            return None
        finally:
            if f:
                f.close()
    
    """
        调用远程服务
    """
    def request(url, data):
        req = Request(url, data.encode('utf-8'))
        has_error = False
        try:
            f = urlopen(req)
            result_str = f.read()
            if (IS_PY3):
                result_str = result_str.decode()
            return result_str
        except  URLError as err:
            print(err)
    
    """
        调用识别接口并打印结果
    """
    def print_result(filename,url):
        # 获取图片
        file_content = read_file(filename)
    
        response = request(url, urlencode(
            {
                'image': base64.b64encode(file_content),
                'top_num': 1
            }))
        result_json = json.loads(response)
    
        #返回识别结果中得分最高的"keyword"
        for data in result_json["result"]:
            return data["keyword"]
    
    #返回结果示例
    #     "result": [{
    #         "score": 0.967622,
    #         "root": "公众人物",
    #         "baike_info": {
    #             "baike_url": "http://baike.baidu.com/item/%E6%96%B0%E5%9E%A3%E7%BB%93%E8%A1%A3/8035884",
    #             "image_url": "http://imgsrc.baidu.com/baike/pic/item/91ef76c6a7efce1b27893518a451f3deb58f6546.jpg",
    #             "description": "新垣结衣(Aragaki Yui),1988年6月11日出生于冲绳县那霸市。日本女演员、歌手、模特。毕业于日出高中。2001年,参加《nicola》模特比赛并获得最优秀奖。2005年,因出演现代剧《涩谷15》而作为演员出道。2006年,参演校园剧《我的老大,我的英雄》;同年,她还出版了个人首本写真集《水漾青春》。2007年,她从日出高校毕业后开始专注于演艺发展,并发表个人首张音乐专辑《天空》;同年,新垣结衣还主演了爱情片《恋空》,而她也凭借该片获得了多个电影新人奖项。2010年,主演爱情片《花水木》。2011年,主演都市剧《全开女孩》。2012年,相继参演现代剧《Legal High》、剧情片《剧场版新参者:麒麟之翼》。2013年,主演都市剧《飞翔情报室》。2014年,她主演了剧情片《黎明的沙耶》。2016年,主演爱情喜剧《逃避虽可耻但有用》,并凭借该剧获得了多个电视剧女主角奖项。2017年,主演爱情片《恋爱回旋》,凭借该片获得第60届蓝丝带奖最佳女主角;同年11月,她还凭借医疗剧《Code Blue 3》获得第94届日剧学院赏最佳女配角。"
    #         },
    #         "keyword": "新垣结衣"
    #     },
    #     {
    #         "score": 0.716067,
    #         "root": "人物-人物特写",
    #         "keyword": "头发"
    #     },
    #     {
    #         "score": 0.421281,
    #         "root": "商品-穿戴",
    #         "keyword": "围巾"
    #     },
    #     {
    #         "score": 0.22347,
    #         "root": "商品-五金",
    #         "keyword": "拉链"
    #     },
    #     {
    #         "score": 0.028031,
    #         "root": "商品-穿戴",
    #         "keyword": "脖套"
    #     }]

    二、将这个python代码插入到as中,需要用到chaquopy,具体配置教程

    三、在MainActivity中调用python函数

    // 初始化Python环境
        void initPython(){
            if (! Python.isStarted()) {
                Python.start(new AndroidPlatform(this));
            }
        }
            mBtnFinish.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mTvPath.getText().toString().equals("图片路径:")){
                        // 如果一张图片都没选
                        ToastUtil.showMsg(getApplicationContext(), "您还没有选择图片呢!");
                    }else{
                        Python py = Python.getInstance();
                        PyObject token = py.getModule("hello").callAttr("fetch_token");//获取token
                        String token2 = token.toJava(String.class);//将获取的token转换为Java中的string类型
                        String url = "https://aip.baidubce.com/rest/2.0/image-classify/v2/advanced_general?access_token=" + token2;//拼接url
    
                        PyObject pyObject = py.getModule("hello").callAttr("print_result",mTvPath.getText(),url);//调用python函数
                        String returnString = pyObject.toString();
                        System.out.println(returnString);
                        mTvResult.setText("识别成功!结果为:"+returnString);
                    }
                }
            });

    遇到的问题:

    点击拍照后,照片不会更新,但是并不影响识别结果

    原因分析:在安卓7.0以上,使用了共享文件的形式,每次拍照使用了相同的路径,旧图片会被新图片顶替掉,于是在

    Glide.with(MainActivity.this).load(outputUri).into(mIvPic);//使用Glide进行图片展示

    的时候,glide使用了相同的uri,导致imageview没有刷新图片,但是并不影响使用python函数进行图片识别的结果,因为uri是正确的。

    暂时还没有解决

  • 相关阅读:
    利用索引提高SQL Server数据处理的效率
    拆掉思维里的墙摘抄
    QR码和PDF417比较
    保存一个记录到数据库又马上返回ID号
    C#获取当前路径的7种方法
    汉诺塔算法不错,收藏了!
    如何确定Z检验的值(查正态分布表时要注意中间的数字都是面积,最左边一列和最上面一行都是Z值)
    opencv的安装
    SQL事务
    重大财务决策前的思考
  • 原文地址:https://www.cnblogs.com/Arisf/p/14674583.html
Copyright © 2011-2022 走看看