mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 00:03:03 +04:00
dnn: move samples
This commit is contained in:
@@ -1 +0,0 @@
|
||||
*.caffemodel
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,143 +0,0 @@
|
||||
/**M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
#include <opencv2/dnn.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
using namespace cv;
|
||||
using namespace cv::dnn;
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
using namespace std;
|
||||
|
||||
/* Find best class for the blob (i. e. class with maximal probability) */
|
||||
void getMaxClass(const Mat &probBlob, int *classId, double *classProb)
|
||||
{
|
||||
Mat probMat = probBlob.reshape(1, 1); //reshape the blob to 1x1000 matrix
|
||||
Point classNumber;
|
||||
|
||||
minMaxLoc(probMat, NULL, classProb, NULL, &classNumber);
|
||||
*classId = classNumber.x;
|
||||
}
|
||||
|
||||
std::vector<String> readClassNames(const char *filename = "synset_words.txt")
|
||||
{
|
||||
std::vector<String> classNames;
|
||||
|
||||
std::ifstream fp(filename);
|
||||
if (!fp.is_open())
|
||||
{
|
||||
std::cerr << "File with classes labels not found: " << filename << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
std::string name;
|
||||
while (!fp.eof())
|
||||
{
|
||||
std::getline(fp, name);
|
||||
if (name.length())
|
||||
classNames.push_back( name.substr(name.find(' ')+1) );
|
||||
}
|
||||
|
||||
fp.close();
|
||||
return classNames;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
cv::dnn::initModule(); //Required if OpenCV is built as static libs
|
||||
|
||||
String modelTxt = "bvlc_googlenet.prototxt";
|
||||
String modelBin = "bvlc_googlenet.caffemodel";
|
||||
String imageFile = (argc > 1) ? argv[1] : "space_shuttle.jpg";
|
||||
|
||||
//! [Read and initialize network]
|
||||
Net net = dnn::readNetFromCaffe(modelTxt, modelBin);
|
||||
//! [Read and initialize network]
|
||||
|
||||
//! [Check that network was read successfully]
|
||||
if (net.empty())
|
||||
{
|
||||
std::cerr << "Can't load network by using the following files: " << std::endl;
|
||||
std::cerr << "prototxt: " << modelTxt << std::endl;
|
||||
std::cerr << "caffemodel: " << modelBin << std::endl;
|
||||
std::cerr << "bvlc_googlenet.caffemodel can be downloaded here:" << std::endl;
|
||||
std::cerr << "http://dl.caffe.berkeleyvision.org/bvlc_googlenet.caffemodel" << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
//! [Check that network was read successfully]
|
||||
|
||||
//! [Prepare blob]
|
||||
Mat img = imread(imageFile);
|
||||
if (img.empty())
|
||||
{
|
||||
std::cerr << "Can't read image from the file: " << imageFile << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
//GoogLeNet accepts only 224x224 RGB-images
|
||||
Mat inputBlob = blobFromImage(img, 1, Size(224, 224),
|
||||
Scalar(104, 117, 123)); //Convert Mat to batch of images
|
||||
//! [Prepare blob]
|
||||
|
||||
//! [Set input blob]
|
||||
net.setInput(inputBlob, "data"); //set the network input
|
||||
//! [Set input blob]
|
||||
|
||||
//! [Make forward pass]
|
||||
Mat prob = net.forward("prob"); //compute output
|
||||
//! [Make forward pass]
|
||||
|
||||
//! [Gather output]
|
||||
int classId;
|
||||
double classProb;
|
||||
getMaxClass(prob, &classId, &classProb);//find the best class
|
||||
//! [Gather output]
|
||||
|
||||
//! [Print results]
|
||||
std::vector<String> classNames = readClassNames();
|
||||
std::cout << "Best class: #" << classId << " '" << classNames.at(classId) << "'" << std::endl;
|
||||
std::cout << "Probability: " << classProb * 100 << "%" << std::endl;
|
||||
//! [Print results]
|
||||
|
||||
return 0;
|
||||
} //main
|
||||
@@ -1,20 +0,0 @@
|
||||
Unlabeled 0 0 0
|
||||
Road 128 64 128
|
||||
Sidewalk 244 35 232
|
||||
Building 70 70 70
|
||||
Wall 102 102 156
|
||||
Fence 190 153 153
|
||||
Pole 153 153 153
|
||||
TrafficLight 250 170 30
|
||||
TrafficSign 220 220 0
|
||||
Vegetation 107 142 35
|
||||
Terrain 152 251 152
|
||||
Sky 70 130 180
|
||||
Person 220 20 60
|
||||
Rider 255 0 0
|
||||
Car 0 0 142
|
||||
Truck 0 0 70
|
||||
Bus 0 60 100
|
||||
Train 0 80 100
|
||||
Motorcycle 0 0 230
|
||||
Bicycle 119 11 32
|
||||
@@ -1,502 +0,0 @@
|
||||
#
|
||||
# This prototxt is based on voc-fcn32s/val.prototxt file from
|
||||
# https://github.com/shelhamer/fcn.berkeleyvision.org, which is distributed under
|
||||
# Caffe (BSD) license:
|
||||
# http://caffe.berkeleyvision.org/model_zoo.html#bvlc-model-license
|
||||
#
|
||||
name: "voc-fcn32s"
|
||||
input: "data"
|
||||
input_dim: 1
|
||||
input_dim: 3
|
||||
input_dim: 500
|
||||
input_dim: 500
|
||||
layer {
|
||||
name: "conv1_1"
|
||||
type: "Convolution"
|
||||
bottom: "data"
|
||||
top: "conv1_1"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
pad: 100
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu1_1"
|
||||
type: "ReLU"
|
||||
bottom: "conv1_1"
|
||||
top: "conv1_1"
|
||||
}
|
||||
layer {
|
||||
name: "conv1_2"
|
||||
type: "Convolution"
|
||||
bottom: "conv1_1"
|
||||
top: "conv1_2"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu1_2"
|
||||
type: "ReLU"
|
||||
bottom: "conv1_2"
|
||||
top: "conv1_2"
|
||||
}
|
||||
layer {
|
||||
name: "pool1"
|
||||
type: "Pooling"
|
||||
bottom: "conv1_2"
|
||||
top: "pool1"
|
||||
pooling_param {
|
||||
pool: MAX
|
||||
kernel_size: 2
|
||||
stride: 2
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_1"
|
||||
type: "Convolution"
|
||||
bottom: "pool1"
|
||||
top: "conv2_1"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu2_1"
|
||||
type: "ReLU"
|
||||
bottom: "conv2_1"
|
||||
top: "conv2_1"
|
||||
}
|
||||
layer {
|
||||
name: "conv2_2"
|
||||
type: "Convolution"
|
||||
bottom: "conv2_1"
|
||||
top: "conv2_2"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu2_2"
|
||||
type: "ReLU"
|
||||
bottom: "conv2_2"
|
||||
top: "conv2_2"
|
||||
}
|
||||
layer {
|
||||
name: "pool2"
|
||||
type: "Pooling"
|
||||
bottom: "conv2_2"
|
||||
top: "pool2"
|
||||
pooling_param {
|
||||
pool: MAX
|
||||
kernel_size: 2
|
||||
stride: 2
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_1"
|
||||
type: "Convolution"
|
||||
bottom: "pool2"
|
||||
top: "conv3_1"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 256
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu3_1"
|
||||
type: "ReLU"
|
||||
bottom: "conv3_1"
|
||||
top: "conv3_1"
|
||||
}
|
||||
layer {
|
||||
name: "conv3_2"
|
||||
type: "Convolution"
|
||||
bottom: "conv3_1"
|
||||
top: "conv3_2"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 256
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu3_2"
|
||||
type: "ReLU"
|
||||
bottom: "conv3_2"
|
||||
top: "conv3_2"
|
||||
}
|
||||
layer {
|
||||
name: "conv3_3"
|
||||
type: "Convolution"
|
||||
bottom: "conv3_2"
|
||||
top: "conv3_3"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 256
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu3_3"
|
||||
type: "ReLU"
|
||||
bottom: "conv3_3"
|
||||
top: "conv3_3"
|
||||
}
|
||||
layer {
|
||||
name: "pool3"
|
||||
type: "Pooling"
|
||||
bottom: "conv3_3"
|
||||
top: "pool3"
|
||||
pooling_param {
|
||||
pool: MAX
|
||||
kernel_size: 2
|
||||
stride: 2
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_1"
|
||||
type: "Convolution"
|
||||
bottom: "pool3"
|
||||
top: "conv4_1"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 512
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu4_1"
|
||||
type: "ReLU"
|
||||
bottom: "conv4_1"
|
||||
top: "conv4_1"
|
||||
}
|
||||
layer {
|
||||
name: "conv4_2"
|
||||
type: "Convolution"
|
||||
bottom: "conv4_1"
|
||||
top: "conv4_2"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 512
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu4_2"
|
||||
type: "ReLU"
|
||||
bottom: "conv4_2"
|
||||
top: "conv4_2"
|
||||
}
|
||||
layer {
|
||||
name: "conv4_3"
|
||||
type: "Convolution"
|
||||
bottom: "conv4_2"
|
||||
top: "conv4_3"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 512
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu4_3"
|
||||
type: "ReLU"
|
||||
bottom: "conv4_3"
|
||||
top: "conv4_3"
|
||||
}
|
||||
layer {
|
||||
name: "pool4"
|
||||
type: "Pooling"
|
||||
bottom: "conv4_3"
|
||||
top: "pool4"
|
||||
pooling_param {
|
||||
pool: MAX
|
||||
kernel_size: 2
|
||||
stride: 2
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_1"
|
||||
type: "Convolution"
|
||||
bottom: "pool4"
|
||||
top: "conv5_1"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 512
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu5_1"
|
||||
type: "ReLU"
|
||||
bottom: "conv5_1"
|
||||
top: "conv5_1"
|
||||
}
|
||||
layer {
|
||||
name: "conv5_2"
|
||||
type: "Convolution"
|
||||
bottom: "conv5_1"
|
||||
top: "conv5_2"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 512
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu5_2"
|
||||
type: "ReLU"
|
||||
bottom: "conv5_2"
|
||||
top: "conv5_2"
|
||||
}
|
||||
layer {
|
||||
name: "conv5_3"
|
||||
type: "Convolution"
|
||||
bottom: "conv5_2"
|
||||
top: "conv5_3"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 512
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu5_3"
|
||||
type: "ReLU"
|
||||
bottom: "conv5_3"
|
||||
top: "conv5_3"
|
||||
}
|
||||
layer {
|
||||
name: "pool5"
|
||||
type: "Pooling"
|
||||
bottom: "conv5_3"
|
||||
top: "pool5"
|
||||
pooling_param {
|
||||
pool: MAX
|
||||
kernel_size: 2
|
||||
stride: 2
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "fc6"
|
||||
type: "Convolution"
|
||||
bottom: "pool5"
|
||||
top: "fc6"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 4096
|
||||
pad: 0
|
||||
kernel_size: 7
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu6"
|
||||
type: "ReLU"
|
||||
bottom: "fc6"
|
||||
top: "fc6"
|
||||
}
|
||||
layer {
|
||||
name: "fc7"
|
||||
type: "Convolution"
|
||||
bottom: "fc6"
|
||||
top: "fc7"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 4096
|
||||
pad: 0
|
||||
kernel_size: 1
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu7"
|
||||
type: "ReLU"
|
||||
bottom: "fc7"
|
||||
top: "fc7"
|
||||
}
|
||||
layer {
|
||||
name: "score_fr"
|
||||
type: "Convolution"
|
||||
bottom: "fc7"
|
||||
top: "score_fr"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 21
|
||||
pad: 0
|
||||
kernel_size: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "upscore"
|
||||
type: "Deconvolution"
|
||||
bottom: "score_fr"
|
||||
top: "upscore"
|
||||
param {
|
||||
lr_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 21
|
||||
bias_term: false
|
||||
kernel_size: 64
|
||||
stride: 32
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "score"
|
||||
type: "Crop"
|
||||
bottom: "upscore"
|
||||
bottom: "data"
|
||||
top: "score"
|
||||
crop_param {
|
||||
axis: 2
|
||||
offset: 19
|
||||
}
|
||||
}
|
||||
@@ -1,612 +0,0 @@
|
||||
#
|
||||
# This prototxt is based on voc-fcn8s/val.prototxt file from
|
||||
# https://github.com/shelhamer/fcn.berkeleyvision.org, which is distributed under
|
||||
# Caffe (BSD) license:
|
||||
# http://caffe.berkeleyvision.org/model_zoo.html#bvlc-model-license
|
||||
#
|
||||
name: "voc-fcn8s"
|
||||
input: "data"
|
||||
input_dim: 1
|
||||
input_dim: 3
|
||||
input_dim: 500
|
||||
input_dim: 500
|
||||
layer {
|
||||
name: "conv1_1"
|
||||
type: "Convolution"
|
||||
bottom: "data"
|
||||
top: "conv1_1"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
pad: 100
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu1_1"
|
||||
type: "ReLU"
|
||||
bottom: "conv1_1"
|
||||
top: "conv1_1"
|
||||
}
|
||||
layer {
|
||||
name: "conv1_2"
|
||||
type: "Convolution"
|
||||
bottom: "conv1_1"
|
||||
top: "conv1_2"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu1_2"
|
||||
type: "ReLU"
|
||||
bottom: "conv1_2"
|
||||
top: "conv1_2"
|
||||
}
|
||||
layer {
|
||||
name: "pool1"
|
||||
type: "Pooling"
|
||||
bottom: "conv1_2"
|
||||
top: "pool1"
|
||||
pooling_param {
|
||||
pool: MAX
|
||||
kernel_size: 2
|
||||
stride: 2
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_1"
|
||||
type: "Convolution"
|
||||
bottom: "pool1"
|
||||
top: "conv2_1"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu2_1"
|
||||
type: "ReLU"
|
||||
bottom: "conv2_1"
|
||||
top: "conv2_1"
|
||||
}
|
||||
layer {
|
||||
name: "conv2_2"
|
||||
type: "Convolution"
|
||||
bottom: "conv2_1"
|
||||
top: "conv2_2"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu2_2"
|
||||
type: "ReLU"
|
||||
bottom: "conv2_2"
|
||||
top: "conv2_2"
|
||||
}
|
||||
layer {
|
||||
name: "pool2"
|
||||
type: "Pooling"
|
||||
bottom: "conv2_2"
|
||||
top: "pool2"
|
||||
pooling_param {
|
||||
pool: MAX
|
||||
kernel_size: 2
|
||||
stride: 2
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_1"
|
||||
type: "Convolution"
|
||||
bottom: "pool2"
|
||||
top: "conv3_1"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 256
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu3_1"
|
||||
type: "ReLU"
|
||||
bottom: "conv3_1"
|
||||
top: "conv3_1"
|
||||
}
|
||||
layer {
|
||||
name: "conv3_2"
|
||||
type: "Convolution"
|
||||
bottom: "conv3_1"
|
||||
top: "conv3_2"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 256
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu3_2"
|
||||
type: "ReLU"
|
||||
bottom: "conv3_2"
|
||||
top: "conv3_2"
|
||||
}
|
||||
layer {
|
||||
name: "conv3_3"
|
||||
type: "Convolution"
|
||||
bottom: "conv3_2"
|
||||
top: "conv3_3"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 256
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu3_3"
|
||||
type: "ReLU"
|
||||
bottom: "conv3_3"
|
||||
top: "conv3_3"
|
||||
}
|
||||
layer {
|
||||
name: "pool3"
|
||||
type: "Pooling"
|
||||
bottom: "conv3_3"
|
||||
top: "pool3"
|
||||
pooling_param {
|
||||
pool: MAX
|
||||
kernel_size: 2
|
||||
stride: 2
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_1"
|
||||
type: "Convolution"
|
||||
bottom: "pool3"
|
||||
top: "conv4_1"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 512
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu4_1"
|
||||
type: "ReLU"
|
||||
bottom: "conv4_1"
|
||||
top: "conv4_1"
|
||||
}
|
||||
layer {
|
||||
name: "conv4_2"
|
||||
type: "Convolution"
|
||||
bottom: "conv4_1"
|
||||
top: "conv4_2"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 512
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu4_2"
|
||||
type: "ReLU"
|
||||
bottom: "conv4_2"
|
||||
top: "conv4_2"
|
||||
}
|
||||
layer {
|
||||
name: "conv4_3"
|
||||
type: "Convolution"
|
||||
bottom: "conv4_2"
|
||||
top: "conv4_3"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 512
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu4_3"
|
||||
type: "ReLU"
|
||||
bottom: "conv4_3"
|
||||
top: "conv4_3"
|
||||
}
|
||||
layer {
|
||||
name: "pool4"
|
||||
type: "Pooling"
|
||||
bottom: "conv4_3"
|
||||
top: "pool4"
|
||||
pooling_param {
|
||||
pool: MAX
|
||||
kernel_size: 2
|
||||
stride: 2
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_1"
|
||||
type: "Convolution"
|
||||
bottom: "pool4"
|
||||
top: "conv5_1"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 512
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu5_1"
|
||||
type: "ReLU"
|
||||
bottom: "conv5_1"
|
||||
top: "conv5_1"
|
||||
}
|
||||
layer {
|
||||
name: "conv5_2"
|
||||
type: "Convolution"
|
||||
bottom: "conv5_1"
|
||||
top: "conv5_2"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 512
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu5_2"
|
||||
type: "ReLU"
|
||||
bottom: "conv5_2"
|
||||
top: "conv5_2"
|
||||
}
|
||||
layer {
|
||||
name: "conv5_3"
|
||||
type: "Convolution"
|
||||
bottom: "conv5_2"
|
||||
top: "conv5_3"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 512
|
||||
pad: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu5_3"
|
||||
type: "ReLU"
|
||||
bottom: "conv5_3"
|
||||
top: "conv5_3"
|
||||
}
|
||||
layer {
|
||||
name: "pool5"
|
||||
type: "Pooling"
|
||||
bottom: "conv5_3"
|
||||
top: "pool5"
|
||||
pooling_param {
|
||||
pool: MAX
|
||||
kernel_size: 2
|
||||
stride: 2
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "fc6"
|
||||
type: "Convolution"
|
||||
bottom: "pool5"
|
||||
top: "fc6"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 4096
|
||||
pad: 0
|
||||
kernel_size: 7
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu6"
|
||||
type: "ReLU"
|
||||
bottom: "fc6"
|
||||
top: "fc6"
|
||||
}
|
||||
layer {
|
||||
name: "fc7"
|
||||
type: "Convolution"
|
||||
bottom: "fc6"
|
||||
top: "fc7"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 4096
|
||||
pad: 0
|
||||
kernel_size: 1
|
||||
stride: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "relu7"
|
||||
type: "ReLU"
|
||||
bottom: "fc7"
|
||||
top: "fc7"
|
||||
}
|
||||
layer {
|
||||
name: "score_fr"
|
||||
type: "Convolution"
|
||||
bottom: "fc7"
|
||||
top: "score_fr"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 21
|
||||
pad: 0
|
||||
kernel_size: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "upscore2"
|
||||
type: "Deconvolution"
|
||||
bottom: "score_fr"
|
||||
top: "upscore2"
|
||||
param {
|
||||
lr_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 21
|
||||
bias_term: false
|
||||
kernel_size: 4
|
||||
stride: 2
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "score_pool4"
|
||||
type: "Convolution"
|
||||
bottom: "pool4"
|
||||
top: "score_pool4"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 21
|
||||
pad: 0
|
||||
kernel_size: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "score_pool4c"
|
||||
type: "Crop"
|
||||
bottom: "score_pool4"
|
||||
bottom: "upscore2"
|
||||
top: "score_pool4c"
|
||||
crop_param {
|
||||
axis: 2
|
||||
offset: 5
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "fuse_pool4"
|
||||
type: "Eltwise"
|
||||
bottom: "upscore2"
|
||||
bottom: "score_pool4c"
|
||||
top: "fuse_pool4"
|
||||
eltwise_param {
|
||||
operation: SUM
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "upscore_pool4"
|
||||
type: "Deconvolution"
|
||||
bottom: "fuse_pool4"
|
||||
top: "upscore_pool4"
|
||||
param {
|
||||
lr_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 21
|
||||
bias_term: false
|
||||
kernel_size: 4
|
||||
stride: 2
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "score_pool3"
|
||||
type: "Convolution"
|
||||
bottom: "pool3"
|
||||
top: "score_pool3"
|
||||
param {
|
||||
lr_mult: 1
|
||||
decay_mult: 1
|
||||
}
|
||||
param {
|
||||
lr_mult: 2
|
||||
decay_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 21
|
||||
pad: 0
|
||||
kernel_size: 1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "score_pool3c"
|
||||
type: "Crop"
|
||||
bottom: "score_pool3"
|
||||
bottom: "upscore_pool4"
|
||||
top: "score_pool3c"
|
||||
crop_param {
|
||||
axis: 2
|
||||
offset: 9
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "fuse_pool3"
|
||||
type: "Eltwise"
|
||||
bottom: "upscore_pool4"
|
||||
bottom: "score_pool3c"
|
||||
top: "fuse_pool3"
|
||||
eltwise_param {
|
||||
operation: SUM
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "upscore8"
|
||||
type: "Deconvolution"
|
||||
bottom: "fuse_pool3"
|
||||
top: "upscore8"
|
||||
param {
|
||||
lr_mult: 0
|
||||
}
|
||||
convolution_param {
|
||||
num_output: 21
|
||||
bias_term: false
|
||||
kernel_size: 16
|
||||
stride: 8
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "score"
|
||||
type: "Crop"
|
||||
bottom: "upscore8"
|
||||
bottom: "data"
|
||||
top: "score"
|
||||
crop_param {
|
||||
axis: 2
|
||||
offset: 31
|
||||
}
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
#include <opencv2/dnn.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
using namespace cv;
|
||||
using namespace cv::dnn;
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
using namespace std;
|
||||
|
||||
static const string fcnType = "fcn8s";
|
||||
|
||||
static vector<cv::Vec3b> readColors(const string &filename = "pascal-classes.txt")
|
||||
{
|
||||
vector<cv::Vec3b> colors;
|
||||
|
||||
ifstream fp(filename.c_str());
|
||||
if (!fp.is_open())
|
||||
{
|
||||
cerr << "File with colors not found: " << filename << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
string line;
|
||||
while (!fp.eof())
|
||||
{
|
||||
getline(fp, line);
|
||||
if (line.length())
|
||||
{
|
||||
stringstream ss(line);
|
||||
|
||||
string name; ss >> name;
|
||||
int temp;
|
||||
cv::Vec3b color;
|
||||
ss >> temp; color[0] = temp;
|
||||
ss >> temp; color[1] = temp;
|
||||
ss >> temp; color[2] = temp;
|
||||
colors.push_back(color);
|
||||
}
|
||||
}
|
||||
|
||||
fp.close();
|
||||
return colors;
|
||||
}
|
||||
|
||||
static void colorizeSegmentation(const Mat &score, const vector<cv::Vec3b> &colors, cv::Mat &segm)
|
||||
{
|
||||
const int rows = score.size[2];
|
||||
const int cols = score.size[3];
|
||||
const int chns = score.size[1];
|
||||
|
||||
cv::Mat maxCl(rows, cols, CV_8UC1);
|
||||
cv::Mat maxVal(rows, cols, CV_32FC1);
|
||||
for (int ch = 0; ch < chns; ch++)
|
||||
{
|
||||
for (int row = 0; row < rows; row++)
|
||||
{
|
||||
const float *ptrScore = score.ptr<float>(0, ch, row);
|
||||
uchar *ptrMaxCl = maxCl.ptr<uchar>(row);
|
||||
float *ptrMaxVal = maxVal.ptr<float>(row);
|
||||
for (int col = 0; col < cols; col++)
|
||||
{
|
||||
if (ptrScore[col] > ptrMaxVal[col])
|
||||
{
|
||||
ptrMaxVal[col] = ptrScore[col];
|
||||
ptrMaxCl[col] = ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
segm.create(rows, cols, CV_8UC3);
|
||||
for (int row = 0; row < rows; row++)
|
||||
{
|
||||
const uchar *ptrMaxCl = maxCl.ptr<uchar>(row);
|
||||
cv::Vec3b *ptrSegm = segm.ptr<cv::Vec3b>(row);
|
||||
for (int col = 0; col < cols; col++)
|
||||
{
|
||||
ptrSegm[col] = colors[ptrMaxCl[col]];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
cv::dnn::initModule(); //Required if OpenCV is built as static libs
|
||||
|
||||
String modelTxt = fcnType + "-heavy-pascal.prototxt";
|
||||
String modelBin = fcnType + "-heavy-pascal.caffemodel";
|
||||
String imageFile = (argc > 1) ? argv[1] : "rgb.jpg";
|
||||
|
||||
vector<cv::Vec3b> colors = readColors();
|
||||
|
||||
//! [Create the importer of Caffe model]
|
||||
Ptr<dnn::Importer> importer;
|
||||
try //Try to import Caffe GoogleNet model
|
||||
{
|
||||
importer = dnn::createCaffeImporter(modelTxt, modelBin);
|
||||
}
|
||||
catch (const cv::Exception &err) //Importer can throw errors, we will catch them
|
||||
{
|
||||
cerr << err.msg << endl;
|
||||
}
|
||||
//! [Create the importer of Caffe model]
|
||||
|
||||
if (!importer)
|
||||
{
|
||||
cerr << "Can't load network by using the following files: " << endl;
|
||||
cerr << "prototxt: " << modelTxt << endl;
|
||||
cerr << "caffemodel: " << modelBin << endl;
|
||||
cerr << fcnType << "-heavy-pascal.caffemodel can be downloaded here:" << endl;
|
||||
cerr << "http://dl.caffe.berkeleyvision.org/" << fcnType << "-heavy-pascal.caffemodel" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
//! [Initialize network]
|
||||
dnn::Net net;
|
||||
importer->populateNet(net);
|
||||
importer.release(); //We don't need importer anymore
|
||||
//! [Initialize network]
|
||||
|
||||
//! [Prepare blob]
|
||||
Mat img = imread(imageFile);
|
||||
if (img.empty())
|
||||
{
|
||||
cerr << "Can't read image from the file: " << imageFile << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
resize(img, img, Size(500, 500)); //FCN accepts 500x500 RGB-images
|
||||
Mat inputBlob = blobFromImage(img); //Convert Mat to batch of images
|
||||
//! [Prepare blob]
|
||||
|
||||
//! [Set input blob]
|
||||
net.setInput(inputBlob, "data"); //set the network input
|
||||
//! [Set input blob]
|
||||
|
||||
//! [Make forward pass]
|
||||
double t = (double)cv::getTickCount();
|
||||
Mat score = net.forward("score"); //compute output
|
||||
t = (double)cv::getTickCount() - t;
|
||||
printf("processing time: %.1fms\n", t*1000./getTickFrequency());
|
||||
//! [Make forward pass]
|
||||
|
||||
Mat colorize;
|
||||
colorizeSegmentation(score, colors, colorize);
|
||||
Mat show;
|
||||
addWeighted(img, 0.4, colorize, 0.6, 0.0, show);
|
||||
imshow("show", show);
|
||||
waitKey(0);
|
||||
return 0;
|
||||
} //main
|
||||
@@ -1,34 +0,0 @@
|
||||
from __future__ import print_function
|
||||
import numpy as np
|
||||
import cv2
|
||||
from cv2 import dnn
|
||||
import timeit
|
||||
|
||||
def prepare_image(img):
|
||||
img = cv2.resize(img, (224, 224))
|
||||
#convert interleaved image (RGBRGB) to planar(RRGGBB)
|
||||
blob = np.moveaxis(img, 2, 0)
|
||||
blob = np.reshape(blob.astype(np.float32), (-1, 3, 224, 224))
|
||||
return blob
|
||||
|
||||
def timeit_forward(net):
|
||||
print("OpenCL:", cv2.ocl.useOpenCL())
|
||||
print("Runtime:", timeit.timeit(lambda: net.forward(), number=10))
|
||||
|
||||
def get_class_list():
|
||||
with open('synset_words.txt', 'rt') as f:
|
||||
return [ x[x.find(" ") + 1 :] for x in f ]
|
||||
|
||||
blob = prepare_image(cv2.imread('space_shuttle.jpg'))
|
||||
print("Input:", blob.shape, blob.dtype)
|
||||
|
||||
cv2.ocl.setUseOpenCL(True) #Disable OCL if you want
|
||||
net = dnn.readNetFromCaffe('bvlc_googlenet.prototxt', 'bvlc_googlenet.caffemodel')
|
||||
net.setBlob(".data", blob)
|
||||
net.forward()
|
||||
#timeit_forward(net) #Uncomment to check performance
|
||||
|
||||
prob = net.getBlob("prob")
|
||||
print("Output:", prob.shape, prob.dtype)
|
||||
classes = get_class_list()
|
||||
print("Best match", classes[prob.argmax()])
|
||||
@@ -1,21 +0,0 @@
|
||||
background 0 0 0
|
||||
aeroplane 128 0 0
|
||||
bicycle 0 128 0
|
||||
bird 128 128 0
|
||||
boat 0 0 128
|
||||
bottle 128 0 128
|
||||
bus 0 128 128
|
||||
car 128 128 128
|
||||
cat 64 0 0
|
||||
chair 192 0 0
|
||||
cow 64 128 0
|
||||
diningtable 192 128 0
|
||||
dog 64 0 128
|
||||
horse 192 0 128
|
||||
motorbike 64 128 128
|
||||
person 192 128 128
|
||||
pottedplant 0 64 0
|
||||
sheep 128 64 0
|
||||
sofa 0 192 0
|
||||
train 128 192 0
|
||||
tvmonitor 0 64 128
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 46 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 27 KiB |
@@ -1,120 +0,0 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2017, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
// Sample of using Halide backend in OpenCV deep learning module.
|
||||
// Based on dnn/samples/caffe_googlenet.cpp.
|
||||
|
||||
#include <opencv2/dnn.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
using namespace cv;
|
||||
using namespace cv::dnn;
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
/* Find best class for the blob (i. e. class with maximal probability) */
|
||||
void getMaxClass(const Mat &probBlob, int *classId, double *classProb)
|
||||
{
|
||||
Mat probMat = probBlob.reshape(1, 1); //reshape the blob to 1x1000 matrix
|
||||
Point classNumber;
|
||||
|
||||
minMaxLoc(probMat, NULL, classProb, NULL, &classNumber);
|
||||
*classId = classNumber.x;
|
||||
}
|
||||
|
||||
std::vector<std::string> readClassNames(const char *filename = "synset_words.txt")
|
||||
{
|
||||
std::vector<std::string> classNames;
|
||||
|
||||
std::ifstream fp(filename);
|
||||
if (!fp.is_open())
|
||||
{
|
||||
std::cerr << "File with classes labels not found: " << filename << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
std::string name;
|
||||
while (!fp.eof())
|
||||
{
|
||||
std::getline(fp, name);
|
||||
if (name.length())
|
||||
classNames.push_back( name.substr(name.find(' ')+1) );
|
||||
}
|
||||
|
||||
fp.close();
|
||||
return classNames;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
initModule(); // Required if OpenCV is built as static libs.
|
||||
|
||||
std::string modelTxt = "train_val.prototxt";
|
||||
std::string modelBin = "squeezenet_v1.1.caffemodel";
|
||||
std::string imageFile = (argc > 1) ? argv[1] : "space_shuttle.jpg";
|
||||
|
||||
//! [Read and initialize network]
|
||||
Net net = dnn::readNetFromCaffe(modelTxt, modelBin);
|
||||
//! [Read and initialize network]
|
||||
|
||||
//! [Check that network was read successfully]
|
||||
if (net.empty())
|
||||
{
|
||||
std::cerr << "Can't load network by using the following files: " << std::endl;
|
||||
std::cerr << "prototxt: " << modelTxt << std::endl;
|
||||
std::cerr << "caffemodel: " << modelBin << std::endl;
|
||||
std::cerr << "SqueezeNet v1.1 can be downloaded from:" << std::endl;
|
||||
std::cerr << "https://github.com/DeepScale/SqueezeNet/tree/master/SqueezeNet_v1.1" << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
//! [Check that network was read successfully]
|
||||
|
||||
//! [Prepare blob]
|
||||
Mat img = imread(imageFile);
|
||||
if (img.empty())
|
||||
{
|
||||
std::cerr << "Can't read image from the file: " << imageFile << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
if (img.channels() != 3)
|
||||
{
|
||||
std::cerr << "Image " << imageFile << " isn't 3-channel" << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
resize(img, img, Size(227, 227)); // SqueezeNet v1.1 predict class by 3x227x227 input image.
|
||||
Mat inputBlob = blobFromImage(img, 1.0, Size(), Scalar(), false); // Convert Mat to 4-dimensional batch.
|
||||
//! [Prepare blob]
|
||||
|
||||
//! [Set input blob]
|
||||
net.setInput(inputBlob); // Set the network input.
|
||||
//! [Set input blob]
|
||||
|
||||
//! [Enable Halide backend]
|
||||
net.setPreferableBackend(DNN_BACKEND_HALIDE); // Tell engine to use Halide where it possible.
|
||||
//! [Enable Halide backend]
|
||||
|
||||
//! [Make forward pass]
|
||||
Mat prob = net.forward("prob"); // Compute output.
|
||||
//! [Make forward pass]
|
||||
|
||||
//! [Determine the best class]
|
||||
int classId;
|
||||
double classProb;
|
||||
getMaxClass(prob, &classId, &classProb); // Find the best class.
|
||||
//! [Determine the best class]
|
||||
|
||||
//! [Print results]
|
||||
std::vector<std::string> classNames = readClassNames();
|
||||
std::cout << "Best class: #" << classId << " '" << classNames.at(classId) << "'" << std::endl;
|
||||
std::cout << "Probability: " << classProb * 100 << "%" << std::endl;
|
||||
//! [Print results]
|
||||
|
||||
return 0;
|
||||
} //main
|
||||
@@ -1,154 +0,0 @@
|
||||
#include <opencv2/dnn.hpp>
|
||||
#include <opencv2/dnn/shape_utils.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
using namespace cv;
|
||||
using namespace cv::dnn;
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
using namespace std;
|
||||
|
||||
const size_t width = 300;
|
||||
const size_t height = 300;
|
||||
|
||||
Mat getMean(const size_t& imageHeight, const size_t& imageWidth)
|
||||
{
|
||||
Mat mean;
|
||||
|
||||
const int meanValues[3] = {104, 117, 123};
|
||||
vector<Mat> meanChannels;
|
||||
for(size_t i = 0; i < 3; i++)
|
||||
{
|
||||
Mat channel(imageHeight, imageWidth, CV_32F, Scalar(meanValues[i]));
|
||||
meanChannels.push_back(channel);
|
||||
}
|
||||
cv::merge(meanChannels, mean);
|
||||
return mean;
|
||||
}
|
||||
|
||||
Mat preprocess(const Mat& frame)
|
||||
{
|
||||
Mat preprocessed;
|
||||
frame.convertTo(preprocessed, CV_32F);
|
||||
resize(preprocessed, preprocessed, Size(width, height)); //SSD accepts 300x300 RGB-images
|
||||
|
||||
Mat mean = getMean(width, height);
|
||||
cv::subtract(preprocessed, mean, preprocessed);
|
||||
|
||||
return preprocessed;
|
||||
}
|
||||
|
||||
const char* about = "This sample uses Single-Shot Detector "
|
||||
"(https://arxiv.org/abs/1512.02325)"
|
||||
"to detect objects on image\n"; // TODO: link
|
||||
|
||||
const char* params
|
||||
= "{ help | false | print usage }"
|
||||
"{ proto | | model configuration }"
|
||||
"{ model | | model weights }"
|
||||
"{ image | | image for detection }"
|
||||
"{ min_confidence | 0.5 | min confidence }";
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
cv::CommandLineParser parser(argc, argv, params);
|
||||
|
||||
if (parser.get<bool>("help"))
|
||||
{
|
||||
std::cout << about << std::endl;
|
||||
parser.printMessage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
cv::dnn::initModule(); //Required if OpenCV is built as static libs
|
||||
|
||||
String modelConfiguration = parser.get<string>("proto");
|
||||
String modelBinary = parser.get<string>("model");
|
||||
|
||||
//! [Create the importer of Caffe model]
|
||||
Ptr<dnn::Importer> importer;
|
||||
|
||||
// Import Caffe SSD model
|
||||
try
|
||||
{
|
||||
importer = dnn::createCaffeImporter(modelConfiguration, modelBinary);
|
||||
}
|
||||
catch (const cv::Exception &err) //Importer can throw errors, we will catch them
|
||||
{
|
||||
cerr << err.msg << endl;
|
||||
}
|
||||
//! [Create the importer of Caffe model]
|
||||
|
||||
if (!importer)
|
||||
{
|
||||
cerr << "Can't load network by using the following files: " << endl;
|
||||
cerr << "prototxt: " << modelConfiguration << endl;
|
||||
cerr << "caffemodel: " << modelBinary << endl;
|
||||
cerr << "Models can be downloaded here:" << endl;
|
||||
cerr << "https://github.com/weiliu89/caffe/tree/ssd#models" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
//! [Initialize network]
|
||||
dnn::Net net;
|
||||
importer->populateNet(net);
|
||||
importer.release(); //We don't need importer anymore
|
||||
//! [Initialize network]
|
||||
|
||||
cv::Mat frame = cv::imread(parser.get<string>("image"), -1);
|
||||
|
||||
if (frame.channels() == 4)
|
||||
cvtColor(frame, frame, COLOR_BGRA2BGR);
|
||||
//! [Prepare blob]
|
||||
Mat preprocessedFrame = preprocess(frame);
|
||||
|
||||
Mat inputBlob = blobFromImage(preprocessedFrame); //Convert Mat to batch of images
|
||||
//! [Prepare blob]
|
||||
|
||||
//! [Set input blob]
|
||||
net.setInput(inputBlob, "data"); //set the network input
|
||||
//! [Set input blob]
|
||||
|
||||
//! [Make forward pass]
|
||||
Mat detection = net.forward("detection_out"); //compute output
|
||||
//! [Make forward pass]
|
||||
|
||||
Mat detectionMat(detection.size[2], detection.size[3], CV_32F, detection.ptr<float>());
|
||||
|
||||
float confidenceThreshold = parser.get<float>("min_confidence");
|
||||
for(int i = 0; i < detectionMat.rows; i++)
|
||||
{
|
||||
float confidence = detectionMat.at<float>(i, 2);
|
||||
|
||||
if(confidence > confidenceThreshold)
|
||||
{
|
||||
size_t objectClass = detectionMat.at<float>(i, 1);
|
||||
|
||||
float xLeftBottom = detectionMat.at<float>(i, 3) * frame.cols;
|
||||
float yLeftBottom = detectionMat.at<float>(i, 4) * frame.rows;
|
||||
float xRightTop = detectionMat.at<float>(i, 5) * frame.cols;
|
||||
float yRightTop = detectionMat.at<float>(i, 6) * frame.rows;
|
||||
|
||||
std::cout << "Class: " << objectClass << std::endl;
|
||||
std::cout << "Confidence: " << confidence << std::endl;
|
||||
|
||||
std::cout << " " << xLeftBottom
|
||||
<< " " << yLeftBottom
|
||||
<< " " << xRightTop
|
||||
<< " " << yRightTop << std::endl;
|
||||
|
||||
Rect object(xLeftBottom, yLeftBottom,
|
||||
xRightTop - xLeftBottom,
|
||||
yRightTop - yLeftBottom);
|
||||
|
||||
rectangle(frame, object, Scalar(0, 255, 0));
|
||||
}
|
||||
}
|
||||
|
||||
imshow("detections", frame);
|
||||
waitKey();
|
||||
|
||||
return 0;
|
||||
} // main
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,173 +0,0 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
// Copyright (C) 2016, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
/*
|
||||
Sample of using OpenCV dnn module with Tensorflow Inception model.
|
||||
*/
|
||||
|
||||
#include <opencv2/dnn.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
using namespace cv;
|
||||
using namespace cv::dnn;
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
using namespace std;
|
||||
|
||||
const String keys =
|
||||
"{help h || Sample app for loading Inception TensorFlow model. "
|
||||
"The model and class names list can be downloaded here: "
|
||||
"https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip }"
|
||||
"{model m |tensorflow_inception_graph.pb| path to TensorFlow .pb model file }"
|
||||
"{image i || path to image file }"
|
||||
"{i_blob | input | input blob name) }"
|
||||
"{o_blob | softmax2 | output blob name) }"
|
||||
"{c_names c | imagenet_comp_graph_label_strings.txt | path to file with classnames for class id }"
|
||||
"{result r || path to save output blob (optional, binary format, NCHW order) }"
|
||||
;
|
||||
|
||||
void getMaxClass(const Mat &probBlob, int *classId, double *classProb);
|
||||
std::vector<String> readClassNames(const char *filename);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
cv::CommandLineParser parser(argc, argv, keys);
|
||||
|
||||
if (parser.has("help"))
|
||||
{
|
||||
parser.printMessage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
String modelFile = parser.get<String>("model");
|
||||
String imageFile = parser.get<String>("image");
|
||||
String inBlobName = parser.get<String>("i_blob");
|
||||
String outBlobName = parser.get<String>("o_blob");
|
||||
|
||||
if (!parser.check())
|
||||
{
|
||||
parser.printErrors();
|
||||
return 0;
|
||||
}
|
||||
|
||||
String classNamesFile = parser.get<String>("c_names");
|
||||
String resultFile = parser.get<String>("result");
|
||||
|
||||
//! [Create the importer of TensorFlow model]
|
||||
Ptr<dnn::Importer> importer;
|
||||
try //Try to import TensorFlow AlexNet model
|
||||
{
|
||||
importer = dnn::createTensorflowImporter(modelFile);
|
||||
}
|
||||
catch (const cv::Exception &err) //Importer can throw errors, we will catch them
|
||||
{
|
||||
std::cerr << err.msg << std::endl;
|
||||
}
|
||||
//! [Create the importer of Caffe model]
|
||||
|
||||
if (!importer)
|
||||
{
|
||||
std::cerr << "Can't load network by using the mode file: " << std::endl;
|
||||
std::cerr << modelFile << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
//! [Initialize network]
|
||||
dnn::Net net;
|
||||
importer->populateNet(net);
|
||||
importer.release(); //We don't need importer anymore
|
||||
//! [Initialize network]
|
||||
|
||||
//! [Prepare blob]
|
||||
Mat img = imread(imageFile);
|
||||
if (img.empty())
|
||||
{
|
||||
std::cerr << "Can't read image from the file: " << imageFile << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
cv::Size inputImgSize = cv::Size(224, 224);
|
||||
|
||||
if (inputImgSize != img.size())
|
||||
resize(img, img, inputImgSize); //Resize image to input size
|
||||
|
||||
Mat inputBlob = blobFromImage(img); //Convert Mat to image batch
|
||||
//! [Prepare blob]
|
||||
inputBlob -= 117.0;
|
||||
//! [Set input blob]
|
||||
net.setInput(inputBlob, inBlobName); //set the network input
|
||||
//! [Set input blob]
|
||||
|
||||
cv::TickMeter tm;
|
||||
tm.start();
|
||||
|
||||
//! [Make forward pass]
|
||||
Mat result = net.forward(outBlobName); //compute output
|
||||
//! [Make forward pass]
|
||||
|
||||
tm.stop();
|
||||
|
||||
if (!resultFile.empty()) {
|
||||
CV_Assert(result.isContinuous());
|
||||
|
||||
ofstream fout(resultFile.c_str(), ios::out | ios::binary);
|
||||
fout.write((char*)result.data, result.total() * sizeof(float));
|
||||
fout.close();
|
||||
}
|
||||
|
||||
std::cout << "Output blob shape " << result.size[0] << " x " << result.size[1] << " x " << result.size[2] << " x " << result.size[3] << std::endl;
|
||||
std::cout << "Inference time, ms: " << tm.getTimeMilli() << std::endl;
|
||||
|
||||
if (!classNamesFile.empty()) {
|
||||
std::vector<String> classNames = readClassNames(classNamesFile.c_str());
|
||||
|
||||
int classId;
|
||||
double classProb;
|
||||
getMaxClass(result, &classId, &classProb);//find the best class
|
||||
|
||||
//! [Print results]
|
||||
std::cout << "Best class: #" << classId << " '" << classNames.at(classId) << "'" << std::endl;
|
||||
std::cout << "Probability: " << classProb * 100 << "%" << std::endl;
|
||||
}
|
||||
return 0;
|
||||
} //main
|
||||
|
||||
|
||||
/* Find best class for the blob (i. e. class with maximal probability) */
|
||||
void getMaxClass(const Mat &probBlob, int *classId, double *classProb)
|
||||
{
|
||||
Mat probMat = probBlob.reshape(1, 1); //reshape the blob to 1x1000 matrix
|
||||
Point classNumber;
|
||||
|
||||
minMaxLoc(probMat, NULL, classProb, NULL, &classNumber);
|
||||
*classId = classNumber.x;
|
||||
}
|
||||
|
||||
std::vector<String> readClassNames(const char *filename)
|
||||
{
|
||||
std::vector<String> classNames;
|
||||
|
||||
std::ifstream fp(filename);
|
||||
if (!fp.is_open())
|
||||
{
|
||||
std::cerr << "File with classes labels not found: " << filename << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
std::string name;
|
||||
while (!fp.eof())
|
||||
{
|
||||
std::getline(fp, name);
|
||||
if (name.length())
|
||||
classNames.push_back( name );
|
||||
}
|
||||
|
||||
fp.close();
|
||||
return classNames;
|
||||
}
|
||||
@@ -1,207 +0,0 @@
|
||||
/*
|
||||
Sample of using OpenCV dnn module with Torch ENet model.
|
||||
*/
|
||||
|
||||
#include <opencv2/dnn.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
using namespace cv;
|
||||
using namespace cv::dnn;
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
using namespace std;
|
||||
|
||||
const String keys =
|
||||
"{help h || Sample app for loading ENet Torch model. "
|
||||
"The model and class names list can be downloaded here: "
|
||||
"https://www.dropbox.com/sh/dywzk3gyb12hpe5/AAD5YkUa8XgMpHs2gCRgmCVCa }"
|
||||
"{model m || path to Torch .net model file (model_best.net) }"
|
||||
"{image i || path to image file }"
|
||||
"{c_names c || path to file with classnames for channels (optional, categories.txt) }"
|
||||
"{result r || path to save output blob (optional, binary format, NCHW order) }"
|
||||
"{show s || whether to show all output channels or not}"
|
||||
"{o_blob || output blob's name. If empty, last blob's name in net is used}"
|
||||
;
|
||||
|
||||
static void colorizeSegmentation(const Mat &score, Mat &segm,
|
||||
Mat &legend, vector<String> &classNames, vector<Vec3b> &colors);
|
||||
static vector<Vec3b> readColors(const String &filename, vector<String>& classNames);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CommandLineParser parser(argc, argv, keys);
|
||||
|
||||
if (parser.has("help"))
|
||||
{
|
||||
parser.printMessage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
String modelFile = parser.get<String>("model");
|
||||
String imageFile = parser.get<String>("image");
|
||||
|
||||
if (!parser.check())
|
||||
{
|
||||
parser.printErrors();
|
||||
return 0;
|
||||
}
|
||||
|
||||
String classNamesFile = parser.get<String>("c_names");
|
||||
String resultFile = parser.get<String>("result");
|
||||
|
||||
//! [Read model and initialize network]
|
||||
dnn::Net net = dnn::readNetFromTorch(modelFile);
|
||||
|
||||
//! [Prepare blob]
|
||||
Mat img = imread(imageFile), input;
|
||||
if (img.empty())
|
||||
{
|
||||
std::cerr << "Can't read image from the file: " << imageFile << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
Size origSize = img.size();
|
||||
Size inputImgSize = cv::Size(1024, 512);
|
||||
|
||||
if (inputImgSize != origSize)
|
||||
resize(img, img, inputImgSize); //Resize image to input size
|
||||
|
||||
Mat inputBlob = blobFromImage(img, 1./255); //Convert Mat to image batch
|
||||
//! [Prepare blob]
|
||||
|
||||
//! [Set input blob]
|
||||
net.setInput(inputBlob, ""); //set the network input
|
||||
//! [Set input blob]
|
||||
|
||||
TickMeter tm;
|
||||
|
||||
String oBlob = net.getLayerNames().back();
|
||||
if (!parser.get<String>("o_blob").empty())
|
||||
{
|
||||
oBlob = parser.get<String>("o_blob");
|
||||
}
|
||||
|
||||
//! [Make forward pass]
|
||||
Mat result = net.forward(oBlob);
|
||||
|
||||
if (!resultFile.empty()) {
|
||||
CV_Assert(result.isContinuous());
|
||||
|
||||
ofstream fout(resultFile.c_str(), ios::out | ios::binary);
|
||||
fout.write((char*)result.data, result.total() * sizeof(float));
|
||||
fout.close();
|
||||
}
|
||||
|
||||
std::cout << "Output blob: " << result.size[0] << " x " << result.size[1] << " x " << result.size[2] << " x " << result.size[3] << "\n";
|
||||
std::cout << "Inference time, ms: " << tm.getTimeMilli() << std::endl;
|
||||
|
||||
if (parser.has("show"))
|
||||
{
|
||||
std::vector<String> classNames;
|
||||
vector<cv::Vec3b> colors;
|
||||
if(!classNamesFile.empty()) {
|
||||
colors = readColors(classNamesFile, classNames);
|
||||
}
|
||||
Mat segm, legend;
|
||||
colorizeSegmentation(result, segm, legend, classNames, colors);
|
||||
|
||||
Mat show;
|
||||
addWeighted(img, 0.1, segm, 0.9, 0.0, show);
|
||||
|
||||
cv::resize(show, show, origSize, 0, 0, cv::INTER_NEAREST);
|
||||
imshow("Result", show);
|
||||
if(classNames.size())
|
||||
imshow("Legend", legend);
|
||||
waitKey();
|
||||
}
|
||||
|
||||
return 0;
|
||||
} //main
|
||||
|
||||
static void colorizeSegmentation(const Mat &score, Mat &segm, Mat &legend, vector<String> &classNames, vector<Vec3b> &colors)
|
||||
{
|
||||
const int rows = score.size[2];
|
||||
const int cols = score.size[3];
|
||||
const int chns = score.size[1];
|
||||
|
||||
cv::Mat maxCl(rows, cols, CV_8UC1);
|
||||
cv::Mat maxVal(rows, cols, CV_32FC1);
|
||||
for (int ch = 0; ch < chns; ch++)
|
||||
{
|
||||
for (int row = 0; row < rows; row++)
|
||||
{
|
||||
const float *ptrScore = score.ptr<float>(0, ch, row);
|
||||
uchar *ptrMaxCl = maxCl.ptr<uchar>(row);
|
||||
float *ptrMaxVal = maxVal.ptr<float>(row);
|
||||
for (int col = 0; col < cols; col++)
|
||||
{
|
||||
if (ptrScore[col] > ptrMaxVal[col])
|
||||
{
|
||||
ptrMaxVal[col] = ptrScore[col];
|
||||
ptrMaxCl[col] = ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
segm.create(rows, cols, CV_8UC3);
|
||||
for (int row = 0; row < rows; row++)
|
||||
{
|
||||
const uchar *ptrMaxCl = maxCl.ptr<uchar>(row);
|
||||
cv::Vec3b *ptrSegm = segm.ptr<cv::Vec3b>(row);
|
||||
for (int col = 0; col < cols; col++)
|
||||
{
|
||||
ptrSegm[col] = colors[ptrMaxCl[col]];
|
||||
}
|
||||
}
|
||||
|
||||
if (classNames.size() == colors.size())
|
||||
{
|
||||
int blockHeight = 30;
|
||||
legend.create(blockHeight*classNames.size(), 200, CV_8UC3);
|
||||
for(int i = 0; i < classNames.size(); i++)
|
||||
{
|
||||
cv::Mat block = legend.rowRange(i*blockHeight, (i+1)*blockHeight);
|
||||
block = colors[i];
|
||||
putText(block, classNames[i], Point(0, blockHeight/2), FONT_HERSHEY_SIMPLEX, 0.5, Scalar());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static vector<Vec3b> readColors(const String &filename, vector<String>& classNames)
|
||||
{
|
||||
vector<cv::Vec3b> colors;
|
||||
classNames.clear();
|
||||
|
||||
ifstream fp(filename.c_str());
|
||||
if (!fp.is_open())
|
||||
{
|
||||
cerr << "File with colors not found: " << filename << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
string line;
|
||||
while (!fp.eof())
|
||||
{
|
||||
getline(fp, line);
|
||||
if (line.length())
|
||||
{
|
||||
stringstream ss(line);
|
||||
|
||||
string name; ss >> name;
|
||||
int temp;
|
||||
cv::Vec3b color;
|
||||
ss >> temp; color[0] = temp;
|
||||
ss >> temp; color[1] = temp;
|
||||
ss >> temp; color[2] = temp;
|
||||
classNames.push_back(name);
|
||||
colors.push_back(color);
|
||||
}
|
||||
}
|
||||
|
||||
fp.close();
|
||||
return colors;
|
||||
}
|
||||
Reference in New Issue
Block a user