雷霆万钧 杜兰特

OpenCV中文網站

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
熱搜: 安裝 配置
查看: 4743|回復: 15
打印 上一主題 下一主題

車輛檢測、車型識別、年檢標檢測等

[復制鏈接]
跳轉到指定樓層
#
發表于 2019-4-16 10:32:04 | 只看該作者 |只看大圖 回帖獎勵 |正序瀏覽 |閱讀模式
上傳車輛等相關檢測,如有需要,相互合作

圖片1.jpg (53.64 KB, 下載次數: 172)

車輛檢測

車輛檢測

圖片3.jpg (140.01 KB, 下載次數: 178)

車系識別、車牌識別

車系識別、車牌識別

圖片5.jpg (75.53 KB, 下載次數: 158)

年檢標等檢測

年檢標等檢測

圖片6.jpg (83.06 KB, 下載次數: 158)

年檢標等檢測

年檢標等檢測

圖片4.jpg (103.26 KB, 下載次數: 167)

車系識別、車牌識別

車系識別、車牌識別

圖片8.jpg (147.07 KB, 下載次數: 155)

機動車分類:轎車、貨車、客車、面包;非機動車分類:自行車、摩托車、三輪車、行人 ...

機動車分類:轎車、貨車、客車、面包;非機動車分類:自行車、摩托車、三輪車、行人 ...

圖片7.jpg (81.78 KB, 下載次數: 154)

年檢標等檢測

年檢標等檢測
分享到:  QQ好友和群QQ好友和群
收藏收藏
回復

使用道具 舉報

14#
發表于 2019-10-31 20:35:17 | 只看該作者
本帖最后由 jsxyheu2014 于 2019-10-31 20:36 編輯

基于OpenVINO
#include <algorithm>
#include <fstream>
#include <iomanip>
#include <vector>
#include <string>
#include <chrono>
#include <memory>
#include <utility>

#include <format_reader_ptr.h>
#include <inference_engine.hpp>
#include <ext_list.hpp>

#include <samples/slog.hpp>
#include <samples/ocv_common.hpp>
#include "segmentation_demo.h"

using namespace InferenceEngine;
using namespace std;
using namespace cv;

