《caffe学习之路》第五章:Ubuntu16.04 caffe ssd 在QT环境上编译运行ssd_detect.cpp

2023-10-29

大多深度学习框架主要支持python,而caffe提供c++接口,这也是我选择caffe框架的原因。

前一章说到examples/ssd目录下的ssd_detect.cpp文件是weiliu等大神给我们提供的,算是一个c++实现demo,这一章主要分析ssd_detect.cpp代码,以及在qt上进行编译调试。

1、Qt环境搭建

(1)ubuntu安装QT

一条命令暴力安装:

sudo apt-get install cmake qt5-default qtcreator

(2)新建一个c++工程

 在.pro文件进行编译配置:

TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt

SOURCES += main.cpp

#system
INCLUDEPATH += /usr/local/lib \
               /usr/lib/x86_64-linux-gnu
LIBS += -L/usr/local/lib

#opencv
INCLUDEPATH += /usr/include \
               /usr/include/opencv \
               /usr/include/opencv2/
LIBS += -L /usr/lib/libopencv_*.so
#LIBS += -L /usr/lib -lopencv_core -lopencv_imgcodecs -lopencv_highgui

#caffe
INCLUDEPATH += /home/bjw/caffe/include \
               /home/bjw/caffe/build/src \
LIBS += -L/home/bjw/caffe/build/lib/lib_*.so
LIBS += -L/home/bjw/caffe/build/lib -lcaffe

#cuda cudnn
INCLUDEPATH += /usr/local/cuda/include
LIBS += -L/usr/local/cuda/lib64
LIBS += -lcudart -lcublas -lcurand

#caffe addition
LIBS += -lglog -lgflags -lprotobuf -lboost_system -lboost_thread -llmdb -lleveldb -lstdc++ -lcblas -latlas -lcudnn

《注意》:需要根据自己的路径进行调整。

2、编译运行ssd_detect.cpp

把官方给的ssd_detect.cpp粘贴复制到自己的工程就可以了,下面是我根据官方给的代码进行了微调,可以测试image,video和摄像头。

// This is a demo code for using a SSD model to do detection.
// The code is modified from examples/cpp_classification/classification.cpp.
// Usage:
//    ssd_detect [FLAGS] model_file weights_file list_file
//
// where model_file is the .prototxt file defining the network architecture, and
// weights_file is the .caffemodel file containing the network parameters, and
// list_file contains a list of image files with the format as follows:
//    folder/img1.JPEG
//    folder/img2.JPEG
// list_file can also contain a list of video files with the format as follows:
//    folder/video1.mp4
//    folder/video2.mp4
//
#define USE_OPENCV
#include <caffe/caffe.hpp>
#ifdef USE_OPENCV
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#endif  // USE_OPENCV
#include <algorithm>
#include <iomanip>
#include <iosfwd>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#ifdef USE_OPENCV

using namespace caffe;  // NOLINT(build/namespaces)
using namespace cv;
using namespace std;

class Detector {
public:
    Detector(const string& model_file,
             const string& weights_file,
             const string& mean_file,
             const string& mean_value);

    std::vector<vector<float> > Detect(const cv::Mat& img);

private:
    void SetMean(const string& mean_file, const string& mean_value);

    void WrapInputLayer(std::vector<cv::Mat>* input_channels);

    void Preprocess(const cv::Mat& img,
                    std::vector<cv::Mat>* input_channels);

private:
    boost::shared_ptr<Net<float> > net_;
    cv::Size input_geometry_;
    int num_channels_;
    cv::Mat mean_;
};

