当前位置: 首页 > wzjs >正文

门户网站建设询价公告网络营销专业介绍

门户网站建设询价公告,网络营销专业介绍,一家专做中式设计的网站,wordpress crossapple概述 本文将详细介绍如何在Linux环境下部署MTCNN模型进行人脸检测,并使用NCNN框架进行推理。 1. CMake的安装与配置 下载CMake源码 前往CMake官网下载,找到适合您系统的最新版本tar.gz文件链接,或者直接通过wget下载:CMake官方…

概述

本文将详细介绍如何在Linux环境下部署MTCNN模型进行人脸检测,并使用NCNN框架进行推理。

1. CMake的安装与配置

下载CMake源码

前往CMake官网下载,找到适合您系统的最新版本tar.gz文件链接,或者直接通过wget下载:CMake官方下载页面https://cmake.org/download/

cd ~
wget https://github.com/Kitware/CMake/releases/download/v3.x.x/cmake-3.x.x.tar.gz

请将3.x.x替换为您想要安装的具体版本号。

解压并进入解压后的目录

tar -xzvf cmake-3.x.x.tar.gz
cd cmake-3.x.x

编译与安装

  1. 配置编译选项:使用bootstrap脚本进行配置:

    ./bootstrap
  2. 编译:使用所有可用的核心进行并行编译:

    make -j$(nproc)
  3. 安装:将CMake安装到系统中:

    sudo make install
  4. 刷新共享库缓存(如果需要):

    sudo ldconfig

安装完成后,再次运行以下命令验证安装是否成功:

cmake --version

配置环境变量(可选)

如果您选择自定义安装路径(例如/usr/local/bin以外的路径),可能需要手动配置环境变量以确保系统能够找到新安装的CMake。

编辑~/.bashrc~/.zshrc文件(取决于您使用的shell),添加以下行:

export PATH=/path/to/cmake/bin:$PATH

其中/path/to/cmake/bin是您指定的CMake安装路径下的bin目录。

保存文件后,运行以下命令使更改生效:

source ~/.bashrc  # 对于Bash用户
# 或者
source ~/.zshrc   # 对于Zsh用户

2. Protobuf的安装

更新系统软件包

首先,更新您的系统软件包列表,确保所有现有的包都是最新的:

sudo apt-get update
sudo apt-get upgrade

安装依赖项

安装构建Protobuf所需的各种工具和库:

sudo apt-get install autoconf automake libtool curl make g++ unzip

下载Protobuf源码

您可以从GitHub上克隆官方Protobuf仓库,或者直接下载特定版本的压缩包。这里我们使用Git进行操作:

cd ~
git clone https://github.com/protocolbuffers/protobuf.git
cd protobuf
git submodule update --init --recursive

编译Protobuf

创建并进入构建目录

为了保持源代码目录的整洁,建议在一个新的目录中进行编译:

cd ~/protobuf
mkdir -p build && cd build

使用CMake配置项目

CMake是一个跨平台的构建系统生成器,支持多种IDE和构建工具。

  1. 配置CMake:

    cmake .. -DCMAKE_BUILD_TYPE=Release
  2. 编译Protobuf:

    make -j$(nproc)
  3. 安装Protobuf:

    sudo make install
    sudo ldconfig  # 刷新共享库缓存

验证安装

检查版本信息

验证Protobuf是否正确安装,并检查其版本号:

protoc --version

您应该看到类似如下的输出:

libprotoc 3.x.x

其中3.x.x是具体的版本号。

配置环境变量(可选)

如果希望在任何位置都能直接运行protoc命令,而无需指定完整路径,可以将Protobuf的bin目录添加到系统的PATH环境变量中。编辑~/.bashrc~/.zshrc文件,根据您的shell类型,添加以下行:

export PATH=$PATH:/usr/local/bin

保存文件后,运行以下命令使更改生效:

source ~/.bashrc  # 对于Bash用户
# 或者
source ~/.zshrc   # 对于Zsh用户

3. OpenCV库的安装与配置

更新系统软件包

首先,更新您的系统软件包列表:

sudo apt-get update
sudo apt-get upgrade

安装依赖项