//從圖片中獲得車和車牌(這里沒有輸出模型的定位結果,如果需要可以適當修改)
vector< pair<Mat, Mat> > GetCarAndPlate(Mat src)
{
    vector<pair<Mat, Mat>> resultVector;
    // 模型準備
    InferencePlugin plugin(PluginDispatcher().getSuitablePlugin(TargetDevice::eCPU));
    plugin.AddExtension(std::make_shared<Extensions::Cpu::CpuExtensions>());//Extension,useful
    //讀取模型(xml和bin
    CNNNetReader networkReader;
    networkReader.ReadNetwork("E:/OpenVINO_modelZoo/vehicle-license-plate-detection-barrier-0106.xml");
    networkReader.ReadWeights("E:/OpenVINO_modelZoo/vehicle-license-plate-detection-barrier-0106.bin");
    CNNNetwork network = networkReader.getNetwork();
    network.setBatchSize(1);
    // 輸入輸出準備
    InputsDataMap inputInfo(network.getInputsInfo());//獲得輸入信息
    if (inputInfo.size() != 1) throw std::logic_error("錯誤,該模型應該為單輸入");
    string inputName = inputInfo.begin()->first;

    OutputsDataMap outputInfo(network.getOutputsInfo());//獲得輸出信息                                      
    DataPtr& _output = outputInfo.begin()->second;
    const SizeVector outputDims = _output->getTensorDesc().getDims();
    string firstOutputName = outputInfo.begin()->first;
    int maxProposalCount = outputDims[2];
    int objectSize = outputDims[3];
    if (objectSize != 7) {
        throw std::logic_error("Output should have 7 as a last dimension");
    }
    if (outputDims.size() != 4) {
        throw std::logic_error("Incorrect output dimensions for SSD");
    }
    _output->setPrecision(Precision::FP32);
    _output->setLayout(Layout::NCHW);

    // 模型讀取和推斷
    ExecutableNetwork executableNetwork = plugin.LoadNetwork(network, {});
    InferRequest infer_request = executableNetwork.CreateInferRequest();

    Blob::Ptr lrInputBlob = infer_request.GetBlob(inputName); //data這個名字是我看出來的,實際上這里可以更統一一些
    matU8ToBlob<float_t>(src, lrInputBlob, 0);//重要的轉換函數,第3個參數是batchSize,應該是自己+1的

    infer_request.Infer();
    // --------------------------- 8. 處理結果-------------------------------------------------------
    const float *detections = infer_request.GetBlob(firstOutputName)->buffer().as<float *>();
    int i_car = 0;
    int i_plate = 0;
    for (int i = 0; i < 200; i++)
    {
        float confidence = detections[i * objectSize + 2];
        float x_min = static_cast<int>(detections[i * objectSize + 3] * src.cols);
        float y_min = static_cast<int>(detections[i * objectSize + 4] * src.rows);
        float x_max = static_cast<int>(detections[i * objectSize + 5] * src.cols);
        float y_max = static_cast<int>(detections[i * objectSize + 6] * src.rows);
        Rect rect = cv::Rect(cv::Point(x_min, y_min), cv::Point(x_max, y_max));
        if (confidence > 0.5)
        {
            if (rect.width > 150)//車輛
            {
                Mat roi = src(rect);
                pair<Mat, Mat> aPair;
                aPair.first = roi.clone();
                resultVector.push_back(aPair);
                i_car++;
            }
            else//車牌
            {
                Mat roi = src(rect);
                resultVector[i_plate].second = roi.clone();
                i_plate++;
            }

        }
    }
    return resultVector;
}
//從車的圖片中識別車型
pair<string,string> GetCarAttributes(Mat src)
{
    pair<string, string> resultPair;
    // --------------------------- 1.為IE準備插件-------------------------------------
    InferencePlugin plugin(PluginDispatcher().getSuitablePlugin(TargetDevice::eCPU));
    printPluginVersion(plugin, std::cout);//正確回顯表示成功
    plugin.AddExtension(std::make_shared<Extensions::Cpu::CpuExtensions>());//Extension,useful
    // --------------------------- 2.讀取IR模型(xml和bin)---------------------------------
    CNNNetReader networkReader;
    networkReader.ReadNetwork("E:/OpenVINO_modelZoo/vehicle-attributes-recognition-barrier-0039.xml");
    networkReader.ReadWeights("E:/OpenVINO_modelZoo/vehicle-attributes-recognition-barrier-0039.bin");
    CNNNetwork network = networkReader.getNetwork();
    // --------------------------- 3. 準備輸入輸出的------------------------------------------
    InputsDataMap inputInfo(network.getInputsInfo());//獲得輸入信息
    BlobMap inputBlobs; //保持所有輸入的blob數據
    if (inputInfo.size() != 1) throw std::logic_error("錯誤,該模型應該為單輸入");

    auto lrInputInfoItem = *inputInfo.begin();//開始讀入
    int w = static_cast<int>(lrInputInfoItem.second->getTensorDesc().getDims()[3]); //這種寫法也是可以的,它的first就是data
    int h = static_cast<int>(lrInputInfoItem.second->getTensorDesc().getDims()[2]);   
    network.setBatchSize(1);//只有1副圖片,故BatchSize = 1
    // --------------------------- 4. 讀取模型 ------------------------------------------(后面這些操作應該可以合并了)
    ExecutableNetwork executableNetwork = plugin.LoadNetwork(network, {});
    // --------------------------- 5. 創建推斷 -------------------------------------------------
    InferRequest infer_request = executableNetwork.CreateInferRequest();
    // --------------------------- 6. 將數據塞入模型 -------------------------------------------------
    Blob::Ptr lrInputBlob = infer_request.GetBlob("input"); //data這個名字是我看出來的,實際上這里可以更統一一些
    matU8ToBlob<float_t>(src, lrInputBlob, 0);//重要的轉換函數,第3個參數是batchSize,應該是自己+1的

    // --------------------------- 7. 推斷結果 -------------------------------------------------
    infer_request.Infer();//多張圖片多次推斷

    // --------------------------- 8. 處理結果-------------------------------------------------------
     // 7 possible colors for each vehicle and we should select the one with the maximum probability
    auto colorsValues = infer_request.GetBlob("color")->buffer().as<float*>();
    // 4 possible types for each vehicle and we should select the one with the maximum probability
    auto typesValues = infer_request.GetBlob("type")->buffer().as<float*>();

    const auto color_id = std::max_element(colorsValues, colorsValues + 7) - colorsValues;
    const auto type_id = std::max_element(typesValues, typesValues + 4) - typesValues;

    static const std::string colors[] = {
             "white", "gray", "yellow", "red", "green", "blue", "black"
    };
    static const std::string types[] = {
            "car", "bus", "truck", "van"
    };

    resultPair.first = colors[color_id];
    resultPair.second = types[type_id];

    return resultPair;

}
//識別車牌
string GetPlateNumber(Mat src)
{
    // --------------------------- 1.為IE準備插件-------------------------------------
    InferencePlugin plugin(PluginDispatcher().getSuitablePlugin(TargetDevice::eCPU));
    plugin.AddExtension(std::make_shared<Extensions::Cpu::CpuExtensions>());//Extension,useful
    // --------------------------- 2.讀取IR模型(xml和bin)---------------------------------
    CNNNetReader networkReader;
    networkReader.ReadNetwork("E:/OpenVINO_modelZoo/license-plate-recognition-barrier-0001.xml");
    networkReader.ReadWeights("E:/OpenVINO_modelZoo/license-plate-recognition-barrier-0001.bin");
    CNNNetwork network = networkReader.getNetwork();
    network.setBatchSize(1);//只有1副圖片,故BatchSize = 1
    // --------------------------- 3. 準備輸入輸出的------------------------------------------
    InputsDataMap inputInfo(network.getInputsInfo());//獲得輸入信息
    BlobMap inputBlobs; //保持所有輸入的blob數據
    string    inputSeqName;

    if (inputInfo.size() == 2) {
        auto sequenceInput = (++inputInfo.begin());
        inputSeqName = sequenceInput->first;
    }
    else if (inputInfo.size() == 1) {
        inputSeqName = "";
    }
    else {
        throw std::logic_error("LPR should have 1 or 2 inputs");
    }

    InputInfo::Ptr& inputInfoFirst = inputInfo.begin()->second;
    inputInfoFirst->setInputPrecision(Precision::U8);
    string inputName = inputInfo.begin()->first;

    //準備輸出數據
    OutputsDataMap outputInfo(network.getOutputsInfo());//獲得輸出信息            
    if (outputInfo.size() != 1) {
        throw std::logic_error("LPR should have 1 output");
    }
    string firstOutputName = outputInfo.begin()->first;

    DataPtr& _output = outputInfo.begin()->second;
    const SizeVector outputDims = _output->getTensorDesc().getDims();

    // --------------------------- 4. 讀取模型 ------------------------------------------(后面這些操作應該可以合并了)
    ExecutableNetwork executableNetwork = plugin.LoadNetwork(network, {});
    // --------------------------- 5. 創建推斷 -------------------------------------------------
    InferRequest infer_request = executableNetwork.CreateInferRequest();
    // --------------------------- 6. 將數據塞入模型 -------------------------------------------------
    Blob::Ptr lrInputBlob = infer_request.GetBlob(inputName); //data這個名字是我看出來的,實際上這里可以更統一一些
    matU8ToBlob<uint8_t>(src, lrInputBlob, 0);//重要的轉換函數,第3個參數是batchSize,應該是自己+1的

    // --------------------------- 7. 推斷結果 -------------------------------------------------
    infer_request.Infer();//多張圖片多次推斷
    // --------------------------- 8. 處理結果-------------------------------------------------------
    static std::vector<std::string> items = {
          "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
          "<Anhui>", "<Beijing>", "<Chongqing>", "<Fujian>",
          "<Gansu>", "<Guangdong>", "<Guangxi>", "<Guizhou>",
          "<Hainan>", "<Hebei>", "<Heilongjiang>", "<Henan>",
          "<HongKong>", "<Hubei>", "<Hunan>", "<InnerMongolia>",
          "<Jiangsu>", "<Jiangxi>", "<Jilin>", "<Liaoning>",
          "<Macau>", "<Ningxia>", "<Qinghai>", "<Shaanxi>",
          "<Shandong>", "<Shanghai>", "<Shanxi>", "<Sichuan>",
          "<Tianjin>", "<Tibet>", "<Xinjiang>", "<Yunnan>",
          "<Zhejiang>", "<police>",
          "A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
          "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
          "U", "V", "W", "X", "Y", "Z"
    };

    const auto data = infer_request.GetBlob(firstOutputName)->buffer().as<float*>();
    std::string result;
    for (size_t i = 0; i < 88; i++) {
        if (data == -1)
            break;
        result += items[static_cast<size_t>(data)];
    }
    return result;
}

