(简单调用篇 02) 图像主体检测 - C++ 简单调用

图像主体检测能检测出图片主体的坐标位置,可使用该接口裁剪出图像主体区域,配合图像识别接口提升识别精度。广泛适用于美图类 app、辅助智能识图等业务场景中。

应用场景

  • 智能美图:根据用户上传照片进行主体检测,实现图像裁剪或背景虚化等功能,可应用于含美图功能 app 等业务场景中
  • 图像识别辅助:可使用图像主体检测裁剪出图像主体区域,配合图像识别接口提升识别精度

接口描述

用户向服务请求检测图像中的主体位置。

请求说明

  • HTTP 方法: POST
  • 请求 URL: https://aip.baidubce.com/rest/2.0/image-classify/v1/object_detect
  • URL参数: access_token
  • Header 参数: Content-Type = application/x-www-form-urlencoded
  • Body 参数:见下表
参数 是否必选 类型 可选值范围 说明
image true string - 图像数据,base64 编码,要求 base64 编码后大小不超过 4M,最短边至少 15px,最长边最大 4096px,支持 jpg/png/bmp 格式 。注意:图片需要 base64 编码、去掉编码头后再进行 urlencode
with_face false number - 如果检测主体是人,主体区域是否带上人脸部分,0 - 不带人脸区域,其他 - 带人脸区域,裁剪类需求推荐带人脸,检索/识别类需求推荐不带人脸。默认取 1,带人脸

返回说明

返回参数如下表:

字段 是否必选 类型 说明
log_id uint64 唯一的 log id,用于问题定位
result watermark-location 裁剪结果
+left uint32 表示定位位置的长方形左上顶点的水平坐标
+top uint32 表示定位位置的长方形左上顶点的垂直坐标
+width uint32 表示定位位置的长方形的宽度
+height uint32 表示定位位置的长方形的高度

返回示例如下:

{
  "log_id": 895582300,
  "result": {
    "width": 486,
    "top": 76,
    "left": 134,
    "height": 394
  }
}

C++ 代码实现调用

这里假设已经将环境配置好了,环境配置的文章可以参考 Windows 下使用 Vcpkg 配置百度 AI 图像识别 C++开发环境(VS2017)

为了方便,首先根据返回参数定义了一个结构体,该结构体包括了返回参数中的参数,如下:

struct ObjDetInfo {
    uint32_t left;
    uint32_t top;
    uint32_t width;
    uint32_t height;

    void print() {
        std::cout << std::setw(20) << std::setfill('-') << '\n';
        std::cout << "left: " << left << "\n";
        std::cout << "top: " << top << "\n";
        std::cout << "width: " << width << "\n";
        std::cout << "height: " << height << "\n";
    }

    void draw(cv::Mat &img) {
        cv::Rect rect(left, top, width, height);
        cv::rectangle(img, rect, cv::Scalar(255, 0, 255), 3);
    }
};

ObjInfo 结构体中,定义了一个 print 方法以打印获取的结果,draw 方法以在图像上画出边框。

然后定义了一个类来调用接口并获取结果

class ObjectDetection
{
public:
    ObjectDetection();
    ~ObjectDetection();

    Json::Value request(std::string imgBase64, std::map<std::string, std::string>& options);

    // only get first result
    void getResult(ObjDetInfo& result);

private:
    Json::Value obj_;
    std::string url_;
    // file to save token key
    std::string filename_;
};

类中的私有成员 obj_ 表示返回结果对应的 json 对象。url_ 表示请求的 url,filename_ 表示用于存储 access token 的文件的文件名。

request 函数输入请求图像的 base64 编码以及请求参数,返回一个 json 对象,json 对象中包含请求的结果。

getResult 获取请求的结果。



完整代码如下

util.hutil.cpp 代码参见 (简单调用篇 01) 通用物体和场景识别高级版 - C++ 简单调用

ObjectDetection.h 代码如下:

#pragma once
#include <string>
#include <iostream>
#include <opencv2/opencv.hpp>
#include "util.h"

struct ObjDetInfo {
    uint32_t left;
    uint32_t top;
    uint32_t width;
    uint32_t height;

    void print() {
        std::cout << std::setw(20) << std::setfill('-') << '\n';
        std::cout << "left: " << left << "\n";
        std::cout << "top: " << top << "\n";
        std::cout << "width: " << width << "\n";
        std::cout << "height: " << height << "\n";
    }

