2019-02-19

pcDuino9 AI视觉边缘计算开发套件开发使用分享



pcDuino9 AI视觉边缘计算开发套件是一款针对图像分析的开发套件,套件包含采用hi3516D方案的普通IPC和pcDuino9嵌入式AI视觉边缘计算模块。套件主要是通过pcDuino9嵌入式AI视觉边缘计算模块,来处理从hi3516D上获取的视频流,并对视频流进行一系列的分析处理。该套件为开发者搭建了基础开发环境,提供了由pcDuino9从hi3516D上获取的视频帧,开发者可在帧图上自由的实现各种图片开发,例如人脸检测、车牌检测、物体检测等AI图像分析处理功能。同时提供开放的API接口,开发者可以把在pcDuino9上处理完成的信息回传到hi3516D上,并可在hi3516D上对检测到的图片进行删选,然后通过FTP输出。


基本框架


已提供环境:

[if !supportLists]1.   [endif]pcDuino9从hi3516D获取视频帧

[if !supportLists]2.   [endif]把开发者分析处理后的信息回传到hi3516D上

[if !supportLists]3.   [endif]在hi3516D上对分析处理的图片进行质量筛选,选择质量优的图片通过FTP输出

开发举例:

[if !supportLists]1.   [endif]在pcDuino9上对帧图进行各种开发,如:人脸检测、车牌检测、物体检测等AI图像分析处理。

[if !supportLists]2.   [endif]开发者可对通过FTP输出的分析检测的图片进行其他应用上的使用

[if !supportLists]3.   [endif]………  

 

开放SDK资料

[if !supportLists]1.   [endif]如何获取hi3516D视频帧?

HI3516将BT1120数据传输到PCDUINO

9。PCDUINO 9通过LT8918将BT1120数据转换成MIPI信号,然后接收。目前支持640x480 60fps帧数据传输。我们封装了协议层,使其类似于opencv样式。在读取帧数据时,我们将返回帧号,该帧号由3516传输,是用于数据交互的同步帧号。

#include

#include

#include "C4L2.hpp"

#include

using namespace std;

using namespace cv;

int main(int argc,char *argv[])

{

string dev = "/dev/video2";

C4L2Capture *cap = new C4L2Capture;

int ret = cap->initialzer(dev);

if(ret < 0)

{

cout <<"C4L2Capture

initialze failed... \n";

return -1;

}

Mat frame;

while(true)

{

unsigned int syn = 0;

cap->read(frame, syn);

if(frame.empty())

{

cout << "this frame is empty

...\n";


break;

}

cv::imshow("DeepCam LLC",frame);

cv::waitKey(10);

}

cap->destroy();

delete cap;

return 0;

}

[if !supportLists]2.   [endif]如何优化网络并运行物体检测?

PcDuino9有一个四核Cortex-A17 1.8GHz的CPU和一个ARM MALI-T764的GPU。如果您想在CPU上运行网络,可以参考NCNN;如果您想在GPU上运行网络,可以参考MACE。

CPU Benchmark:



物体检测:

#include

#include

#include

#include

#include

#include "net.h"

class Noop : public ncnn::Layer {};

DEFINE_LAYER_CREATOR(Noop)

struct Object

{

cv::Rect_ rect;

int label;

float prob;

};

static int detect_mobilenetv2(const cv::Mat& bgr, std::vector& objects)