Detector::Detector(const string& model_file,
                   const string& weights_file,
                   const string& mean_file,
                   const string& mean_value) {
#ifdef CPU_ONLY
    Caffe::set_mode(Caffe::CPU);
#else
    Caffe::set_mode(Caffe::GPU);
#endif

    /* Load the network. */
    net_.reset(new Net<float>(model_file, TEST));
    net_->CopyTrainedLayersFrom(weights_file);

    CHECK_EQ(net_->num_inputs(), 1) << "Network should have exactly one input.";
    CHECK_EQ(net_->num_outputs(), 1) << "Network should have exactly one output.";

    Blob<float>* input_layer = net_->input_blobs()[0];
    num_channels_ = input_layer->channels();
    CHECK(num_channels_ == 3 || num_channels_ == 1)
            << "Input layer should have 1 or 3 channels.";
    input_geometry_ = cv::Size(input_layer->width(), input_layer->height());

    /* Load the binaryproto mean file. */
    SetMean(mean_file, mean_value);
}

std::vector<vector<float> > Detector::Detect(const cv::Mat& img) {
    Blob<float>* input_layer = net_->input_blobs()[0];
    input_layer->Reshape(1, num_channels_,
                         input_geometry_.height, input_geometry_.width);
    /* Forward dimension change to all layers. */
    net_->Reshape();

    std::vector<cv::Mat> input_channels;
    WrapInputLayer(&input_channels);

    Preprocess(img, &input_channels);

    net_->Forward();

    /* Copy the output layer to a std::vector */
    Blob<float>* result_blob = net_->output_blobs()[0];
    const float* result = result_blob->cpu_data();
    const int num_det = result_blob->height();
    vector<vector<float> > detections;
    for (int k = 0; k < num_det; ++k) {
        if (result[0] == -1) {
            // Skip invalid detection.
            result += 7;
            continue;
        }
        vector<float> detection(result, result + 7);
        detections.push_back(detection);
        result += 7;
    }
    return detections;
}

/* Load the mean file in binaryproto format. */
void Detector::SetMean(const string& mean_file, const string& mean_value) {
    cv::Scalar channel_mean;
    if (!mean_file.empty()) {
        CHECK(mean_value.empty()) <<
                                     "Cannot specify mean_file and mean_value at the same time";
        BlobProto blob_proto;
        ReadProtoFromBinaryFileOrDie(mean_file.c_str(), &blob_proto);

        /* Convert from BlobProto to Blob<float> */
        Blob<float> mean_blob;
        mean_blob.FromProto(blob_proto);
        CHECK_EQ(mean_blob.channels(), num_channels_)
                << "Number of channels of mean file doesn't match input layer.";

        /* The format of the mean file is planar 32-bit float BGR or grayscale. */
        std::vector<cv::Mat> channels;
        float* data = mean_blob.mutable_cpu_data();
        for (int i = 0; i < num_channels_; ++i) {
            /* Extract an individual channel. */
            cv::Mat channel(mean_blob.height(), mean_blob.width(), CV_32FC1, data);
            channels.push_back(channel);
            data += mean_blob.height() * mean_blob.width();
        }

        /* Merge the separate channels into a single image. */
        cv::Mat mean;
        cv::merge(channels, mean);

        /* Compute the global mean pixel value and create a mean image
     * filled with this value. */
        channel_mean = cv::mean(mean);
        mean_ = cv::Mat(input_geometry_, mean.type(), channel_mean);
    }
    if (!mean_value.empty()) {
        CHECK(mean_file.empty()) <<
                                    "Cannot specify mean_file and mean_value at the same time";
        stringstream ss(mean_value);
        vector<float> values;
        string item;
        while (getline(ss, item, ',')) {
            float value = std::atof(item.c_str());
            values.push_back(value);
        }
        CHECK(values.size() == 1 || values.size() == num_channels_) <<
                                                                       "Specify either 1 mean_value or as many as channels: " << num_channels_;

        std::vector<cv::Mat> channels;
        for (int i = 0; i < num_channels_; ++i) {
            /* Extract an individual channel. */
            cv::Mat channel(input_geometry_.height, input_geometry_.width, CV_32FC1,
                            cv::Scalar(values[i]));
            channels.push_back(channel);
        }
        cv::merge(channels, mean_);
    }
}