    void draw(cv::Mat &img) {
        cv::Rect rect(left, top, width, height);
        cv::rectangle(img, rect, cv::Scalar(255, 0, 255), 3);
    }
};

class ObjectDetection
{
public:
    ObjectDetection();
    ~ObjectDetection();

    Json::Value request(std::string imgBase64, std::map<std::string, std::string>& options);

    // only get first result
    void getResult(ObjDetInfo& result);

private:
    Json::Value obj_;
    std::string url_;
    // file to save token key
    std::string filename_;
};

void objectDetectionTest();

ObjectDetection.cpp 代码如下:

#include "ObjectDetection.h"

ObjectDetection::ObjectDetection()
{
    filename_ = "tokenKey";
    url_ = "https://aip.baidubce.com/rest/2.0/image-classify/v1/object_detect";
}

ObjectDetection::~ObjectDetection()
{
}

Json::Value ObjectDetection::request(std::string imgBase64, std::map<std::string, std::string>& options)
{
    std::string response;
    Json::Value obj;
    std::string token;

    // 1. get HTTP post body
    std::string body;
    mergeHttpPostBody(body, imgBase64, options);

    // 2. get HTTP url with access token
    std::string url = url_;
    getHttpPostUrl(url, filename_, token);

    // 3. post request, response store the result
    int status_code = httpPostRequest(url, body, response);
    if (status_code != CURLcode::CURLE_OK) {
        obj["curl_error_code"] = status_code;
        obj_ = obj;
        return obj; // TODO: maybe should exit
    }

    // 4. make string to json object
    generateJson(response, obj);

    // if access token is invalid or expired, we will get a new one
    if (obj["error_code"].asInt() == 110 || obj["error_code"].asInt() == 111) {
        token = getTokenKey();
        writeFile(filename_, token);
        return request(imgBase64, options);
    }

    obj_ = obj;

    checkErrorWithExit(obj);

    return obj;
}

void ObjectDetection::getResult(ObjDetInfo & result)
{
    result.left = obj_["result"].get("left", "0").asInt();
    result.top = obj_["result"].get("top", "0").asInt();
    result.width = obj_["result"].get("width", "0").asInt();
    result.height = obj_["result"].get("height", "0").asInt();
}

void objectDetectionTest()
{
    std::cout << "size: " << sizeof(ObjDetInfo) << "\n";

    // read image and encode to base64
    std::string img_file = "./images/cat.jpg";
    std::string out;
    readImageFile(img_file.c_str(), out);
    std::string img_base64 = base64_encode(out.c_str(), (int)out.size());

    // set options
    std::map<std::string, std::string> options;
    options["with_face"] = "0";

    Json::Value obj;
    ObjectDetection objDetObj;
    obj = objDetObj.request(img_base64, options);
    //std::cout << (obj.get("result", "null")) << std::endl;
    ObjDetInfo result;
    objDetObj.getResult(result);
    result.print();

    cv::Mat img = cv::imread(img_file);
    result.draw(img);
    cv::namedWindow("Object Detection", cv::WINDOW_NORMAL);
    cv::imshow("Object Detection", img);
    cv::waitKey();
}

main.cpp 代码如下:

#include "util.h"
#include "ObjectDetection.h"
#include <stdlib.h>

int main() {
    objectDetectionTest();

    system("pause");
    return EXIT_SUCCESS;
}

运行结果

原文地址:https://www.cnblogs.com/busyboxs/p/12245433.html

时间: 2024-08-01 21:19:00

(简单调用篇 02) 图像主体检测 - C++ 简单调用的相关文章

iOS开发Swift篇(02) NSThread线程相关简单说明

iOS开发Swift篇(02) NSThread线程相关简单说明 一 说明 1)关于多线程部分的理论知识和OC实现,在之前的博文中已经写明,所以这里不再说明. 2)该文仅仅简单讲解NSThread在swift语境中的一些使用和注意点,别他. 3)本文涉及代码可以从https://github.com/HanGangAndHanMeimei/Code地址获得. 二 NSThread的基本使用和创建 1)基本用法(主线程|当前线程) 1 //1.获得执行该方法的当前线程 2 let currentT

文顶顶 iOS开发UI篇—iOS开发中三种简单的动画设置

iOS开发UI篇—iOS开发中三种简单的动画设置 [在ios开发中,动画是廉价的] 一.首尾式动画 代码示例: // beginAnimations表示此后的代码要“参与到”动画中 [UIView beginAnimations:nil context:nil]; //设置动画时长 [UIView setAnimationDuration:2.0]; self.headImageView.bounds = rect; // commitAnimations,将beginAnimation之后的所