{

ncnn::Net mobilenetv2;

mobilenetv2.register_custom_layer("Silence", Noop_layer_creator);

// original pretrained model fromhttps://github.com/chuanqi305/MobileNetv2-SSDLite

// https://github.com/chuanqi305/MobileNetv2-

SSDLite/blob/master/ssdlite/voc/deploy.prototxt

mobilenetv2.load_param("mobilenetv2_ssdlite_voc.param");

mobilenetv2.load_model("mobilenetv2_ssdlite_voc.bin");

const int target_size = 300;

int img_w = bgr.cols;

int img_h = bgr.rows;

ncnn::Mat in = ncnn::Mat::from_pixels_resize(bgr.data, ncnn::Mat::PIXEL_BGR,

bgr.cols, bgr.rows, target_size, target_size);

const float mean_vals[3] = {127.5f, 127.5f, 127.5f};

const float norm_vals[3] = {1.0/127.5,1.0/127.5,1.0/127.5};

in.substract_mean_normalize(mean_vals, norm_vals);

ncnn::Extractor ex = mobilenetv2.create_extractor();

ex.set_light_mode(true);

ex.set_num_threads(4);

ex.input("data", in);

ncnn::Mat out;

ex.extract("detection_out",out);

// printf("%d %d %d\n", out.w, out.h, out.c);

objects.clear();

for (int i=0; i

{

const float* values = out.row(i);

Object object;

object.label = values[0];

object.prob = values[1];

object.rect.x = values[2] * img_w;

object.rect.y = values[3] * img_h;

object.rect.width = values[4] * img_w - object.rect.x;

object.rect.height = values[5] * img_h - object.rect.y;

objects.push_back(object);

}

return 0;

}

static void draw_objects(const cv::Mat& bgr, const std::vector& objects)

{

static const char* class_names[] = {"background",

"aeroplane", "bicycle", "bird", "boat",

"bottle", "bus", "car", "cat", "chair",

"cow", "diningtable", "dog", "horse",

"motorbike", "person", "pottedplant",

"sheep", "sofa", "train", "tvmonitor"};

cv::Mat image = bgr.clone();

for (size_t i = 0; i < objects.size(); i++)

{

const Object& obj = objects[i];

fprintf(stderr, "%d = %.5f at %.2f %.2f %.2f x

%.2f\n", obj.label, obj.prob,

obj.rect.x, obj.rect.y, obj.rect.width, obj.rect.height);

cv::rectangle(image, obj.rect, cv::Scalar(255, 0, 0));

char text[256];

sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100);

int baseLine = 0;

cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1,

&baseLine);

int x = obj.rect.x;

int y = obj.rect.y - label_size.height - baseLine;

if (y < 0)

y = 0;

if (x + label_size.width > image.cols)

x = image.cols - label_size.width;

cv::rectangle(image, cv::Rect(cv::Point(x, y),

cv::Size(label_size.width, label_size.height +

baseLine)),

cv::Scalar(255, 255, 255), CV_FILLED);

cv::putText(image, text, cv::Point(x, y + label_size.height),

cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));

}

cv::imshow("image", image);

cv::waitKey(0);

}

int main(int argc, char** argv)

{

if (argc != 2)

{

fprintf(stderr, "Usage: %s [imagepath]\n", argv[0]);

return -1;

}

const char* imagepath = argv[1];

cv::Mat m = cv::imread(imagepath, CV_LOAD_IMAGE_COLOR);

if (m.empty())

{

fprintf(stderr, "cv::imread %s failed\n", imagepath);

return -1;

}

std::vector objects;

detect_mobilenetv2(m, objects);

draw_objects(m, objects);

return 0;

}

[if !supportLists]3.   [endif]如何和IPC通信?

我们提供一个开放式API接口。开发人员可以将pcDuino9上处理的信息返回到HI3516D,在HI3516D上对检测到的图像进行优化选择,然后通过ftp输出。

#include

#include "json/json.h"

#include "spi_slave.hpp"

using namespace std;

struct DetectInfo

{

int ID; //tracker ID

int x; // bbox left top x

int y; // bbox left top y

int w; // bbox width

int h; // bbox height;

int syn; // sync frame count

int quality; // object quality (0 -- 100)

int confidence; // object confidence (0 -- 100)

};

void detect_out(std::vector &detectBoxs, std::string &message)

{

Json::Value root;

Json::Value faces;

Json::FastWriter

writer;

for(int i = 0; i < detectBoxs.size(); i++)

{

Json::Value face;

face["x"] = detectBoxs[i].x;

face["y"] = detectBoxs[i].y;

face["w"] = detectBoxs[i].w;

face["h"] = detectBoxs[i].h;

face["id"] = detectBoxs[i].ID;

face["s"] = detectBoxs[i].ID;

face["q"] = detectBoxs[i].quality;

face["c"] = detectBoxs[i].confidence;

faces.append(face);

}

root["faces"] = faces;

message = writer.write(root);

}

int main(int argc, char *argv[])

{

unsigned char SOF;

spi_slave *rk3288_spi = new spi_slave;

if(rk3288_spi->init() < 0)

{

printf("spi test spi_init

error.\n");

return -1;

}

unsigned

char *r_buf = new unsigned char[MAX_DATA_LENGTH];

unsigned char *w_buf = new unsigned char[MAX_DATA_LENGTH];

while (true)

{

std::string message;

std::vector detectBoxs;

//Do object detect get message

detect_out(detectBoxs, message);

SOF = 0;

memset(r_buf, 0, MAX_DATA_LENGTH);

strcpy((char *)w_buf,message.c_str());

int ret = rk3288_spi->spi_slave_xfer(r_buf,MAX_DATA_LENGTH, w_buf,

MAX_DATA_LENGTH, &SOF);

if(ret > 0 )

{

memset(w_buf, 0, MAX_DATA_LENGTH);

if(SPI_M_TX == SOF)

{

std::cout <<"recv

: " <

usleep(30000);

}

}

else

{

std::cout<<"get

message failed!\n";

break;

}

}

return 0;

}

 

硬件介绍

pcDuino9嵌入式AI视觉边缘计算模块介绍

接口图



引脚图

 



原文链接:

http://linksprite.com/wiki/index.php?title=PcDuino9_AI_visual_edge_computing_development_kit

D

你可能感兴趣的:(2019-02-19)