void main()
{
    string imageNames = "E:/OpenVINO_modelZoo/滬A51V39.jpg";
    Mat src = imread(imageNames);
    if (src.empty())
        return;

    vector<pair<Mat, Mat>> CarAndPlateVector = GetCarAndPlate(src);
    for (int i=0;i<CarAndPlateVector.size();i++)
    {
        pair<Mat, Mat> aPair = CarAndPlateVector;
        pair<string, string> ColorAndType = GetCarAttributes(aPair.first);
        string PlateNumber = GetPlateNumber(aPair.second);
        cout << ColorAndType.first <<"  "<<ColorAndType.second <<"   "<< PlateNumber << endl;
    }

    cv::waitKey();

}
回復 支持 反對

使用道具 舉報

13#
發表于 2019-10-31 20:35:11 | 只看該作者
圖片
回復 支持 反對

使用道具 舉報

12#
發表于 2019-10-31 20:34:14 | 只看該作者
看看這個了《一、多車輛識別可能和車輛車牌分割;》
https://www.cnblogs.com/jsxyhelu/p/11392219.html
回復 支持 反對

使用道具 舉報

11#
 樓主| 發表于 2019-10-22 18:43:37 | 只看該作者
軌跡是有的,但是速度沒有進行開發
回復 支持 反對