安装构建OpenCV所需的各种工具和库:

sudo apt-get install build-essential cmake git pkg-config libgtk-3-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install python3-dev python3-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev
sudo apt-get install libdc1394-22-dev libopenblas-dev liblapack-dev gfortran
sudo apt-get install libprotobuf-dev protobuf-compiler

下载OpenCV源码

您可以通过Git克隆OpenCV的GitHub仓库来获取最新的稳定版本:

cd ~
git clone https://github.com/opencv/opencv.git
cd opencv
git checkout 4.x # 替换为所需的版本号# 克隆contrib仓库(可选)
cd ~
git clone https://github.com/opencv/opencv_contrib.git
cd opencv_contrib
git checkout 4.x # 确保与主仓库版本一致

编译OpenCV

创建并进入构建目录

cd ~/opencv
mkdir -p build && cd build

使用CMake配置项目

运行CMake以配置构建选项。这里我们指定一些常用的选项,例如启用Python支持、设置安装路径等。如果您不需要这些功能或使用了不同的路径,请相应地调整命令。

cmake -D CMAKE_BUILD_TYPE=Release \-D CMAKE_INSTALL_PREFIX=/usr/local \-D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \-D BUILD_opencv_python3=ON \-D PYTHON3_EXECUTABLE=$(which python3) \-D PYTHON3_INCLUDE_DIR=$(python3 -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())") \-D PYTHON3_PACKAGES_PATH=$(python3 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())") ..

编译

make -j$(nproc)

这可能需要一些时间,具体取决于您的硬件性能。

安装

完成编译后,使用以下命令安装OpenCV到系统中:

sudo make install
sudo ldconfig

验证安装

查找头文件和库文件

安装完成后,OpenCV的头文件通常位于/usr/local/include/opencv4/,而库文件则位于/usr/local/lib/

您可以检查这些位置是否包含必要的文件:

ls /usr/local/include/opencv4/
ls /usr/local/lib/

4. ncnn库在Linux环境下的编译

更新系统软件包

首先,更新您的系统软件包列表,确保所有现有的包都是最新的:

sudo apt-get update
sudo apt-get upgrade

安装依赖项

安装构建NCNN所需的各种工具和库:

sudo apt-get install build-essential cmake git libprotobuf-dev protobuf-compiler
sudo apt-get install libvulkan-dev vulkan-utils  # 如果需要Vulkan支持

libprotobuf-devprotobuf-compiler 是用于处理模型文件(如 .param.bin 文件)的必要依赖项。

下载NCNN源码

您可以通过Git克隆NCNN的GitHub仓库来获取最新的稳定版本:

cd ~
git clone https://github.com/Tencent/ncnn.git
cd ncnn

如果您想要特定的版本,可以切换到对应的分支或标签:

git checkout <branch_or_tag_name>

例如,切换到最新稳定版:

git checkout master

编译NCNN

创建并进入构建目录

为了保持源代码目录的整洁,建议在一个新的目录中进行编译:

mkdir -p build && cd build

使用CMake配置项目

运行CMake以配置构建选项。这里我们指定一些常用的选项,例如启用Vulkan支持、设置安装路径等。如果您不需要这些功能或使用了不同的路径,请相应地调整命令。

