caffemodelではほとんど問題にYOLOv3について

まず第一に、私は参照してくださいhttps://blog.csdn.net/Chen_yingpeng/article/details/80692018 caffemodelに変身ダークネット-yolov3を達成するために提供さyolov3_darknet2caffe.pyスクリプトは、prototxtとcaffemodelてきました。

しかし、私は陳は、サーバーにはsudoの権限がないので、opencv3をインストールすることはできません、提供コンパイル-yolov3をCAFFEとき、それは正常にコンパイルすることはできません、カフェの前に、使用中のMobileNet-YOLOv3に応じたため、私が使用します。https:// githubの.COM / eric612 / MobileNet-YOLOは(ブロガーが既に完全に使用cmakeのを通してMobileNet-YOLOコンパイルされる前に)ブロガーのニーズに応じてコースの試験は、(いくつかの変更されたssd_detect.cpp / yolo_detect.cppを提供しました関連のコード)

使用ssd_detect.cppのMobileNet-YOLO陳、すなわち適切なYOLOのdetection_out層と最終層を追加するために、yolov3.prototxt特定の適応上必要な変換を提供する提供、特定の基準フレームが与えられることに注意してくださいprototxtファイルの変更。

ショーの写真がcaffemodelを発見した後、最終的には通常のテストは、より悪い多くの下でダークネットに関してリコール交通標識で見つかった集中テスト具体的な目標の専用の時間にデモ試験後、結果がまだ正常である、caffemodelの1に変換しますが、我々のデータ青は、状況は依然として深刻わずかに良いですが、後にトレーニングデータの増加、赤の交通標識の検出を無視します。

次のようにこのような理由から、私は陳が提供コンバートPythonのデバッグコードです、変換の値がどの重みの一部は、(全体的なコードの最も重要な部分)は次のとおりです。

def darknet2caffe(cfgfile, weightfile, protofile, caffemodel):
    net_info = cfg2prototxt(cfgfile)
    save_prototxt(net_info , protofile, region=False)

    net = caffe.Net(protofile, caffe.TEST)
    params = net.params

    blocks = parse_cfg(cfgfile)

    #Open the weights file
    fp = open(weightfile, "rb")

    #The first 4 values are header information 
    # 1. Major version number
    # 2. Minor Version Number
    # 3. Subversion number 
    # 4. IMages seen 
    header = np.fromfile(fp, dtype = np.int32, count = 5)

    #fp = open(weightfile, 'rb')
    #header = np.fromfile(fp, count=5, dtype=np.int32)
    #header = np.ndarray(shape=(5,),dtype='int32',buffer=fp.read(20))
    #print(header)
    buf = np.fromfile(fp, dtype = np.float32)
    #print(buf)
    fp.close()

    layers = []
    layer_id = 1
    start = 0
    for block in blocks:
        if start >= buf.size:
            break

        if block['type'] == 'net':
            continue
        elif block['type'] == 'convolutional':
            batch_normalize = int(block['batch_normalize'])
            if block.has_key('name'):
                conv_layer_name = block['name']
                bn_layer_name = '%s-bn' % block['name']
                scale_layer_name = '%s-scale' % block['name']
            else:
                conv_layer_name = 'layer%d-conv' % layer_id
                bn_layer_name = 'layer%d-bn' % layer_id
                scale_layer_name = 'layer%d-scale' % layer_id

            if batch_normalize:
                start = load_conv_bn2caffe(buf, start, params[conv_layer_name], params[bn_layer_name], params[scale_layer_name])
            else:
                start = load_conv2caffe(buf, start, params[conv_layer_name])
            layer_id = layer_id+1
        elif block['type'] == 'depthwise_convolutional':
            batch_normalize = int(block['batch_normalize'])
            if block.has_key('name'):
                conv_layer_name = block['name']
                bn_layer_name = '%s-bn' % block['name']
                scale_layer_name = '%s-scale' % block['name']
            else:
                conv_layer_name = 'layer%d-dwconv' % layer_id
                bn_layer_name = 'layer%d-bn' % layer_id
                scale_layer_name = 'layer%d-scale' % layer_id

            if batch_normalize:
                start = load_conv_bn2caffe(buf, start, params[conv_layer_name], params[bn_layer_name], params[scale_layer_name])
            else:
                start = load_conv2caffe(buf, start, params[conv_layer_name])
            layer_id = layer_id+1
        elif block['type'] == 'connected':
            if block.has_key('name'):
                fc_layer_name = block['name']
            else:
                fc_layer_name = 'layer%d-fc' % layer_id
            start = load_fc2caffe(buf, start, params[fc_layer_name])
            layer_id = layer_id+1
        elif block['type'] == 'maxpool':
            layer_id = layer_id+1
        elif block['type'] == 'avgpool':
            layer_id = layer_id+1
        elif block['type'] == 'region':
            layer_id = layer_id + 1
        elif block['type'] == 'route':
            layer_id = layer_id + 1
        elif block['type'] == 'shortcut':
            layer_id = layer_id + 1
        elif block['type'] == 'softmax':
            layer_id = layer_id + 1
        elif block['type'] == 'cost':
            layer_id = layer_id + 1
	elif block['type'] == 'upsample':
	    layer_id = layer_id + 1
        else:
            print('unknow layer type %s ' % block['type'])
            layer_id = layer_id + 1
    print('save prototxt to %s' % protofile)
    save_prototxt(net_info , protofile, region=True)
    print('save caffemodel to %s' % caffemodel)
    net.save(caffemodel)