/* Wrap the input layer of the network in separate cv::Mat objects
 * (one per channel). This way we save one memcpy operation and we
 * don't need to rely on cudaMemcpy2D. The last preprocessing
 * operation will write the separate channels directly to the input
 * layer. */
void Detector::WrapInputLayer(std::vector<cv::Mat>* input_channels) {
    Blob<float>* input_layer = net_->input_blobs()[0];

    int width = input_layer->width();
    int height = input_layer->height();
    float* input_data = input_layer->mutable_cpu_data();
    for (int i = 0; i < input_layer->channels(); ++i) {
        cv::Mat channel(height, width, CV_32FC1, input_data);
        input_channels->push_back(channel);
        input_data += width * height;
    }
}

void Detector::Preprocess(const cv::Mat& img,
                          std::vector<cv::Mat>* input_channels) {
    /* Convert the input image to the input image format of the network. */
    cv::Mat sample;
    if (img.channels() == 3 && num_channels_ == 1)
        cv::cvtColor(img, sample, cv::COLOR_BGR2GRAY);
    else if (img.channels() == 4 && num_channels_ == 1)
        cv::cvtColor(img, sample, cv::COLOR_BGRA2GRAY);
    else if (img.channels() == 4 && num_channels_ == 3)
        cv::cvtColor(img, sample, cv::COLOR_BGRA2BGR);
    else if (img.channels() == 1 && num_channels_ == 3)
        cv::cvtColor(img, sample, cv::COLOR_GRAY2BGR);
    else
        sample = img;

    cv::Mat sample_resized;
    if (sample.size() != input_geometry_)
        cv::resize(sample, sample_resized, input_geometry_);
    else
        sample_resized = sample;

    cv::Mat sample_float;
    if (num_channels_ == 3)
        sample_resized.convertTo(sample_float, CV_32FC3);
    else
        sample_resized.convertTo(sample_float, CV_32FC1);

    cv::Mat sample_normalized;
    cv::subtract(sample_float, mean_, sample_normalized);

    /* This operation will write the separate BGR planes directly to the
   * input layer of the network because it is wrapped by the cv::Mat
   * objects in input_channels. */
    cv::split(sample_normalized, *input_channels);

    CHECK(reinterpret_cast<float*>(input_channels->at(0).data)
          == net_->input_blobs()[0]->cpu_data())
            << "Input channels are not wrapping the input layer of the network.";
}

DEFINE_string(mean_file, "",
              "The mean file used to subtract from the input image.");
DEFINE_string(mean_value, "104,117,123",
              "If specified, can be one value or can be same as image channels"
              " - would subtract from the corresponding channel). Separated by ','."
              "Either mean_file or mean_value should be provided, not both.");
DEFINE_string(file_type, "image",
              "The file type in the list_file. Currently support image and video.");
DEFINE_string(out_file, "/home/bjw/caffe/output.txt",
              "If provided, store the detection results in the out_file.");
DEFINE_double(confidence_threshold, 0.3,
              "Only store detections with score higher than the threshold.");

vector<string> labels = {"background",
                         "aeroplane", "bicycle","bird", "boat", "bottle",
                         "bus", "car", "cat","chair","cow",
                         "diningtable","dog","horse","motorbike","person",
                         "pottedplant","sheep","sofa","train","tvmonitor"};

