OpenCV调用TensorFlow预训练模型
OpenCV調(diào)用TensorFlow預(yù)訓(xùn)練模型
? 【尊重原創(chuàng),轉(zhuǎn)載請注明出處】https://panjinquan.blog.csdn.net/article/details/80570120
? ? ? 強(qiáng)大OpenCV從自O(shè)penCV 3.1版以來,dnn模塊一直是opencv_contrib庫的一部分,在3.3版中,它被提到了主倉庫中。新版OpenCV dnn模塊目前支持Caffe、TensorFlow、Torch、PyTorch等深度學(xué)習(xí)框架。另外,新版本中使用預(yù)訓(xùn)練深度學(xué)習(xí)模型的API同時(shí)兼容C++和Python
? ? OpenCV?3.3開始就提供了讀取TensoFlow模型的接口了,不過現(xiàn)在能支持的模型并不多。目前,我測試成功只有兩個(gè),分別是object_detection的“ssd_mobilenet_v1_coco_11_06_2017”和“ssd_inception_v2_coco_2017_11_17”預(yù)訓(xùn)練模型,其他模型報(bào)出各種各樣的錯(cuò)誤,反正我暫時(shí)還沒有解決問題,各位神一樣的網(wǎng)友若有新的進(jìn)展,麻煩告知一聲,哈哈~!
一、版本配置要求
- 1. Windows 7 和 VS2015
- 2. OpenCV3.3.1以上,本人使用的OpenCV 3.4.1,下載地址:https://github.com/opencv/opencv/releases?
- 3.至于TensoFlow,鄙人只是想測試已經(jīng)訓(xùn)練好的模型,那就可以不安裝TensoFlow了,偷懶一下~!
二、模型下載和配置
1. ? 先用VS2015新建一個(gè)項(xiàng)目“opercv4tensorflow”,并在源文件目錄下新建 一個(gè)“models”的文件夾,這個(gè)文件夾用于下載TensoFlow的模型。
2. ? 目前,只測試TensoFlow的object_detection模塊的“ssd_mobilenet_v1_coco_11_06_2017”和“ssd_inception_v2_coco_2017_11_17”兩個(gè)預(yù)訓(xùn)練模型,其他的自己看著辦吧:
?
- ssd_mobilenet_v1_coco_11_06_2017下載地址:
? ??http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_11_06_2017.tar.gz
- ssd_inception_v2_coco_2017_11_17下載地址:
? ??http://download.tensorflow.org/models/object_detection/ssd_inception_v2_coco_2017_11_17.tar.gz
- COCO-trained models
? ? 當(dāng)然了,你可以自己訓(xùn)練模型,也可以下載更多的預(yù)訓(xùn)練模型,這個(gè)可以到TensoFlow下載,下載地址是:
? ??https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md
? ? Tensorflow模型的graph結(jié)構(gòu)可以保存為.pb文件或者.pbtxt文件,或者.meta文件,其中只有.pbtxt文件是可讀的。在OpenCV中,每個(gè)模型.pb文件,原則上應(yīng)有一個(gè)對應(yīng)的文本圖形定義的.pbtxt文件,當(dāng)然也可能沒有,在opencv_extra\testdata\dnn有些.pbtxt文件是可以對應(yīng)找到,這個(gè)要看opencv會不會提供,當(dāng)然,你厲害的話,可以自己按照網(wǎng)絡(luò)定義結(jié)構(gòu)寫一份。
? ? 下表給出,目前我在object_detection模塊中測試成功.pb文件與.pbtxt文件的對應(yīng)關(guān)系,更多的模型,還請網(wǎng)友下方留言,支援一下,我會及時(shí)更新博客內(nèi)容:
| 序號 | .pb文件:預(yù)訓(xùn)練模型 | .pbtxt文件 | 備注 |
| 1 | ssd_mobilenet_v1_coco_11_06_2017 | ssd_mobilenet_v1_coco.pbtxt | ? |
| 2 | ssd_inception_v2_coco_2017_11_17 | ssd_inception_v2_coco_2017_11_17.pbtxt | ? |
| 3 | ? | ? | ? |
| 4 | ? | ? | ? |
| ? | ? | ? | ? |
3. 上面下載的TensoFlow模型解壓后,里含有重要的二進(jìn)制protobuf描述的.pb文件,我們還需要對應(yīng)的protobuf格式文本圖形定義的.pbtxt文件,這個(gè)就需要到opencv_extra\testdata\dnn下載了
? ?opencv_extra下載地址:https://github.com/opencv/opencv_extra/tree/master/testdata/dnn
? ?把dnn文件夾中的“ssd_inception_v2_coco_2017_11_17.pbtxt”和“ssd_mobilenet_v1_coco.pbtxt”也下載復(fù)制到項(xiàng)目的models中吧
三、使用opencv讀取網(wǎng)絡(luò)模型
? ? 一切準(zhǔn)備妥當(dāng)了,下面就使用opencv C++(也可以是python的)實(shí)現(xiàn)讀取TensoFlow訓(xùn)練好的網(wǎng)絡(luò)模型。opencv dnn為我們提供TensoFlow的接口:readNetFromTensorflow,當(dāng)然也有支持Caffe的接口:readNetFromCaffe。我們這里只考慮TensoFlow的模型,readNetFromTensorflow函數(shù)有多個(gè)重載函數(shù):
/** @brief Reads a network model stored in <a href="https://www.tensorflow.org/">TensorFlow</a> framework's format.* @param model path to the .pb file with binary protobuf description of the network architecture* @param config path to the .pbtxt file that contains text graph definition in protobuf format.* Resulting Net object is built by text graph using weights from a binary one that* let us make it more flexible.* @returns Net object.*/CV_EXPORTS_W Net readNetFromTensorflow(const String &model, const String &config = String());? ? 完整的測試代碼:
#include<opencv2\opencv.hpp> #include<opencv2\dnn.hpp> #include <iostream>using namespace std; using namespace cv;const size_t inWidth = 300; const size_t inHeight = 300; const float WHRatio = inWidth / (float)inHeight; const char* classNames[] = { "background","face" };//這個(gè)需要根據(jù)訓(xùn)練的類別定義int main() {Mat frame = cv::imread("2.jpg");Size frame_size = frame.size();String weights = "models\\ssd_inception_v2_coco_2017_11_17\\frozen_inference_graph.pb";String prototxt = "models\\ssd_inception_v2_coco_2017_11_17.pbtxt";dnn::Net net = cv::dnn::readNetFromTensorflow(weights, prototxt);Size cropSize;if (frame_size.width / (float)frame_size.height > WHRatio){cropSize = Size(static_cast<int>(frame_size.height * WHRatio),frame_size.height);}else{cropSize = Size(frame_size.width,static_cast<int>(frame_size.width / WHRatio));}Rect crop(Point((frame_size.width - cropSize.width) / 2,(frame_size.height - cropSize.height) / 2),cropSize);cv::Mat blob = cv::dnn::blobFromImage(frame, 1. / 255, Size(300, 300));//cout << "blob size: " << blob.size << endl;net.setInput(blob);Mat output = net.forward();//cout << "output size: " << output.size << endl;Mat detectionMat(output.size[2], output.size[3], CV_32F, output.ptr<float>());frame = frame(crop);float confidenceThreshold = 0.20;for (int i = 0; i < detectionMat.rows; i++){float confidence = detectionMat.at<float>(i, 2);if (confidence > confidenceThreshold){size_t objectClass = (size_t)(detectionMat.at<float>(i, 1));int xLeftBottom = static_cast<int>(detectionMat.at<float>(i, 3) * frame.cols);int yLeftBottom = static_cast<int>(detectionMat.at<float>(i, 4) * frame.rows);int xRightTop = static_cast<int>(detectionMat.at<float>(i, 5) * frame.cols);int yRightTop = static_cast<int>(detectionMat.at<float>(i, 6) * frame.rows);ostringstream ss;ss << confidence;String conf(ss.str());Rect object((int)xLeftBottom, (int)yLeftBottom,(int)(xRightTop - xLeftBottom),(int)(yRightTop - yLeftBottom));rectangle(frame, object, Scalar(0, 255, 0), 2);String label = String(classNames[objectClass]) + ": " + conf;int baseLine = 0;Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);rectangle(frame, Rect(Point(xLeftBottom, yLeftBottom - labelSize.height),Size(labelSize.width, labelSize.height + baseLine)),Scalar(0, 255, 0), CV_FILLED);putText(frame, label, Point(xLeftBottom, yLeftBottom),FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0));}}imshow("image", frame);waitKey(0);return 0; }運(yùn)行結(jié)果:
四、常見的錯(cuò)誤和坑
?
?
- OpenCV(3.4.1) Error: Unspecified error (FAILED: fs.is_open(). Can't open "models\ssd_inception_v2_coco_2017_1117\frozen_inference_graph.pb") in cv::dnn::ReadProtoFromBinaryFile, file C:\build\master_winpack-build-win64-vc14\opencv\modules\dnn\src\caffe\caffe_io.cpp, line 1126
? ? ? 出現(xiàn)這個(gè)問題,很大的原因是你的模型路徑,錯(cuò)鳥!!導(dǎo)致不能打開
- OpenCV(3.4.1) Error: Unspecified error (Const input blob for weights not found) in cv::dnn::experimental_dnn_v4::`anonymous-namespace'::TFImporter::getConstBlob, file C:\build\master_winpack-build-win64-vc14\opencv\modules\dnn\src\tensorflow\tf_importer.cpp, line 579
? ? ?出現(xiàn)這個(gè)問題,可能是你的.pb模型文件與.pbtxt文件不對應(yīng)
五、參考資料:
https://blog.csdn.net/xingchenbingbuyu/article/details/78416887
總結(jié)
以上是生活随笔為你收集整理的OpenCV调用TensorFlow预训练模型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解决:object_detection/
- 下一篇: 解决Ubuntu17.04不能安装git