......


def load_conv_bn2caffe(buf, start, conv_param, bn_param, scale_param):
    conv_weight = conv_param[0].data
    running_mean = bn_param[0].data
    running_var = bn_param[1].data
    scale_weight = scale_param[0].data
    scale_bias = scale_param[1].data

    
   
    scale_param[1].data[...] = np.reshape(buf[start:start+scale_bias.size], scale_bias.shape); start = start + scale_bias.size
    #print scale_bias.size
    #print scale_bias

    scale_param[0].data[...] = np.reshape(buf[start:start+scale_weight.size], scale_weight.shape); start = start + scale_weight.size
    #print scale_weight.size

    bn_param[0].data[...] = np.reshape(buf[start:start+running_mean.size], running_mean.shape); start = start + running_mean.size
    #print running_mean.size

    bn_param[1].data[...] = np.reshape(buf[start:start+running_var.size], running_var.shape); start = start + running_var.size
    #print running_var.size

    bn_param[2].data[...] = np.array([1.0])
    conv_param[0].data[...] = np.reshape(buf[start:start+conv_weight.size], conv_weight.shape); start = start + conv_weight.size
    #print conv_weight.size

    return start

重量が読み出さyolov3.weights特徴、BUFは、重み記憶ダークネットの重みに従って、bufが全ての層に蓄積yolov3により得られる1次元ベクトル、寸法X 1 61592497、及び各記録開始されます層の重みは、開始位置。しかし、caffemodelに切り替えた後、出力チャンネル32、カーネルサイズにベクトル寸法変化、例えば64x32x3x3(表し畳み込み層入力チャンネル64、(caffemodel書き込まload_conv_bn2caffe(で取得した右コード値)が来るBUF) 3×3)であり、このステップはnumpyのパッケージ()関数を再形成主としてload_conv_bn2caffeによって完成されます。ない対応する重みがRGBに影響を与える場合したがって、最終的な試験結果はどうか四次元変形の減少を引き起こす原因ダークネットに順に発生するオフセット。

私は、ssd_detection.cppのMobileNet-YOLO設けられ、開始画像からネットワークの入力部を用いて調べ、以下のように、コードの例は以下のとおりです。

		  cv::Mat img = cv::imread(fn[k]);
		  if (img.empty()) continue; //only proceed if sucsessful
									// you probably want to do some preprocessing
		  CHECK(!img.empty()) << "Unable to decode image " << file;
		  Timer batch_timer;
		  batch_timer.Start();
		  std::vector<vector<float> > detections = detector.Detect(img);
		  LOG(INFO) << "Computing time: " << batch_timer.MilliSeconds() << " ms.";

