【语音/图像识别】Logo识别导航
让天涯 发布于2021-11 浏览:3150 回复:0
2
收藏
最后编辑于2022-04

一、背景

生活中,我们看到的logo图片琳琅满目,无论如何我们也不能都认全,在遇到不认识的品牌图片时,我们要么选择请教他人,要么就只能自己想办法获取,而自己获取品牌logo的方法有限,且获取到的结果不一定快速准确。

因此本教程,提供了一个快速、准确获取品牌logo名称的方法:使用百度品牌logo识别技术,可识别超过2万类商品logo,准确识别图片中品牌logo的名称,并获取其在60LOG、百度百科、企查查等网站上的相关信息,形成一个基于品牌logo名称的信息聚合搜索平台,让你不仅能认识品牌,还能深入了解该品牌的相关信息。

应用场景:

        1、不认识品牌logo,拍照识别。

        2、想了解品牌logo详情,拍照获取。

二、技术方案简介

使用.NET 5 开发网站,通过接收图片,调用百度品牌logo识别技术的在线API接口,快速识别图片中品牌logo的名称,利用识别的logo名称,显示其在60LOG、百度百科、企查查等网站上的相关链接。
三、具体实现的步骤

(1)创建应用
登陆 百度智能云-管理中心 创建 “图像识别”应用,获取 “API Key ”和 “Secret Key”:https://console.bce.baidu.com/ai/#/ai/imagerecognition/overview/index

(1-1)创建应用(若已创建,则跳过,直接点击”管理应用“,获取“API Key ”和 “Secret Key”)

(1-2)创建完成后,选择“管理应用”,获取 “API Key ”和 “Secret Key”

(2)查看文档

文档地址:https://ai.baidu.com/ai-doc/IMAGERECOGNITION/Ok3bcxc59

接口描述:该请求用于检测和识别图片中的台标、品牌商标等logo信息。即对于输入的一张图片(可正常解码,且长宽比适宜),输出图片中logo的名称、位置和置信度。

请求说明

HTTP方法:POST
请求URL:https://aip.baidubce.com/rest/2.0/image-classify/v2/logo
URL参数:

Header如下:

Body中放置请求参数,参数详情如下:
请求参数

返回说明
返回参数

返回示例:

HTTP/1.1 200 OK
x-bce-request-id: 73c4e74c-3101-4a00-bf44-fe246959c05e
Cache-Control: no-cache
Server: BWS
Date: Tue, 18 Oct 2016 02:21:01 GMT
Content-Type: application/json;charset=UTF-8
{
  "log_id": 843411868,
  "result_num": 1,
  "result": [
    {
      "type": 0,
      "name": "科颜氏",
      "probability": 0.99998807907104,
      "location": {
        "width": 296,
        "top": 20,
        "height": 128,
        "left": 23
      }
    }
  ]
}

(3)开发源码

(3-1)根据 API Key 和 Secret Key 获取 AccessToken

/// 
/// 获取百度access_token
/// 
/// API Key
/// Secret Key
/// 
public static string GetAccessToken(string clientId, string clientSecret)
{
    string authHost = "https://aip.baidubce.com/oauth/2.0/token";
    HttpClient client = new HttpClient();
    List> paraList = new List>();
    paraList.Add(new KeyValuePair("grant_type", "client_credentials"));
    paraList.Add(new KeyValuePair("client_id", clientId));
    paraList.Add(new KeyValuePair("client_secret", clientSecret));

    HttpResponseMessage response = client.PostAsync(authHost, new FormUrlEncodedContent(paraList)).Result;
    string result = response.Content.ReadAsStringAsync().Result;
    JObject jo = (JObject)JsonConvert.DeserializeObject(result);

    string token = jo["access_token"].ToString();
    return token;
}

(3-2)调用API接口获取识别结果

(3-2-1)在Startup.cs 文件 的 Configure(IApplicationBuilder app, IHostingEnvironment env) 方法中开启虚拟目录映射功能:

string webRootPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");//wwwroot目录

string curPath = Path.Combine(webRootPath, "Uploads", "BaiduAIs", "ImageSearch");
if (!Directory.Exists(curPath ))
{
    Directory.CreateDirectory(curPath );
}
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(curPath),
    RequestPath = "/ImageSearch"
});

(3-2-2) 建立ImageSearch.cshtml文件

(3-2-2-1)前台代码:

    由于html代码无法原生显示,只能简单说明一下:

    主要是一个form表单,需要设置属性enctype="multipart/form-data",否则无法上传图片;

    form表单里面有几个控件:

一个Input:type="text",asp-for="ImageUrl" ,输入图片的网络地址;

一个Input:type="file",asp-for="FileUpload" ,上传本地图片;