int main(int argc, char** argv) {

    const string& model_file = "/home/bjw/caffe/models/VGGNet/VOC0712/SSD_300x300/deploy.prototxt";
    const string& weights_file = "/home/bjw/caffe/models/VGGNet/VOC0712/SSD_300x300/VGG_VOC0712_SSD_300x300_iter_120000.caffemodel";
    const string& mean_file = FLAGS_mean_file;
    const string& mean_value = FLAGS_mean_value;
    const string& file_type = FLAGS_file_type;
    const string& out_file = FLAGS_out_file;
    const float confidence_threshold = FLAGS_confidence_threshold;

    // Initialize the network.
    Detector detector(model_file, weights_file, mean_file, mean_value);

    // Set the output mode.
    std::streambuf* buf = std::cout.rdbuf();
    std::ofstream outfile;
    if (!out_file.empty()) {
        outfile.open(out_file.c_str());
        if (outfile.good()) {
            buf = outfile.rdbuf();
        }
    }
    std::ostream out(buf);

    // Process image one by one.
    std::ifstream infile("/home/bjw/caffe/examples/images/list.txt");
    std::string file;

    while (infile >> file)
    {
        if (file_type == "image")
        {
            cv::Mat img = cv::imread(file, -1);
            CHECK(!img.empty()) << "Unable to decode image " << file;
            std::vector<vector<float> > detections = detector.Detect(img);

            /* Print the detection results. */
            for (int i = 0; i < detections.size(); ++i) {
                const vector<float>& d = detections[i];
                // Detection format: [image_id, label, score, xmin, ymin, xmax, ymax].
                CHECK_EQ(d.size(), 7);
                const float score = d[2];
                if (score >= confidence_threshold) {
                    //save to file
                    out << file << " ";
                    out << static_cast<int>(d[1]) << " ";
                    out << score << " ";
                    out << static_cast<int>(d[3] * img.cols) << " ";
                    out << static_cast<int>(d[4] * img.rows) << " ";
                    out << static_cast<int>(d[5] * img.cols) << " ";
                    out << static_cast<int>(d[6] * img.rows) << std::endl;
                    //plot
                    int x = static_cast<int>(d[3] * img.cols);
                    int y = static_cast<int>(d[4] * img.rows);
                    int width = static_cast<int>(d[5] * img.cols) - x;
                    int height = static_cast<int>(d[6] * img.rows) - y;
                    Rect rect(max(x,0), max(y,0), width, height);
                    rectangle(img, rect, Scalar(0,255,0));
                    string sco = to_string(score).substr(0, 5);
                    putText(img, labels[static_cast<int>(d[1])] + ":" + sco, Point(max(x, 0), max(y + height / 2, 0)),
                       FONT_HERSHEY_SIMPLEX, 1, Scalar(0,255,0));
                }
            }
            imshow("image_show",img);
            //按任意键切换图片
            waitKey(0);
        } else if (file_type == "video") {

            cv::VideoCapture cap(file);
            if (!cap.isOpened()) {
                LOG(FATAL) << "Failed to open video: " << file;
            }
            cv::Mat img;
            int frame_count = 0;
            while (true) {
                bool success = cap.read(img);
                if (!success) {
                    LOG(INFO) << "Process " << frame_count << " frames from " << file;
                    break;
                }
                CHECK(!img.empty()) << "Error when read frame";
                std::vector<vector<float> > detections = detector.Detect(img);

                /* Print the detection results. */
                for (int i = 0; i < detections.size(); ++i) {
                    const vector<float>& d = detections[i];
                    // Detection format: [image_id, label, score, xmin, ymin, xmax, ymax].
                    CHECK_EQ(d.size(), 7);
                    const float score = d[2];
                    if (score >= confidence_threshold) {
                        //save to file
                        out << file << "_";
                        out << std::setfill('0') << std::setw(6) << frame_count << " ";
                        out << static_cast<int>(d[1]) << " ";
                        out << score << " ";
                        out << static_cast<int>(d[3] * img.cols) << " ";
                        out << static_cast<int>(d[4] * img.rows) << " ";
                        out << static_cast<int>(d[5] * img.cols) << " ";
                        out << static_cast<int>(d[6] * img.rows) << std::endl;
                        //plot
                        int x = static_cast<int>(d[3] * img.cols);
                        int y = static_cast<int>(d[4] * img.rows);
                        int width = static_cast<int>(d[5] * img.cols) - x;
                        int height = static_cast<int>(d[6] * img.rows) - y;
                        Rect rect(max(x,0), max(y,0), width, height);
                        rectangle(img, rect, Scalar(0,255,0));
                        //string sco = to_string(score).substr(0, 5);
                        //putText(img, labels[static_cast<int>(d[1])] + ":" + sco, Point(max(x, 0), max(y + height / 2, 0)),
                        //   FONT_HERSHEY_SIMPLEX, 1, Scalar(0,255,0));
                    }
                }
                imshow("video_show",img);
                waitKey(30);
                ++frame_count;
            }
            if (cap.isOpened()) {
                cap.release();
            }
        }else if (file_type == "camera"){
            cv::VideoCapture capture;
            capture.open(0);
            while(capture.isOpened()){
                //frame存储每一帧图像
                Mat img;
                //读取当前帧
                capture >> img;
                std::vector<vector<float> > detections = detector.Detect(img);
                for (int i = 0; i < detections.size(); ++i) {
                    const vector<float>& d = detections[i];
                    // Detection format: [image_id, label, score, xmin, ymin, xmax, ymax].
                    CHECK_EQ(d.size(), 7);
                    const float score = d[2];
                    if (score >= confidence_threshold) {
                        //plot
                        int x = static_cast<int>(d[3] * img.cols);
                        int y = static_cast<int>(d[4] * img.rows);
                        int width = static_cast<int>(d[5] * img.cols) - x;
                        int height = static_cast<int>(d[6] * img.rows) - y;
                        Rect rect(max(x,0), max(y,0), width, height);
                        rectangle(img, rect, Scalar(0,255,0));
                        //string sco = to_string(score).substr(0, 5);
                        //putText(img, labels[static_cast<int>(d[1])] + ":" + sco, Point(max(x, 0), max(y + height / 2, 0)),
                        //   FONT_HERSHEY_SIMPLEX, 1, Scalar(0,255,0));
                    }
                }
                //显示当前视频
                imshow("camera", img);
                //延时30ms,按下任何键退出
                if (waitKey(30) >= 0)
                    break;
            }
        }else {
            LOG(FATAL) << "Unknown file_type: " << file_type;
        }
    }
    return 0;
}
#else
int main(int argc, char** argv) {
    LOG(FATAL) << "This example requires OpenCV; compile with USE_OPENCV.";
}
#endif  // USE_OPENCV