使用道具 舉報

10#
發表于 2019-10-22 14:41:40 | 只看該作者
能不能在交叉口識別車輛,獲取軌跡和速度?
回復 支持 反對

使用道具 舉報

9#
 樓主| 發表于 2019-10-10 12:54:52 | 只看該作者
we0091234 發表于 2019-10-9 17:25
年檢標是通過檢測的方法搞出來的嗎?這么模糊都能檢測出來,有點牛

ssd
回復 支持 反對

使用道具 舉報

8#
發表于 2019-10-9 17:25:24 | 只看該作者
年檢標是通過檢測的方法搞出來的嗎?這么模糊都能檢測出來,有點牛
回復 支持 反對

使用道具 舉報

7#
 樓主| 發表于 2019-9-18 15:04:02 | 只看該作者
代碼 不能 共享 ,QQ 114772751  可以討論開發技術
回復 支持 反對

使用道具 舉報

6#
發表于 2019-9-18 10:33:27 | 只看該作者
大佬,同求代碼,我郵箱[email protected]
回復 支持 反對

使用道具 舉報

5#
發表于 2019-9-17 15:27:48 | 只看該作者
大佬,同求代碼,我郵箱[email protected]
回復 支持 反對

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|OpenCV中文網站  

GMT+8, 2019-12-9 08:58 , Processed in 0.058821 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回復 返回頂部 返回列表
雷霆万钧 杜兰特 5251789660610640842177694714159514383344168295524717219468748644181471941118967481904131370504993 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();