一个Input:type="submit",asp-page-handler="Logo" ,提交品牌Logo识别请求。

一个img:src="@Model.curPath",显示需要识别的图片。

最后显示后台 msg 字符串列表信息,如果需要输出原始Html代码,则需要使用@Html.Raw()函数。

(3-2-2-2) 后台代码: 

主程序代码:

[BindProperty]
public IFormFile FileUpload { get; set; }
[BindProperty]
public string ImageUrl { get; set; }
string webRootPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");//wwwroot目录
public List msg = new List();//显示结果的字符串列表
public string curPath { get; set; }//显示要识别的品牌Logo图片路径

string BaiduAI_ImageSearchPath="Uploads//BaiduAIs//ImageSearch//";
string BaiduAI_ImageSearchUrl="/ImageSearch/";
string Image_API_KEY="你的API KEY";
string Image_SECRET_KEY="你的SECRET KEY";

public OCRSearchModel(IHostingEnvironment hostingEnvironment)
{
    HostingEnvironment = hostingEnvironment;
}

public async Task OnPostLogoAsync()
{
    if (string.IsNullOrEmpty(ImageUrl) && (FileUpload is null))
    {
        ModelState.AddModelError(string.Empty, "网络图片 或 本地图片 请至少选择一项!");
    }
    if (!ModelState.IsValid)
    {
        return Page();
    }
    msg = new List();

    string fileDir = Path.Combine(webRootPath, BaiduAI_ImageSearchPath);
    string imgName = GetRandomName();

    if (!string.IsNullOrEmpty(ImageUrl))
    {
        imgName = await SaveImageFromWeb(ImageUrl, fileDir, imgName);
    }
    else
    {
        imgName = await UploadFile(FileUpload, fileDir);
    }

    string fileName = Path.Combine(fileDir, imgName);
    string imgBase64 = GetFileBase64(fileName);
    curPath = Path.Combine(BaiduAI_ImageSearchUrl, imgName);

    string result = GetImageJson( imgBase64, Image_API_KEY, Image_SECRET_KEY);
    JObject jo = (JObject)JsonStringToObj(result);

    List msgList = jo["result"].ToList();
    int number = msgList.Count;
    int credible= 0;
    int curNumber = 1;

    foreach (JToken ms in msgList)
    {
        double probability = double.Parse(ms["probability"].ToString());
        if (probability > 0.5)
        {
            credible++;
            if (number > 1)
            {
                msg.Add("第 " + (curNumber++).ToString() + " 条:");
            }
            int type = int.Parse(ms["type"].ToString());
            string typeString = type > 1 ? "自定义logo库" : (type.Equals(0) ? "高优商标" : "2万类logo库");
            msg.Add("识 别 库:" + typeString);
            msg.Add("置 信 度:" + probability.ToString());
            msg.Add("品牌名称:" + ms["name"].ToString());
            msg.Add("相关信息:相关LOGO  百度百科  企查查");
            //msg.Add("企 查 查:企 查 查");
        }
    }

     msg.Insert(0, "返回结果:" + number.ToString() + "(可信结果:" + credible.ToString() + ")");
    return Page();
}

其他相关函数:

/// 
/// 图像识别Json字符串
/// 
/// 图片base64编码
/// API Key
/// Secret Key
/// 
public static string GetImageJson(string strbaser64, string clientId, string clientSecret)
{
    string token = GetAccessToken(clientId, clientSecret);
    string host = "https://aip.baidubce.com/rest/2.0/image-classify/v2/logo?access_token=" + token;
    Encoding encoding = Encoding.Default;
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(host);
    request.Method = "post";
    request.ContentType = "application/x-www-form-urlencoded";
    request.KeepAlive = true;
    string str = "image=" + HttpUtility.UrlEncode(strbaser64);
    byte[] buffer = encoding.GetBytes(str);
    request.ContentLength = buffer.Length;
    request.GetRequestStream().Write(buffer, 0, buffer.Length);
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default);
    string result = reader.ReadToEnd();
    return result;
}

/// 
/// 获取百度access_token
/// 
/// API Key
/// Secret Key
/// 
public static string GetAccessToken(string clientId, string clientSecret)
{
    string authHost = "https://aip.baidubce.com/oauth/2.0/token";
    HttpClient client = new HttpClient();
    List> paraList = new List>();
    paraList.Add(new KeyValuePair("grant_type", "client_credentials"));
    paraList.Add(new KeyValuePair("client_id", clientId));
    paraList.Add(new KeyValuePair("client_secret", clientSecret));

    HttpResponseMessage response = client.PostAsync(authHost, new FormUrlEncodedContent(paraList)).Result;
    string result = response.Content.ReadAsStringAsync().Result;
    JObject jo = (JObject)JsonConvert.DeserializeObject(result);

    string token = jo["access_token"].ToString();
    return token;
}