注意需要修改的几个点:

(1)模型描述文件和caffemodel文件

源代码是通过传参的方式,我把它写死了,如图:

(2)mean_file、mean_value默认,file_type(检测类型)、out_file(输出路径)和confidence_threshold(阈值)需要修改

《注》 本代码file_type可选image、video和camera

(3) 测试图片或者video的路径

同样,源代码是通过传参的方式,我把它写死了,如图:

 《注》:list.txt里面是图片或者video的绝对路径,camera测试不需要。

3、运行测试

(1)图片测试

在代码中,file_type选择image。测试图片路径:CAFFE_ROOT/examples/images/list.txt

list.txt内容:

CAFFE_ROOT/examples/images/cat.jpg
CAFFE_ROOT/examples/images/fish-bike.jpg

 按任意键,切换检测图片: 

(2)video测试

在代码中,file_type选择video。测试图片路径:CAFFE_ROOT/examples/videos/list.txt

list.txt内容:

CAFFE_ROOT/examples/videos/ILSVRC2015_train_00755001.mp4

(2)camera测试

在代码中,file_type选择camera。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

《caffe学习之路》第五章:Ubuntu16.04 caffe ssd 在QT环境上编译运行ssd_detect.cpp 的相关文章

  • 【caffe-windows】 caffe-master 之 cifar10 超详细

    本教程尽量详细 大多步骤都有图 如果运行出错 请先对照自己的文件是否和图上的一样 包括标点啊 空格啊 斜杠 反斜杠啊之类的小细节 本例程是在 win10 64位 caffe master vs2013下进行的 并且已经配置GPU版本 若用C
  • caffe源码 之 CPU与GPU数据同步类

    本文主要解析caffe源码文件 src caffe SycedMem cpp 该文件主要实现cpu与gpu的内存同步 先看SycedMem hpp中SycedMem的类定义 ifndef CAFFE SYNCEDMEM HPP define
  • [caffe]:检查失败:检查失败:hdf_blobs_[i]->shape(0) == num(200 vs. 6000)

    我有训练并将数据标记为 data mat 我有 200 个训练数据 包含 6000 个特征 标签为 1 1 已保存在 data mat 中 我正在尝试将数据转换为 hdf5 并使用以下命令运行 C affe load data mat hd
  • 大图像的语义分割

    我正在处理数量有限的大尺寸图像 每个图像都可以有3072 3072像素 为了使用 FCN 或 U net 训练语义分割模型 我构建了一个大样本的训练集 每个训练图像是128 128 在预测阶段 我所做的是将大图像切成小块 与训练集相同128
  • 解决类别不平衡:扩大对损失和 SGD 的贡献

    已添加对此问题的更新 我是比利时根特大学的研究生 我的研究是关于深度卷积神经网络的情感识别 我正在使用Caffe实施 CNN 的框架 最近我遇到了一个关于班级不平衡的问题 我正在使用大约 9216 个训练样本 5 被标记为阳性 1 其余样本
  • 如何修改批量归一化层(DeconvNet)以便能够与 caffe 一起运行?

    我想运行反卷积网络在我的数据上 但是它似乎是为另一个版本编写的caffe 有谁知道如何改变batch params Deconvnet 中的那个 layers bottom conv1 1 top conv1 1 name bn1 1 ty
  • 三元组损失的softmax版本的梯度计算

    我一直在尝试在Caffe中实现softmax版本的三元组损失 描述于 霍弗和艾隆 使用三元组网络进行深度度量学习 ICLR 2015 我已经尝试过这个 但我发现很难计算梯度 因为指数中的 L2 不是平方的 有人可以帮我吗 使用现有的 caf
  • Caffe 模型为每个图像提供相同的输出

    我刚刚使用预定义的 prototxt 和 caffemodel 文件在 caffe 中加载了 alexnet 然而 将任何图像发送到模型都会返回与 fc7 层的输出相同的值 这是代码片段 net caffe Net alexnet trai
  • Caffe 快照:.solverstate 与 .caffemodel

    训练网络时 每 N 次迭代拍摄的快照有两种形式 一个是 solverstate 文件 我想它就像它听起来的那样 存储损失函数和梯度的状态等 另一个是 caffemodel 文件 我知道它存储训练后的参数 如果您想要预训练的模型 caffem
  • 在 ubuntu 16.04 中安装 Caffe 时遇到困难

    操作系统 ubuntu 16 04 CUDA 7 5 库德恩 5 我正在关注this https github com BVLC caffe wiki Ubuntu 16 04 or 15 10 OpenCV 3 1 Installatio
  • Caffe/pyCaffe:设置所有 GPU

    是否可以为Caffe 尤其是pyCaffe 设置所有GPU 就像是 caffe train solver examples mnist lenet solver prototxt gpu all 这两个分支现在都支持多 GPU 一段时间了
  • PyInstaller“ValueError:太多值无法解压”

    pyinstaller 版本 3 2 操作系统 win10 我的 python 脚本在 Winpython Python 解释器中运行良好 但是当我使用 Pyinstaller 包时 python 脚本包含 caffe 模块 我将面临的问题
  • nvcc fatal:安装 cuda 9.1+caffe+openCV 3.4.0 时不支持 gpu 架构“compute_20”

    我已经安装了CUDA 9 1 cudnn 9 1 opencv 3 4 0 caffe 当我尝试跑步时make all j8 in caffe目录下 出现这个错误 nvcc fatal 不支持的 GPU 架构 compute 20 我尝试过
  • 在 Yosemite 上编译 caffe

    我正在尝试在 Yosemite 上安装 caffe 但我的 C 不是最强的 这是我的错误 Alis MacBook Pro caffe ali make all NVCC src caffe layers absval layer cu u
  • Caffe:如果内存中只能容纳一小部分,我该怎么办?

    我正在尝试训练一个非常大的模型 因此 我只能将非常小的批量大小放入 GPU 内存中 处理小批量的结果非常噪声梯度估计 https stackoverflow com a 33717093 1714410 我该怎么做才能避免这个问题 您可以更
  • 如何加载 caffe 模型并转换为 numpy 数组?

    我有一个 caffemodel 文件 其中包含 ethereon 的 caffe tensorflow 转换实用程序不支持的层 我想生成我的咖啡模型的 numpy 表示 我的问题是 如何将 caffemodel 文件 我还有 prototx
  • 如何在 Caffe 中从头开始训练 ResNet101 模型?

    我正在使用深度实验室 v2 https bitbucket org aquariusjay deeplab public ver2Caffe 版本 以便进行语义分割 我可以使用 imagenet 模型微调 ResNet101 但无法使用自定
  • caffe reshape / 上采样全连接层

    假设我们有一个像这样的层 layer name fully connected type InnerProduct bottom bottom top top inner product param num output 1 输出是batc
  • 卷积 ImageNet 网络对于翻转图像具有不变性

    我正在使用深度学习 caffe 框架进行图像分类 我有一些有头像的硬币 有些是左向的 有些是右向的 为了对它们进行分类 我使用常见的方法 从预训练的 ImageNet 网络中获取权重和结构 该网络已经捕获了大量图像模式 并主要训练最后一层以
  • Caffe 多输入图像

    我正在考虑实现一个 Caffe CNN 它接受两个输入图像和一个标签 后来可能是其他数据 并且想知道是否有人知道 prototxt 文件中执行此操作的正确语法 它只是一个带有额外顶部的 IMAGE DATA 层吗 或者我应该为每个层使用单独

