在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

OpenCV編程:OpenCV3.X訓練自己的分類器

DS小龍哥-嵌入式技術 ? 來源:DS小龍哥-嵌入式技術 ? 作者:DS小龍哥-嵌入式技 ? 2022-08-14 09:31 ? 次閱讀

一、環境介紹

操作系統: windows10 64位

QT版本: 5.12.6 (我的程序里主要是QT+OpenCV實現圖像處理顯示的)

OpenCV版本: OpenCV3.4.7

二、下載安裝OpenCV

windows下不用下載源碼,可以直接在官網下載編譯好的文件解壓即可使用。

OpenCV官網下載地址: https://opencv.org/releases/ 下載之后解壓到指定目錄即可,我這里是直接解壓到C盤的。

img

因為在官網下載的版本是VC版本,而我的QT使用的是MinGW編譯器,上面下在官網下載的安裝包里的庫用不了,需要再下載一個MinGW版本。 下載地址:https://github.com/huihut/OpenCV-MinGW-Build

img

為什么需要下載兩個版本? 其實主要是MinGW版本的OpenCV里帶的兩個訓練分類器(opencv_traincascade.exe)的文件在我電腦上無法使用,可能庫沖突,具體問題沒有深究,就干脆再下載了一個VC版本是OpenCV,VC版本里opencv_traincascade.exe文件是可以正常使用。 其實下載的VC版本OpenCV主要是為了用這兩個文件(opencv_traincascade.exe、opencv_createsamples.exe)

img

三、測試OpenCV自帶的分類器

3.1 自帶的分類器文件介紹

OpenCV的官方已經提供了很多訓練好的分類器文件,在OpenCV的安裝目錄下有。

img

上面文件中提供了常見的 人臉檢測、眼睛檢測、貓臉檢測、行人檢測等,看XML文件的命名即可得知。

下面編寫QT程序,調用OpenCV的級聯分類器進行測試。

3.2 QT的示例代碼

下面的QT界面很簡單,主要是為了測試分類器文件。

xxx.cpp文件代碼:

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    dir="C:/";

    ui->label_source->setAlignment(Qt::AlignVCenter);
    ui->label_2->setAlignment(Qt::AlignVCenter);
}

Widget::~Widget()
{
    delete ui;
}
QImage Widget::Mat2QImage(const Mat& mat)
{
    // 8-bits unsigned, NO. OF CHANNELS = 1
    if(mat.type() == CV_8UC1)
    {
        QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
        // Set the color table (used to translate colour indexes to qRgb values)
        image.setColorCount(256);
        for(int i = 0; i < 256; i++)
        {
            image.setColor(i, qRgb(i, i, i));
        }
        // Copy input Mat
        uchar *pSrc = mat.data;
        for(int row = 0; row < mat.rows; row ++)
        {
            uchar *pDest = image.scanLine(row);
            memcpy(pDest, pSrc, mat.cols);
            pSrc += mat.step;
        }
        return image;
    }
    // 8-bits unsigned, NO. OF CHANNELS = 3
    else if(mat.type() == CV_8UC3)
    {
        // Copy input Mat
        const uchar *pSrc = (const uchar*)mat.data;
        // Create QImage with same dimensions as input Mat
        QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
        return image.rgbSwapped();
    }
    else if(mat.type() == CV_8UC4)
    {
        // Copy input Mat
        const uchar *pSrc = (const uchar*)mat.data;
        // Create QImage with same dimensions as input Mat
        QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
        return image.copy();
    }
    else
    {
        return QImage();
    }
}

//打開本地圖片
void Widget::on_pushButton_open_clicked()
{
    filename=QFileDialog::getOpenFileName(this,"選擇打開的文件",dir,tr("*.bmp *.jpg *.png"));
    if(filename.isEmpty())return;
    QFileInfo info(filename);
    dir=info.path(); //保存當前路徑
}

