Yolov 3 모델 프레임 워 크 darknet 연구 (4) cpu + opencv 4.0.1 에서 yolov 3 모델 을 직접 실행 합 니 다.
6413 단어 딥 러 닝
배경
GPU 에서 데 이 터 를 훈련 시 키 고 GPU 에서 추 리 를 하 는 것 은 이미 일상적인 일이 다.그러나 현실 적 으로 GPU 가 잘 훈련 되 기 를 바 라 는 알고리즘 모델 이 서로 다른 cpu 플랫폼 에서 추 리 를 할 수 있 도록 요구 하 는 장면 이 많다. 예 를 들 어 ARM, intel cpu 등 이다.여기 서 intel cpu 를 예 로 들 어 두 가지 방식 을 소개 합 니 다.
1) darknet c 코드 를 다운로드 하여 lib 로 만 든 다음 lib 인 터 페 이 스 를 호출 하여 이미지 인식 을 한다.
2) opencv 3.43 이상 버 전 을 설치 한 후 API 를 호출 하여 이미지 인식
방법 2 장점 이 뚜렷 하 다.
a) 공식 darknet 은 Makefile 만 Liux 에서 컴 파일 하고 windows 플랫폼 의 컴 파일 은 스스로 해결 할 수 있 습 니 다.
b) 더 중요 한 것 은 opencv 는 intel cpu 에 대해 많은 명령 집합 을 최적화 시 켰 기 때문에 같은 yolo 3 의 알고리즘 모델 에 대해 추 리 를 해 야 한다. 방법 1 은 6s 정도 이 고 opencv 방식 은 600 ms 정도 밖 에 안 된다.
여기 서 한 가지 더 설명해 야 한다. 인터넷 에서 opencv API 로 추리 하 는 시간 은 220 ms 에 불과 하 다 고 발 표 했 지만 나의 실험 결 과 는 600 ms 에 달 했다. 대략 두 가지 이유 가 있다.
(1) 인터넷 상의 신경 망 크기 는 416 x 416 이다. 제 사 이 즈 는 608 x608 입 니 다. 대략 전 자 는 1.5x 1.5 = 2.25
(2) CPU 가 다르다.인터넷 에 i7 6 핵 이 있어 야 돼 요. 내 것 은 i54 캐 시 만 있어 도 많이 부족 하 다.
이루어지다
1。 네트워크 프로필, 가중치, 인식 할 그림 과 형식 이름 을 포함 한 입력 매개 변 수 를 준비 하 십시오.
//
String model_config = "xxx/yolov3_2019_01.cfg";
String model_weights = "xxx/yolov3-2019_01_final.weights";
String image_file = "xxx/img20190108_000544.jpg";
vector class_names = get_class_names("xxx/class_2019_01.names");
2。opencv API 로 네트워크 모델 불 러 오기
// Load the network
Net net = readNetFromDarknet(model_config, model_weights);
if (net.empty())
{
printf("loading network fails
");
return 1;
}
net.setPreferableBackend(DNN_BACKEND_OPENCV);
net.setPreferableTarget(DNN_TARGET_CPU);
3。그림 을 읽 고 blob 4 차원 장 량 을 변환 하 는 동시에 네트워크 모델 size 로 크기 를 조정 합 니 다.
// Create a 4D blob from a frame.
Mat frame, blob;
frame = imread(image_file);
if (frame.empty())
{
printf("reading image fails
");
return 1;
}
int newwork_width = 608;
int newwork_height = 608;
blobFromImage(frame, blob, 1 / 255.0, Size(newwork_width, newwork_height), Scalar(0, 0, 0), true, false);
4。blob 를 모델 에 주입 하고 전방 향 예측 (최 소모 시간 부분)
//Sets the input to the network
net.setInput(blob);
// Runs the forward pass to get output of the output layers
vector outs;
net.forward(outs, getOutputsNames(net));
식 별 된 outs 는 3 개의 mat 형식 데이터 인 데 왜 3 입 니까?darknet 에 3 개의 yolo 검 측 출력 층 이 있 으 니까!이 3 개의 mat 득 shape 는 각각 (4 + 1 + 5) x19x19x 3, (4 + 1 + 5) x38x 38x 3 이다. (4+1+5)x76x76x3 주: 내 모델 안에 클 라 스 수량 은 5
5。outs 에서 신뢰 도가 한도 값 보다 높 은 box 를 선택 한 다음 에 NMS 를 추가 로 걸 러 냅 니 다.
// Remove the bounding boxes with low confidence
postprocess(class_names, frame, outs);
//
// Initialize the parameters
float confThreshold = 0.5; // Confidence threshold
float nmsThreshold = 0.4; // Non-maximum suppression threshold
// Draw the predicted bounding box
void drawPred(vectorclasses, int classId, float conf, int left, int top, int right, int bottom, Mat& frame)
{
//Draw a rectangle displaying the bounding box
rectangle(frame, Point(left, top), Point(right, bottom), Scalar(0, 0, 255));
//Get the label for the class name and its confidence
string label = format("%.2f", conf);//
// ,
if (!classes.empty())
{
CV_Assert(classId < (int)classes.size());
label = classes[classId] + ":" + label;
}
//Display the label at the top of the bounding box
int baseLine;
Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
top = max(top, labelSize.height);
//
putText(frame, label, Point(left, top), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255, 255, 255));
}
// Remove the bounding boxes with low confidence using non-maxima suppression
void postprocess(vectorclasses, Mat& frame, const vector& outs)
{
vector classIds;
vector confidences;
vector boxes;
for (size_t i = 0; i < outs.size(); ++i)
{
// Scan through all the bounding boxes output from the network and keep only the
// ones with high confidence scores. Assign the box's class label as the class
// with the highest score for the box.
float* data = (float*)outs[i].data;
for (int j = 0; j < outs[i].rows; ++j, data += outs[i].cols)
{
int a = outs[i].cols;// + + + =2+2+1+80
int b = outs[i].rows;// 507
Mat scores = outs[i].row(j).colRange(5, outs[i].cols);// , 80 ,
Point classIdPoint;
double confidence;
// Get the value and location of the maximum score
minMaxLoc(scores, 0, &confidence, 0, &classIdPoint);//
if (confidence > confThreshold)//
{
int centerX = (int)(data[0] * frame.cols);
int centerY = (int)(data[1] * frame.rows);
int width = (int)(data[2] * frame.cols);
int height = (int)(data[3] * frame.rows);
int left = centerX - width / 2;
int top = centerY - height / 2;
classIds.push_back(classIdPoint.x);
confidences.push_back((float)confidence);
boxes.push_back(Rect(left, top, width, height));
}
}
}
// Perform non maximum suppression to eliminate redundant overlapping boxes with
// lower confidences
vector indices;
NMSBoxes(boxes, confidences, confThreshold, nmsThreshold, indices);// 、 、 、 、 ( )
for (size_t i = 0; i < indices.size(); ++i)
{
int idx = indices[i];//
Rect box = boxes[idx];// ( )
drawPred(classes, classIds[idx], confidences[idx], box.x, box.y,
box.x + box.width, box.y + box.height, frame);
}
}
// Get the names of the output layers
vector getOutputsNames(const Net& net)
{
static vector names;
if (names.empty())
{
//Get the indices of the output layers, i.e. the layers with unconnected outputs
vector outLayers = net.getUnconnectedOutLayers();
//get the names of all the layers in the network
vector layersNames = net.getLayerNames();
// Get the names of the output layers in names
names.resize(outLayers.size());
for (size_t i = 0; i < outLayers.size(); ++i)
names[i] = layersNames[outLayers[i] - 1];
}
return names;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
caffe 데이터 구조 깊이 학습 (4) - blob 데이터 구조 blob. hpp 파일 상세 해석이 줄 은 shape 벡터 를 통 해 Blob 의 모양 을 바 꾸 는 또 다른 변형 함 수 를 정의 합 니 다. 이 줄 은 Blob 모양 의 함 수 를 읽 고 구성원 변수 shape 로 돌아 가 는 것 을 정의 합 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.