随机推荐

  • Spring源码深度解析:三、容器的刷新 - refresh()

    一 前言 文章目录 Spring源码深度解析 文章目录 我们先通过Spring源码的整体流程 来了解Spring的工作流程是什么 接着根据这个工作流程一步一步的阅读源码 二 Spring容器的启动 public class Test pub
  • QT页面旋转涉及源码修改

    QT页面旋转涉及源码修改 qlinuxfbscreen cpp qlinuxfbscreen h qt页面旋转 在源码中直接搜索这两个文件名称 直接替换内容即可 qlinuxfbscreen cpp Copyright C 2016 The
  • Mongo进阶--存储原理

    存储引擎 Storage wiredTiger引擎 3 0新增引擎 官方宣称在read insert和复杂的update下具有更高的性能 所以后续版本 我们建议使用wiredTiger 所有的write请求都基于 文档级别 的lock 因此
  • GitHub 供应链安全已支持 Dart 开发者生态

    通过 Dart 和 GitHub 团队的共同努力 自 10 月 7 日起 GitHub 的 Advisory Database 安全咨询数据库 Dependency Graph 依赖项关系图 和 Dependabot 依赖更新机器人 开始支
  • MySQL 时间减法

    select date sub curdate interval 1 SECOND 减一秒 select date sub curdate interval 1 MINUTE 减一分钟 select date sub curdate int
  • linux远程telnet和ss都连不上,CentOS7 可以ping通 但是telnet无法连接上端口的问题

    在一台全新的Linux上部署项目 遇到了一些问题 1 安装zookeeper 启动成功 正常运行 本地通过telnet无法连接到zookeeper 可能原因 1 可能是端口没有起来 通过ss ntl可以清楚看到 2181端口已经启动 起来了
  • P1005 最大公约数

    算法 欧几里得辗转相除法 include
  • 文件包含 78-79

    web78 没有什么绕过 file php filter convert base64 encode resource flag php构建这个伪协议之后可以得到flag 首先这是一个file关键字的get参数传递 php 是一种协议名称
  • 2020年中国研究生数学建模竞赛B题

    降低汽油精制过程中的辛烷值损失模型 一 背景 汽油是小型车辆的主要燃料 汽油燃烧产生的尾气排放对大气环境有重要影响 为此 世界各国都制定了日益严格的汽油质量标准 见下表 汽油清洁化重点是降低汽油中的硫 烯烃含量 同时尽量保持其辛烷值 欧盟和
  • JavaScript的一些设计原则

    1 单一职责原则 SRP 单一职责原则通常指 一个类只有一种功能 但是JavaScript是一门面向对象的语言 没有类的概念 所以单一职责在JavaScript中的含义是 一个对象 方法 只有一种功能 那么为什么需要单一职责原则呢 是因为不
  • 「Web3大厂」价值70亿美元的核心竞争力

    经过近 5 年的研发和酝酿 Linea 团队在 7 月的巴黎 ETHCC 大会期间宣布了主网 Alpha 的上线 引起了社区的广泛关注 截止 8 月 4 日 据 Dune 数据信息显示 其主网在一周内就涌入了 100 多个生态项目 跨入了超
  • 远程桌面链接怎么用(win10电脑远程桌面连接工具怎么使用)

    相信很多人都已经使用过QQ的远程协助 远程协助功能可以实现好友间桌面共享 还可以让好友操作自己的电脑 帮助解决一些电脑问题 然而 很多人却忽略了Windows本身就附带的一个功能 远程桌面连接 其实它的功能 性能等一点都不弱 而且它比很多第
  • 融云荣获「2023 中国数字生态通信领军企业」奖

    融云北极星如何协助开发者排查问题和预警风险 8月17日直播课 点击上方报名 由 B P 商业伙伴主办的 2023 数字生态大会 于 8 月 4 日在京举行 融云携数智办公解决方案受邀参展 并获 2023 中国数字生态通信领军企业 奖 关注
  • 微信H5页面背景音乐自动播放

    移动端默认是禁止背景音乐自动播放的 很多需求都需要在页面加载完成的情况下同时出现背景音乐 基于微信的H5页面的音频自动播放的方法网上有很多教程 本次分享的只是一种思路
  • angular 单元测试jest

    前言 最近公司要求笔者开发编写项目单元测试 之前使用过angular框架 但是不知道原来在生成组件的时候多的内个文件 name spec ts 是用来编写angular的单元测试的 下面简单介绍一下关于单元测试的一些问题 单元测试代码和业务
  • java基础:初始化块

    初始化块 1 什么是初始化块 初始化块是java类中可出现的第四种成员 成员变量 方法 构造器 一个类中可以有多个初始化块 2 初始化块的作用 从某种程度来看 初始化块是构造器的补充 初始化块总是在构造器执行之前执行 系统通压根可以使用初始
  • CUDA 初体验

    CUDA Visual Profiler CUDA编程指导 shared memory Page locked out memory C CUDA 调用 CUDA 编程介绍 CUDA 数据同步 CUDA Visual Profiler 在上
  • 关于静态批处理/动态批处理/GPU Instancing /SRP Batcher的详细剖析

    静态批处理 1 定义 标明为 Static 的静态物件 如果在使用相同材质球的条件下 在Build 项目打包 的时候Unity会自动地提取这些共享材质的静态模型的Vertex buffer和Index buffer 根据其摆放在场景中的位置
  • 刷脸支付成众多创业者青睐的项目

    风口正盛 优势尽显 刷脸支付成了众多投资者与创业者青睐的项目 布局刷脸支付行业 快速抢占头部市场 支付机构是供给方 商家B端和用户C端是需求方 而中间ISV服务商的作用就至关重要了 虽然未来存在很多变数 但刷脸支付的趋势不可阻挡 用户使用比
  • 《caffe学习之路》第五章:Ubuntu16.04 caffe ssd 在QT环境上编译运行ssd_detect.cpp

    大多深度学习框架主要支持python 而caffe提供c 接口 这也是我选择caffe框架的原因 前一章说到examples ssd目录下的ssd detect cpp文件是weiliu等大神给我们提供的 算是一个c 实现demo 这一章主