/// 
/// 生成一个随机唯一文件名(Guid)
/// 
/// 
public static string GetRandomName()
{
    return Guid.NewGuid().ToString("N");
}

/// 
/// 返回图片的base64编码
/// 
/// 文件绝对路径名称
/// 
public static String GetFileBase64(string fileName)
{
    FileStream filestream = new FileStream(fileName, FileMode.Open);
    byte[] arr = new byte[filestream.Length];
    filestream.Read(arr, 0, (int)filestream.Length);
    string baser64 = Convert.ToBase64String(arr);
    filestream.Close();
    return baser64;
}

/// 
/// json转为对象
/// 
/// Json字符串
/// 
public static Object JsonStringToObj(string jsonString)
{
    Object s = JsonConvert.DeserializeObject(jsonString);
    return s;
}

/// 
/// 上传文件,返回文件名
/// 
/// 文件上传控件
/// 文件绝对路径
/// 
public static async Task UploadFile(IFormFile formFile, string fileDir)
{
    if (!Directory.Exists(directory))
    {
        Directory.CreateDirectory(directory);
    }
    string extension = Path.GetExtension(formFile.FileName);
    string imgName = GetRandomName()+ extension;
    var filePath = Path.Combine(fileDir, imgName);

    using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
    {
        await formFile.CopyToAsync(fileStream);
    }

    return imgName;
}

/// 
/// 保存Web图片到本地
/// 
/// web图片路径
/// 保存路径
/// 保存文件名
/// 
public static async Task SaveImageFromWeb(string imgUrl, string path, string fileName)
{
    if (path.Equals(""))
    {
        throw new Exception("未指定保存文件的路径!");
    }
    string imgName = imgUrl.ToString().Substring(imgUrl.ToString().LastIndexOf("/") + 1);
    string defaultType = ".jpg";
    string[] imgTypes = new string[] { ".jpg", ".jpeg", ".png", ".gif", ".bmp" };
    string imgType = imgUrl.ToString().Substring(imgUrl.ToString().LastIndexOf("."));
    string imgPath = "";
    foreach (string it in imgTypes)
    {
        if (imgType.ToLower().Equals(it))
            break;
        if (it.Equals(".bmp"))
            imgType = defaultType;
    }
    imgType = string.IsNullOrEmpty(imgType) ? default : imgType;

    try
    {

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(imgUrl);
        request.UserAgent = "Mozilla/6.0 (MSIE 6.0; Windows NT 5.1; Natas.Robot)";
        request.Timeout = 3000;

        WebResponse response = request.GetResponse();
        Stream stream = response.GetResponseStream();

        if (response.ContentType.ToLower().StartsWith("image/"))
        {
            byte[] arrayByte = new byte[1024];
            int imgLong = (int)response.ContentLength;
            int l = 0;

            if (fileName == "")
                fileName = imgName;

            FileStream fso = new FileStream(path + fileName + imgType, FileMode.Create);
            while (l < imgLong)
            {
                int i = stream.Read(arrayByte, 0, 1024);
                fso.Write(arrayByte, 0, i);
                l += i;
            }

            fso.Close();
            stream.Close();
            response.Close();
            imgPath = fileName + imgType;
            return imgPath;
        }
        else
        {
            return "";
        }
    }
    catch (Exception e1)
    {
        throw new Exception("Web图片保存失败:" + e1.Message);
    }
}

四、实现的效果

1、页面:

2、识别结果(点击链接,可以跳转到对于网站,显示相应品牌LOGO的相关信息)

2.1

2.2

2.3

五、总结

本网站使用VS2022开发工具:https://docs.microsoft.com/zh-cn/visualstudio/releases/2022/release-notes-preview

采用C# 语言:https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/razor-pages/razor-pages-start?view=aspnetcore-5.0&tabs=visual-studio

目标框架为.Net 5.0:https://dotnet.microsoft.com/download/dotnet/5.0

调用品牌logo识别的API接口:https://ai.baidu.com/ai-doc/IMAGERECOGNITION/Ok3bcxc59

相关LOGO主站:60LOGO-logo图片大全-品牌标志-logo下载-标志设计

链接网址:

相关LOGO:https://www.60logo.com/

百度百科:https://baike.baidu.com/

企查查:https://www.qcc.com/

 

注意:GetAccessToken()函数由于百度文字过滤原因(应该是),存在部分单词丢失现象,具体可以参考文档补全:https://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjhhu
 
 
收藏
点赞
2
个赞
TOP
切换版块