上記のコードから、読み取った画像は、OpenCVの関数imread()関数で使用され、着信IMG検出器のテストを読み取るために、以下のように三つのサブ機能を含む、クラスクラス検出器のように定義されます。

class Detector {
 public:
  Detector(const string& model_file,
           const string& weights_file,
           const string& mean_file,
           const string& mean_value,
		   const float confidence_threshold,
		   const float normalize_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);
  void Preprocess(const cv::Mat& img,
	  std::vector<cv::Mat>* input_channels,double normalize_value);
 private:
  shared_ptr<Net<float> > net_;
  cv::Size input_geometry_;
  int num_channels_;
  cv::Mat mean_;
  float nor_val = 1.0;
};

4つのサブ関数の入力IMGのみサイズ変更操作運ばRGBチャネルを変換し、テストしていません。

そこから私はいくつかのインスピレーションを得るように見える、RGB画像関数imread OpenCVの読み取りは、青と赤の検出における道路標識に対応するように起こるかどうか、BGR順序に従って読まれる法律を逃しましたか?私は、次に読み出すIMREAD(2)のIMGチャネルを読み取り、チャネル(0)の交換、及び、検出器試験結果(スコア及び座標情報)への入力は矩形()関数をテストするために使用されるRGBチャネルの変換に描画されていません元IMG、リシェイプ陳でコードを変換証明したダークネットの下で、基本的には同じ結果と通常の試験結果は、全く間違っを提供していないが、私は(関数imreadでCVを使用)を直接検出器のリード線にことがわかりました。

なぜ(SSDなど、RefineDet、など)私のオリジナルダークネットやカフェ、他のモデル後の考慮から、この場合には表示されないのですか?私は探検するために行きました。関数load_image_color()、次のコードは、特定のSRC / image.cに、コードダークネット画像入力部を読み取ります。

image load_image_color(char *filename, int w, int h)
{
    return load_image(filename, w, h, 3);
}

image load_image(char *filename, int w, int h, int c)
{
#ifdef OPENCV
    image out = load_image_cv(filename, c);
#else
    image out = load_image_stb(filename, c);
#endif

    if((h && w) && (h != out.h || w != out.w)){
		//按网络要求调整到(w,h)大小,前提是输入的w,h不要是0
        image resized = resize_image(out, w, h);
        free_image(out);
        out = resized;
    }
    return out;
}

私たちが知っているので、どのload_image()関数が利用ダークネット品種で明らかにまだ、load_image_cv()関数を呼び出すには、CVはBGRフォーマットに従って読まれている2つの方法で関数imread(C ++)とcvLoadImage(C#の)の画像を読み、画像を読み取りますこれは次のようにload_image_cv()関数のコードを見て、私はさらに困惑します:

image load_image_cv(char *filename, int channels)
{
    IplImage* src = 0;
    int flag = -1;
    if (channels == 0) flag = -1;
    else if (channels == 1) flag = 0;  //grayscale image
    else if (channels == 3) flag = 1;  //3-channel color image
    else {
        fprintf(stderr, "OpenCV can't force load with %d channels\n", channels);
    }
 
	//opencv api load image
    if( (src = cvLoadImage(filename, flag)) == 0 )
    {
        fprintf(stderr, "Cannot load image \"%s\"\n", filename);
        char buff[256];
        sprintf(buff, "echo %s >> bad.list", filename);
        system(buff);
        return make_image(10,10,3);
        //exit(0);
    }

	//将读取到的IplImage容器中的图片装入image结构中
    image out = ipl_to_image(src);
    cvReleaseImage(&src);
    rgbgr_image(out); //convert BGR to RGB
    
    return out;
}

 

おすすめ

転載: blog.csdn.net/xunan003/article/details/94741304