iOS开发UI篇—iOS开发中三种简单的动画设置

iOS开发UI篇—iOS开发中三种简单的动画设置 [在ios开发中,动画是廉价的] 一.首尾式动画 代码示例: // beginAnimations表示此后的代码要“参与到”动画中 [UIView beginAnimations:nil context:nil]; //设置动画时长 [UIView setAnimationDuration:2.0]; self.headImageView.bounds = rect; // commitAnimations,将beginAnimation之后的所

图像物体检测识别中的LBP特征

1        引言 之前讲了人脸识别中的Haar特征,本文则关注人脸检测中的LBP特征,说是对于人脸检测的,其实对于其他物体也能检测,只需修改训练数据集即可.所以本文的题目是物体检测识别,比如可以检测是否汽车是否有车牌号等. 在opencv实现的haar特征的人脸识别算法中,LBP特征也被支持. haar特征的博文链接:http://blog.csdn.net/stdcoutzyx/article/details/34842233. 2        LBP的历史 1996年,Ojala老大

OPENCV图像轮廓检测

前面在图像转换的时候学到canny算子,可以检测出图像的轮廓信息,但是,该算子检测到的轮廓信息还需要我们手动的用眼睛去识别,而实际工程应用中,我们需要得到轮廓的具体数学信息,这就涉及到今天的主题,图像轮廓检测. 一.图像轮廓检测 在opencv中,轮廓对应着一系列的点的集合,opencv提供了一个函数,用来获得这些点的集合 API:void finContours(输入图像,输出轮廓点集,输出向量,int 轮廓检索模式,int 轮廓近似方法,Point 轮廓点的可选偏移量) 注:1.输入图像,是

地图篇-02.地理编码

地图篇-02.地理编码(GeoCoding/ReverseGeoCoding) 上一节给大家简单介绍了一下获取用户位置,用经纬度表示位置.这一节我们来讲讲地理编码. 首先,我们要知道什么是地理编码 概念: 地理编码:指的是将统计资料或是地址信息建立空间坐标关系的过程,称为地理编码.实现了将中文地址或地名描述转换为经纬度表示在地图上(地球表面上)功能. 反地理编码:实现了将地图上(地球表面上)的经纬度转换为中文地址或地名描述. 编码前准备: 在写代码之前,在storyboard中拖几个控件,如下图

用numpy.pad()对图像进行填充及简单的图像处理

三.用numpy.pad()对图像进行填充及简单的图像处理 https://blog.csdn.net/wang454592297/article/details/80854996 一.用numpy.pad()对图像进行填 我们都知道在css的盒子模型中,有padding(内边距)这一属性.同css中的padding类似,在numpy中,numpy.pad()可以跟矩阵添加内边距,这一方法在CNN中的卷积层可以用到,可以影响到卷积后矩阵的维度,其用法如下: numpy.pad(array, pa

图像人脸检测(框出人脸、笑脸、眼睛)

1 # 通过图片识别人脸 2 3 #1.概述: 人脸识别,是基于人的脸部特征信息进行身份识别的一种生物识别技术.用摄像机或摄像头采集含有人脸的图像或视频流,并自动在图像中检测和跟踪人脸,进而对检测到的人脸进行脸部的一系列相关技术,通常也叫做人像识别.面部识别. 4 5 # 2.人脸识别步骤 6 # 1 人脸图像采集及检测 7 # 2 人脸图像预处理 8 # 3 人脸图像特征提取以及匹配与识别 9 10 # 3. 人脸识别的方法 11 # 在OpenCV中主要使用了两种特征(即两种方法)进行人脸检

Unity3D热更新之LuaFramework篇[02]--用Lua创建自己的面板

在上篇文章 Unity3D热更新之LuaFramework篇[01]--从零开始 中,我们了解了怎么获得一个可用的LuaFramework框架. 本篇将我会先介绍一下如何配置Lua开发环境,然后分析在此框架中加载面板的流程,以及如何创建自己的面板. 1.配置Lua开发环境 有一点要说明的是,使用此种方式(ToLua+LuaFramework)做热更新,则意味着你的大部分逻辑都需要改用Lua语言来编写. 因此,开发前得先得配置好Lua开发环境.毕竟,工欲善其事,必先利其器. 环境配置大概分以下三个