cmake .. \-DCMAKE_BUILD_TYPE=Release \-DNCNN_VULKAN=ON \  # 如果你希望使用Vulkan加速,请启用此选项-DNCNN_PROTOBUF_USE_SYSTEM=ON \-DProtobuf_DIR=/usr/lib/x86_64-linux-gnu/pkgconfig \  # 手动指定 Protobuf 的路径-DProtobuf_INCLUDE_DIR=/usr/include \-DProtobuf_LIBRARY=/usr/lib/x86_64-linux-gnu/libprotobuf.so \-DProtobuf_PROTOC_EXECUTABLE=/usr/bin/protoc

    编译

    使用所有可用的核心进行并行编译:

    make -j$(nproc)

    这可能需要一些时间,具体取决于您的硬件性能。

    安装

    完成编译后,使用以下命令安装NCNN到系统中:

    sudo make install
    sudo ldconfig  # 刷新共享库缓存

    默认情况下,头文件会被安装到 /usr/local/include/ncnn,库文件会被安装到 /usr/local/lib

    验证安装

    查找头文件和库文件

    安装完成后,NCNN的头文件通常位于 /usr/local/include/ncnn,而库文件则位于 /usr/local/lib

    您可以检查这些位置是否包含必要的文件:

    ls /usr/local/include/ncnn/
    ls /usr/local/lib/

    5. MTCNN源码

    ncnn框架实现的mtcnn主要包含两个核心代码文件mtcnn.h,mtcnn.cpp

    mtcnn.h代码如下:

    #pragma once#ifndef __MTCNN_NCNN_H__
    #define __MTCNN_NCNN_H__
    #include <ncnn/net.h>
    #include <string>
    #include <vector>
    #include <time.h>
    #include <algorithm>
    #include <map>
    #include <iostream>using namespace std;
    struct Bbox
    {float score;int x1;int y1;int x2;int y2;bool exist;float area;float ppoint[10];float regreCoord[4];
    };class MTCNN {public:MTCNN(const string& model_path);MTCNN(const std::vector<std::string> param_files, const std::vector<std::string> bin_files);~MTCNN();void configure_ncnn(ncnn::Net& net, int num_threads);void SetMinFace(int minSize);void detect(ncnn::Mat& img_, std::vector<Bbox>& finalBbox);
    private:void generateBbox(ncnn::Mat score, ncnn::Mat location, vector<Bbox>& boundingBox_, float scale);void nms(vector<Bbox>& boundingBox_, const float overlap_threshold, string modelname = "Union");void refine(vector<Bbox>& vecBbox, const int& height, const int& width, bool square);void PNet();void RNet();void ONet();ncnn::Net Pnet, Rnet, Onet;ncnn::Mat img;const float nms_threshold[3] = { 0.5f, 0.7f, 0.7f };const float mean_vals[3] = { 127.5, 127.5, 127.5 };const float norm_vals[3] = { 0.0078125, 0.0078125, 0.0078125 };const int MIN_DET_SIZE = 12;std::vector<Bbox> firstBbox_, secondBbox_, thirdBbox_;int img_w, img_h;private://部分可调参数const float threshold[3] = { 0.8f, 0.8f, 0.6f };int minsize = 20;const float pre_facetor = 0.709f;};#endif //__MTCNN_NCNN_H__
    

    mtcnn.cpp代码如下:

    #include "mtcnn.h"bool cmpScore(Bbox lsh, Bbox rsh) {if (lsh.score < rsh.score)return true;elsereturn false;
    }bool cmpArea(Bbox lsh, Bbox rsh) {if (lsh.area < rsh.area)return false;elsereturn true;
    }MTCNN::MTCNN(const std::string& model_path) {std::vector<std::string> param_files = {model_path + "/det1.param",model_path + "/det2.param",model_path + "/det3.param"};std::vector<std::string> bin_files = {model_path + "/det1.bin",model_path + "/det2.bin",model_path + "/det3.bin"};// 配置多线程int num_threads = 4; // 设置线程数configure_ncnn(Pnet, num_threads);configure_ncnn(Rnet, num_threads);configure_ncnn(Onet, num_threads);// 加载模型Pnet.load_param(param_files[0].data());Pnet.load_model(bin_files[0].data());Rnet.load_param(param_files[1].data());Rnet.load_model(bin_files[1].data());Onet.load_param(param_files[2].data());Onet.load_model(bin_files[2].data());
    }MTCNN::~MTCNN(){Pnet.clear();Rnet.clear();Onet.clear();
    }void MTCNN::configure_ncnn(ncnn::Net& net, int num_threads) {ncnn::Option opt;opt.num_threads = num_threads; // 设置线程数opt.use_vulkan_compute = false; // 如果不使用 Vulkan,设置为 falsenet.opt = opt;
    }void MTCNN::SetMinFace(int minSize){minsize = minSize;
    }void MTCNN::generateBbox(ncnn::Mat score, ncnn::Mat location, std::vector<Bbox>& boundingBox_, float scale){const int stride = 2;const int cellsize = 12;//score pfloat *p = score.channel(1);//score.data + score.cstep;//float *plocal = location.data;Bbox bbox;float inv_scale = 1.0f/scale;for(int row=0;row<score.h;row++){for(int col=0;col<score.w;col++){if(*p>threshold[0]){bbox.score = *p;bbox.x1 = round((stride*col+1)*inv_scale);bbox.y1 = round((stride*row+1)*inv_scale);bbox.x2 = round((stride*col+1+cellsize)*inv_scale);bbox.y2 = round((stride*row+1+cellsize)*inv_scale);bbox.area = (bbox.x2 - bbox.x1) * (bbox.y2 - bbox.y1);const int index = row * score.w + col;for(int channel=0;channel<4;channel++){bbox.regreCoord[channel]=location.channel(channel)[index];}boundingBox_.push_back(bbox);}p++;//plocal++;}}
    }void MTCNN::nms(std::vector<Bbox> &boundingBox_, const float overlap_threshold, string modelname){if(boundingBox_.empty()){return;}sort(boundingBox_.begin(), boundingBox_.end(), cmpScore);float IOU = 0;float maxX = 0;float maxY = 0;float minX = 0;float minY = 0;std::vector<int> vPick;int nPick = 0;std::multimap<float, int> vScores;const int num_boxes = boundingBox_.size();vPick.resize(num_boxes);for (int i = 0; i < num_boxes; ++i){vScores.insert(std::pair<float, int>(boundingBox_[i].score, i));}while(vScores.size() > 0){int last = vScores.rbegin()->second;vPick[nPick] = last;nPick += 1;for (std::multimap<float, int>::iterator it = vScores.begin(); it != vScores.end();){int it_idx = it->second;maxX = (std::max)(boundingBox_.at(it_idx).x1, boundingBox_.at(last).x1);maxY = (std::max)(boundingBox_.at(it_idx).y1, boundingBox_.at(last).y1);minX = (std::min)(boundingBox_.at(it_idx).x2, boundingBox_.at(last).x2);minY = (std::min)(boundingBox_.at(it_idx).y2, boundingBox_.at(last).y2);//maxX1 and maxY1 reuse maxX = ((minX-maxX+1)>0)? (minX-maxX+1) : 0;maxY = ((minY-maxY+1)>0)? (minY-maxY+1) : 0;//IOU reuse for the area of two bboxIOU = maxX * maxY;if(!modelname.compare("Union"))IOU = IOU/(boundingBox_.at(it_idx).area + boundingBox_.at(last).area - IOU);else if(!modelname.compare("Min")){IOU = IOU/((boundingBox_.at(it_idx).area < boundingBox_.at(last).area)? boundingBox_.at(it_idx).area : boundingBox_.at(last).area);}if(IOU > overlap_threshold){it = vScores.erase(it);}else{it++;}}}vPick.resize(nPick);std::vector<Bbox> tmp_;tmp_.resize(nPick);for(int i = 0; i < nPick; i++){tmp_[i] = boundingBox_[vPick[i]];}boundingBox_ = tmp_;
    }void MTCNN::refine(vector<Bbox> &vecBbox, const int &height, const int &width, bool square){if(vecBbox.empty()){cout<<"Bbox is empty!!"<<endl;return;}float bbw=0, bbh=0, maxSide=0;float h = 0, w = 0;float x1=0, y1=0, x2=0, y2=0;for(vector<Bbox>::iterator it=vecBbox.begin(); it!=vecBbox.end();it++){bbw = (*it).x2 - (*it).x1 + 1;bbh = (*it).y2 - (*it).y1 + 1;x1 = (*it).x1 + (*it).regreCoord[0]*bbw;y1 = (*it).y1 + (*it).regreCoord[1]*bbh;x2 = (*it).x2 + (*it).regreCoord[2]*bbw;y2 = (*it).y2 + (*it).regreCoord[3]*bbh;if(square){w = x2 - x1 + 1;h = y2 - y1 + 1;maxSide = (h>w)?h:w;x1 = x1 + w*0.5 - maxSide*0.5;y1 = y1 + h*0.5 - maxSide*0.5;(*it).x2 = round(x1 + maxSide - 1);(*it).y2 = round(y1 + maxSide - 1);(*it).x1 = round(x1);(*it).y1 = round(y1);}//boundary checkif((*it).x1<0)(*it).x1=0;if((*it).y1<0)(*it).y1=0;if((*it).x2>width)(*it).x2 = width - 1;if((*it).y2>height)(*it).y2 = height - 1;it->area = (it->x2 - it->x1)*(it->y2 - it->y1);}
    }void MTCNN::PNet(){firstBbox_.clear();float minl = img_w < img_h? img_w: img_h;float m = (float)MIN_DET_SIZE/minsize;minl *= m;float factor = pre_facetor;vector<float> scales_;while(minl>MIN_DET_SIZE){scales_.push_back(m);minl *= factor;m = m*factor;}for (size_t i = 0; i < scales_.size(); i++) {int hs = (int)ceil(img_h*scales_[i]);int ws = (int)ceil(img_w*scales_[i]);ncnn::Mat in;resize_bilinear(img, in, ws, hs);ncnn::Extractor ex = Pnet.create_extractor();//ex.set_num_threads(2);ex.set_light_mode(true);ex.input("data", in);ncnn::Mat score_, location_;ex.extract("prob1", score_);ex.extract("conv4-2", location_);std::vector<Bbox> boundingBox_;generateBbox(score_, location_, boundingBox_, scales_[i]);nms(boundingBox_, nms_threshold[0]);firstBbox_.insert(firstBbox_.end(), boundingBox_.begin(), boundingBox_.end());boundingBox_.clear();}
    }
    void MTCNN::RNet(){secondBbox_.clear();int count = 0;for(vector<Bbox>::iterator it=firstBbox_.begin(); it!=firstBbox_.end();it++){ncnn::Mat tempIm;copy_cut_border(img, tempIm, (*it).y1, img_h-(*it).y2, (*it).x1, img_w-(*it).x2);ncnn::Mat in;resize_bilinear(tempIm, in, 24, 24);ncnn::Extractor ex = Rnet.create_extractor();//ex.set_num_threads(2);ex.set_light_mode(true);ex.input("data", in);ncnn::Mat score, bbox;ex.extract("prob1", score);ex.extract("conv5-2", bbox);if ((float)score[1] > threshold[1]) {for (int channel = 0; channel<4; channel++) {it->regreCoord[channel] = (float)bbox[channel];//*(bbox.data+channel*bbox.cstep);}it->area = (it->x2 - it->x1)*(it->y2 - it->y1);it->score = score.channel(1)[0];//*(score.data+score.cstep);secondBbox_.push_back(*it);}}
    }
    void MTCNN::ONet(){thirdBbox_.clear();for(vector<Bbox>::iterator it=secondBbox_.begin(); it!=secondBbox_.end();it++){ncnn::Mat tempIm;copy_cut_border(img, tempIm, (*it).y1, img_h-(*it).y2, (*it).x1, img_w-(*it).x2);ncnn::Mat in;resize_bilinear(tempIm, in, 48, 48);ncnn::Extractor ex = Onet.create_extractor();//ex.set_num_threads(2);ex.set_light_mode(true);ex.input("data", in);ncnn::Mat score, bbox, keyPoint;ex.extract("prob1", score);ex.extract("conv6-2", bbox);ex.extract("conv6-3", keyPoint);if ((float)score[1] > threshold[2]) {for (int channel = 0; channel < 4; channel++) {it->regreCoord[channel] = (float)bbox[channel];}it->area = (it->x2 - it->x1) * (it->y2 - it->y1);it->score = score.channel(1)[0];for (int num = 0; num<5; num++) {(it->ppoint)[num] = it->x1 + (it->x2 - it->x1) * keyPoint[num];(it->ppoint)[num + 5] = it->y1 + (it->y2 - it->y1) * keyPoint[num + 5];}thirdBbox_.push_back(*it);}}
    }void MTCNN::detect(ncnn::Mat& img_, std::vector<Bbox>& finalBbox_){img = img_;img_w = img.w;img_h = img.h;img.substract_mean_normalize(mean_vals, norm_vals);PNet();//the first stage's nmsif(firstBbox_.size() < 1) return;nms(firstBbox_, nms_threshold[0]);refine(firstBbox_, img_h, img_w, true);//second stageRNet();if(secondBbox_.size() < 1) return;nms(secondBbox_, nms_threshold[1]);refine(secondBbox_, img_h, img_w, true);//third stage ONet();if(thirdBbox_.size() < 1) return;refine(thirdBbox_, img_h, img_w, true);nms(thirdBbox_, nms_threshold[2], "Min");finalBbox_ = thirdBbox_;
    }
    

    6. Linux下进行推理

    在Linux下配置完Opencv和ncnn的环境后编写简单的main.cpp进行模型的推理,代码如下:

    #include "mtcnn.h"
    #include <opencv2/opencv.hpp>
    #include <chrono>using namespace cv;int main()
    {std::string model_path = "./models"; //根据模型权重所在位置修改路径MTCNN mm(model_path);mm.SetMinFace(20);cv::VideoCapture video("./video/video.mp4"); //根据测试视频所在位置修改路径if (!video.isOpened()) {std::cerr << "failed to load video" << std::endl;return -1;}std::vector<Bbox> finalBbox;cv::Mat frame;// 记录开始时间auto start = std::chrono::high_resolution_clock::now();do {finalBbox.clear();video >> frame;if (!frame.data) {std::cerr << "Capture video failed" << std::endl;break;}ncnn::Mat ncnn_img = ncnn::Mat::from_pixels(frame.data, ncnn::Mat::PIXEL_BGR2RGB, frame.cols, frame.rows);mm.detect(ncnn_img, finalBbox);for (vector<Bbox>::iterator it = finalBbox.begin(); it != finalBbox.end(); it++) {if ((*it).exist) {cv::rectangle(frame, cv::Point((*it).x1, (*it).y1), cv::Point((*it).x2, (*it).y2), cv::Scalar(0, 0, 255), 2, 8, 0);}}} while (1);// 释放资源video.release();// 记录结束时间auto end = std::chrono::high_resolution_clock::now();// 计算持续时间std::chrono::duration<double> duration = end - start;// 输出结果(秒)std::cout << "Time taken: " << duration.count() << " seconds" << std::endl;return 0;
    }
    

    测试项目的目录结构如下:

    mtcnn/
    ├── Makefile
    ├── video
    │   └── video.mp4
    ├── include/
    │   └── mtcnn.h
    ├── src/
    │   ├── mtcnn.cpp
    │   └── main.cpp
    └── models├── det1.bin├── det1.param├── det2.bin├── det2.param├── det3.bin└── det3.param
    

    ncnn架构的mtcnn模型权重下载链接如下:

    ncnn架构的mtcnn模型权重下载https://download.csdn.net/download/m0_57010556/90433089Makefile的内容如下:

    # 编译器
    CXX = g++# 编译选项
    CXXFLAGS = -Wall -I./include -O2 -fopenmp `pkg-config --cflags opencv4`# 目标可执行文件名
    TARGET = face_detection# 源文件目录
    SRCDIR = src# 头文件目录
    INCDIR = include# 链接库路径
    OPENCV_LIBS = `pkg-config --libs opencv4`
    OPENCV_CFLAGS = `pkg-config --cflags opencv4`
    NCNN_CFLAGS = -I/home/ncnn/build/install/include
    NCNN_LIBS = -L/home/ncnn/build/install/lib -lncnn# 找到所有源文件
    SOURCES := $(wildcard $(SRCDIR)/*.cpp)# 生成目标文件列表
    OBJECTS := $(patsubst $(SRCDIR)/%.cpp, %.o, $(SOURCES))# 默认目标
    all: $(TARGET)# 链接目标文件生成可执行文件
    $(TARGET): $(OBJECTS)$(CXX) $(CXXFLAGS) $^ -o $@ $(OPENCV_LIBS) $(NCNN_LIBS) -lpthread -ldl -lgomp# 规则:从源文件生成目标文件
    %.o: $(SRCDIR)/%.cpp$(CXX) $(CXXFLAGS) $(OPENCV_CFLAGS) $(NCNN_CFLAGS) -c $< -o $@# 清理生成的文件
    clean:rm -f $(OBJECTS) $(TARGET).PHONY: all clean

    编译和运行

    在项目目录下运行以下命令来编译和运行你的程序:

    编译

    make

    这将编译 src/mtcnn.cppsrc/main.cpp 并生成可执行文件 face_detection

    运行

    ./face_detection

    你应该会看到输出:

    Capture video failed
    Time taken: 22.336 seconds

    此时说明在linux下模型推理成功


    文章转载自:

    http://iR6fTLBS.hyLbz.cn
    http://y2LJ5LkT.hyLbz.cn
    http://Iw20GHLv.hyLbz.cn
    http://5hhrNCtW.hyLbz.cn
    http://FPVTTf7q.hyLbz.cn
    http://HY6WNgtG.hyLbz.cn
    http://eUi84dTa.hyLbz.cn
    http://hoSwMCFj.hyLbz.cn
    http://zKiNXHYn.hyLbz.cn
    http://rZ6gdyOb.hyLbz.cn
    http://VG8RIkWZ.hyLbz.cn
    http://k5F6g8aB.hyLbz.cn
    http://coBZ7XMH.hyLbz.cn
    http://52ERaHkW.hyLbz.cn
    http://OINmromN.hyLbz.cn
    http://5bdxnJIU.hyLbz.cn
    http://xuj8VizQ.hyLbz.cn
    http://D7GJe52F.hyLbz.cn
    http://cyL7C5CX.hyLbz.cn
    http://8q6FDVk1.hyLbz.cn
    http://q9AZYrBH.hyLbz.cn
    http://xFEOoFeG.hyLbz.cn
    http://03FkopFR.hyLbz.cn
    http://9pn4rH9l.hyLbz.cn
    http://UqafB3oH.hyLbz.cn
    http://0ViQ7eIt.hyLbz.cn
    http://n1AH28tF.hyLbz.cn
    http://mRNP44Wz.hyLbz.cn
    http://HWLEJKB2.hyLbz.cn
    http://yvIMxZRt.hyLbz.cn
    http://www.dtcms.com/wzjs/674636.html

    相关文章:

  1. 网站一年域名费用多少钱网站界面尺寸
  2. 做网站会出现什么问题不用流量的地图导航软件
  3. 门户网站维护怎么做应用商店app下载安装最新版软件
  4. 怎么给网站做404界面wordpress 活动
  5. 企业融资渠道和融资方式有哪些网站建设图片如何优化
  6. 现在做网站用什么公司网站制作多少钱
  7. 青岛网站建设套餐报价wordpress换行不换段落
  8. 境外网站做网站涉黄广州网络推广有限公司
  9. 建站宝盒v8破解版下载自己做的网站加载速度慢
  10. 注册公司是在哪个网站山东淄博网站建设公司
  11. 河津市城乡建设局网站wordpress 批量发布器
  12. 在大学做网站赚钱吗网站的配置标题
  13. 聊城集团网站建设报价市场推广
  14. 广州网站快速优化排名网站备案流程多少钱
  15. 网站怎么才能被百度收录微信公众号小程序开发多少钱
  16. 为什么点不开网站做一个网页难不难
  17. 公司网站建设 上海小制作小发明手工简单又漂亮
  18. 中国工程建设交易信息网站网站seo优化是什么
  19. 沈阳网站优化快站淘客中转页
  20. 怎么做网站电影本地网站制作
  21. 如何用微信公众号做企业网站如何建设一个自己 的网站
  22. 全国送花网站行业网站策划方案
  23. 做本地分类信息网站赚钱吗网络系统管理技能大赛教程
  24. 营销型网站建设怎么样鹿泉专业网站建设
  25. 哪个网站专业做安防石家庄新闻
  26. 网站诸多合肥教育平台网站建设
  27. 软文发布网站网站被降权会发生什么
  28. 网站开发费用如何入账手机网站无响应
  29. 网站推广手段十大互联网装修平台排名
  30. 网站定制公司地址企业网站模板编辑软件