//人臉檢測代碼
void Widget::opencv_face(QImage qImage)
{
    QTime time;
    time.start();

    //定義級聯分類器
    CascadeClassifier face_cascade;
    //加載分類文件
    //
    if( !face_cascade.load("C:/OpenCV_3.4.7/OpenCV-MinGW-Build-OpenCV-3.4.7/etc/haarcascades/haarcascade_frontalcatface.xml") )
    {
        qDebug()<<"haarcascade_frontalface_alt.xml 分類器加載錯誤";
        return;
    }
    Mat frame=QImage2cvMat(qImage);
    cvtColor( frame, frame, COLOR_BGR2GRAY );//轉換成灰度圖像

    std::vector faces;
    //正臉檢測
    face_cascade.detectMultiScale(frame,faces);
    qDebug()<("耗時:%1>

xxx.h文件代碼:

#ifndef WIDGET_H
#define WIDGET_H

#include 
#include "opencv2/core/core.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"

#include 
#include 
#include 

using namespace cv;

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    QImage Mat2QImage(const Mat& mat);
    void opencv_face(QImage qImage);
    Mat QImage2cvMat(QImage image);
    QString dir;
    QString filename;
private slots:
    void on_pushButton_open_clicked();

    void on_pushButton_start_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

xxx.pro文件

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    widget.cpp

HEADERS += \
    widget.h

FORMS += \
    widget.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

#linu平臺的路徑設置
linux {
message('運行linu版本')
#添加opencv頭文件的路徑,需要根據自己的頭文件路徑進行修改
INCLUDEPATH+=/home/wbyq/work_pc/opencv-3.4.9/_install/install/include\
             /home/wbyq/work_pc/opencv-3.4.9/_install/install/include/opencv\
             /home/wbyq/work_pc/opencv-3.4.9/_install/install/include/opencv2

LIBS+=/home/wbyq/work_pc/opencv-3.4.9/_install/install/lib/libopencv_*
}

win32
{
    message('運行win32版本')
    #添加opencv頭文件的路徑,需要根據自己的頭文件路徑進行修改
    INCLUDEPATH+=C:/OpenCV_3.4.7/OpenCV-MinGW-Build-OpenCV-3.4.7/include \
                 C:/OpenCV_3.4.7/OpenCV-MinGW-Build-OpenCV-3.4.7/include/opencv \
                 C:/OpenCV_3.4.7/OpenCV-MinGW-Build-OpenCV-3.4.7/include/opencv2
    LIBS+=C:/OpenCV_3.4.7/OpenCV-MinGW-Build-OpenCV-3.4.7/x86/mingw/bin/libopencv_*.dll
}

xxx.ui文件:

img

3.3 測試人臉分類器效果

把代碼中的分類器文件換成:haarcascade_frontalface_alt2.xml

imgimgimg

這份QT代碼只是為了簡單的測試,就沒有開線程去識別,如果識別耗時比較久的話,識別過程中UI界面會卡住,等一會即可。

3.4 測試貓臉分類器效果

把代碼中的分類器文件換成:haarcascade_frontalcatface.xml

img

3.5 測試行人檢測分類器效果

把代碼中的分類器文件換成:haarcascade_fullbody.xml

img

四、訓練自己的分類器

4.1 前言

如果自己實際要檢測的物體在OpenCV自帶的分類器里沒有,或者OpenCV自帶的分類器識別精度不滿足要求,就可以使用OpenCV自帶的分類器程序自己訓練。訓練的方法網上的教程非常多,下面就重復造輪子簡單的敘述一下訓練過程。

說明: 因為下面的內容主要是簡單的敘述一下訓練過程,所以我準備的樣本數量都較少,如果實際訓練需要看下面說明增加樣本數量。

4.1 準備訓練的正負樣本素材說明

想要讓計算器識別指定的物體,那么首先得讓計算器知道你要識別的物體長什么樣,需要提前學習一番。學習過程中,需要準備一份正樣本和一份負樣本。 正樣本就是要識別的物體;負樣就是用來與正樣本比較的,負樣本里不包含正樣本里圖片或者相似的圖片,但是也不能亂選,最好與正樣本的取景在一個環境下,這樣效果最好,減少誤識別。

樣本圖片最好使用灰度圖(也就是黑白圖);樣本數量越多越好,盡量高于1000,樣本間差異性越大越好,正負樣本比例可以為1:3,訓練樣本官方推薦最佳尺寸為20x20,樣本圖片的命名不要出現特殊字符,使用正常點的名字即可。

正樣本的所有的圖片尺寸必須一致,如果不一致的或者尺寸較大的,可以先將所有樣本統一縮放到20*20。

尺寸大小決定的是訓練的時間長短,大尺寸也可以訓練,如果圖片太小也會損失很多細節,尺寸可以根據實際情況權衡,但是太大的圖片樣本訓練可能會導致內存不夠用的情況,具體情況可以根據訓練效果和情況進行調整。

注意,為了提高訓練準確率,負樣本不能亂選。

比如: 檢測的正樣本是車輪,那么負樣本就最好是車身,馬路、護欄、等等環境。

4.2 正樣本圖片示例

下面是識別汽車的正樣本圖片,正樣本圖片可以創建一個PositiveSample文件夾存放。

img

4.3 負樣本圖片示例

負樣本圖片可以創建一個NegativeSample文件夾存放。
負樣本圖片不要求樣本的尺寸,但要大于等于正樣本的大??;且負樣本不能重復,要增大負樣本的差異性。
負樣本也要灰度化,同正樣本操作相同。

img

4.4 創建工作目錄

在電腦任意目錄,創建一個工作目錄OpenCV_TrainingData,將存放正負樣本的目錄拷貝到OpenCV_TrainingData目錄下,再創建一個XML目錄,用于存放生成的訓練文件。

img

3.2 創建正樣本描述文件

打開電腦命令行終端。

img

使用cd命令進入到正樣本的目錄下。

img

執行命令如下:

命令1-進入到正樣本目錄下:cd /d D:\linux-share-dir\OpenCV_TrainingData\PositiveSample

命令2-將目錄下所有圖片名字和路徑輸出到pos.txt文件:dir /b/s/p/w *.jpg > pos.txt

打開生成的pos.txt文件內容如下。

img

將文件的內容稍作修改,加上檢測目標個數、目標圖片左上位置坐標、圖片寬高參數。

我這里準備的樣本圖片尺寸都是40x40,所以填寫的代碼:1 0 0 40 40

修改效果如下:

img

如果圖片數量很大,手動修改比較麻煩, 直接使用文本編輯器,搜索替換即可。

****

img

3.3 創建負樣本描述文件

負樣本描述文件創建方法與正樣本描述文件一樣,進入到負樣本圖片的目錄下,生成neg.txt文件,代碼如下:

命令1:cd /d D:\linux-share-dir\OpenCV_TrainingData\NegativeSample

命令2:dir /b/s/p/w *.jpg > neg.txt

注意:負樣本neg.txt文件不需要做任何修改,以下就是最終文件。

img

3.4 生成正樣本的.vec文件

為了方便填路徑,將生成的正負樣本描述文件pos.txt和neg.txt拷貝到上層目錄下。

img

正樣本的.vec文件生成,執行命令如下:

命令1:cd /d D:\linux-share-dir\OpenCV_TrainingData

命令2:C:\OpenCV_3.4.7\opencv-vc-3.4.7\build\x64\vc15\bin\opencv_createsamples.exe -vec pos.vec -info pos.txt -num 54 -w 40 -h 40

參數介紹:

opencv_createsamples.exe: 生成樣本描述文件的可執行程序(opencv自帶),前面是我電腦上的路徑。

-vec pos.vec 指定生成的vec文件

-info pos.txt 指定源樣本的描述文件

-num 54 指定標定目標樣本總數量,就是樣本描述文件里所有第2列的數字之和。

-w 40 指定樣本縮放后的寬,如果之前圖片不是40,那么這里就會縮放成40,有了這個參數就可以省去之前的圖片處理過程。

-h 40 指定樣本縮放后的高,如果之前圖片不是40,那么這里就會縮放成40,有了這個參數就可以省去之前的圖片處理過程。

我電腦上OpenCV的安裝路徑:

img

生成結果如下:

****

img

執行成功之后在當前目錄下生成pos.vec文件。

img


說明: 負樣本不需要生成vec文件。

3.5 開始訓練樣本

命令1:cd /d D:\linux-share-dir\OpenCV_TrainingData
命令2:C:\OpenCV_3.4.7\opencv-vc-3.4.7\build\x64\vc15\bin\opencv_traincascade.exe -data XML -vec pos.vec -bg neg.txt -numPos 50 -numNeg 133 -numStages 20 -w 40 -h 40 -mode ALL

參數介紹:

-data 指定輸出目錄,訓練生成的xml文件就放在這個目錄下

-vec 指定正樣本生成的 vec 文件

-bg 指定負樣本數據文件,即前面生成的neg.txt文件

-numPos 指定正樣本數目,這個數值一定要比準備正樣本時的數目少,不然會報 can not get new positive sample。

參考理由:minHitRate:影響每個強分類器閾值,當設置為0.95時如果正訓練樣本個數為10000個,那么其中的500個就很可能背叛別為負樣本,第二次選擇的時候必須多選擇后面的500個,按照這種規律我們為后面的每級多增加numPos*minHitRate個正樣本,根據訓練的級數可以得到如下公式

numPos+(numStages-1)numPos(1-minHitRate)《=準備的訓練樣本

以上式子也只是根據訓練級數和準備的正樣本總和設置一個參與訓練的正樣本個數,只能作為估算,小于計算出來的數可能沒有問題,但是大于那個數肯定有問題

現在解釋下”可能有問題“是如何理解的:因為我們總是默認每次添加固定個數的正訓練樣本,但是有時候后面的固定個數的正訓練樣本中也可能存在不滿足條件的樣本,這些樣本跟我們排除的樣本類似,所以比如我們打算添加500個樣本就夠了,但是實際需要添加600個,這時候就出現問題了。

從上面例子的結果中可以看出,每級我們允許丟掉12000*0.001個正樣本=12,需要注意的是萬一第11個或者第10個跟第12個的閾值是一樣的,那么我們之丟掉了前面的10個或者9個而已,因此每次增加的個數可能要小于12個,大于12個的情況就是上面所說的”可能有問題“。

-numStages 指定訓練級數

-numNeg 指定負樣本數目

-w 40 -h 40 指定樣本圖尺寸

-mode 指定haar特征的種類,basio僅僅使用垂直特征,al1表示使用垂直以及45度旋轉特征

開始訓練:

img

訓練成功之后在XML目錄下會生成cascade.xml文件,這個文件就是最終訓練成功的文件,可以替換到到上面代碼里測試。

img

審核編輯:湯梓紅("耗時:%1>
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 分類器
    +關注

    關注

    0

    文章

    152

    瀏覽量

    13225
  • OpenCV
    +關注

    關注

    31

    文章

    635

    瀏覽量

    41563
收藏 人收藏

    評論

    相關推薦

    OpenCV_編程簡介(入門必讀)

    opencv編程簡介,入門必讀,適合新手簡單了解opencv的相關知識。
    發表于 03-21 13:49 ?12次下載

    OpenCV開發環境的配置

    OpenCV3編程入門》書本配套源代碼:OpenCV開發環境的配置
    發表于 06-06 15:20 ?8次下載

    xml和YAML文件的寫入_OpenCV3編程入門

    OpenCV3編程入門》書本配套源代碼:xml和YAML文件的寫入
    發表于 06-06 15:20 ?6次下載

    OpenCV進行基本繪圖_《OpenCV3編程入門》書本配套源

    OpenCV3編程入門》書本配套源代碼:用OpenCV進行基本繪圖
    發表于 05-11 16:46 ?36次下載

    用迭代訪問像素_《OpenCV3編程入門》書本配套源代碼

    OpenCV3編程入門》書本配套源代碼:用迭代訪問像素
    發表于 06-06 15:52 ?2次下載

    OpenCV3編程入門-源碼例程全集-OpenCV開發環境的配置

    OpenCV3編程入門-源碼例程全集-OpenCV開發環境的配置,感興趣的小伙伴們可以瞧一瞧。
    發表于 09-18 16:27 ?20次下載

    OpenCV3編程入門-源碼例程全集-HoughCircles函

    OpenCV3編程入門-源碼例程全集-HoughCircles函數用法示例
    發表于 09-18 16:38 ?2次下載

    OpenCV3編程入門-源碼例程全集-HoughLinesP函數

    OpenCV3編程入門-源碼例程全集-HoughLinesP函數用法示例
    發表于 09-18 16:38 ?10次下載

    OpenCV3編程入門-源碼例程全集-GaussianBlur函

    OpenCV3編程入門-源碼例程全集-GaussianBlur函數用法示例
    發表于 09-18 16:38 ?1次下載

    OpenCV3編程入門-源碼例程全集-點追蹤

    OpenCV3編程入門-源碼例程全集-點追蹤
    發表于 09-18 16:38 ?0次下載

    OpenCV3編程入門-源碼例程全集-播放視頻

    OpenCV3編程入門-源碼例程全集-播放視頻
    發表于 09-17 22:54 ?18次下載

    OpenCV3編程入門-源碼例程全集-人臉識別

    OpenCV3編程入門-源碼例程全集-人臉識別
    發表于 09-17 22:55 ?2次下載

    OpenCV3編程入門-源碼例程全集-模板匹配

    OpenCV3編程入門-源碼例程全集-模板匹配
    發表于 09-17 22:55 ?4次下載

    OpenCV進行基本繪圖_OpenCV3編程入門-源碼例程

    OpenCV3編程入門-源碼例程全集-用OpenCV進行基本繪圖,感興趣的小伙伴們可以瞧一瞧。
    發表于 09-18 17:02 ?3次下載

    opencv-python和opencv一樣嗎

    的。以下是對OpenCVOpenCV-Python的比較: 編程語言: OpenCV是一個跨平臺的庫,支持多種編程語言,如C++、Java
    的頭像 發表于 07-16 10:38 ?1405次閱讀
    主站蜘蛛池模板: 欧美视频区 | 国产成人乱码一区二区三区 | 日本久本草精品 | 国产18到20岁美女毛片 | 日韩欧美不卡片 | 羞羞色男人的天堂伊人久久 | 怡红院免费va男人的天堂 | 国产人人艹 | 日韩欧美高清一区 | 日韩一级高清 | 免费欧美 | 天天躁日日躁狠狠躁一级毛片 | 日本高清一区二区三区不卡免费 | 国产精品好好热在线观看 | 亚洲免费网站在线观看 | 201天天爱天天做 | 免费高清成人啪啪网站 | 9久久精品 | 色免费看 | 在线种子搜索 | 国产午夜在线观看 | 18男女很黄的视频 | 华人被黑人粗大猛然进 | 你懂的网站在线观看网址 | 色老头影视| 天天做天天爰夜夜爽 | 国产精品久久精品福利网站 | 天天躁狠狠躁夜躁2021 | 亚洲高清中文字幕一区二区三区 | 农村三级毛片 | 欧美精品专区55页 | 在线视频网址免费播放 | 亚洲韩国欧美一区二区三区 | 特级毛片永久久免费观看 | 成人午夜久久 | 久草免费新视频 | 99青草青草久热精品视频 | 丁香久久婷婷 | 亚洲第一狼人社区 | 亚洲第七页 | 欧美成人性色 |