色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

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

3天內不再提示

嵌入式Qt-簡易網絡監控攝像頭

碼農愛學習 ? 來源:碼農愛學習 ? 作者:碼農愛學習 ? 2022-09-14 08:52 ? 次閱讀


本編利用Qt實現一個網絡攝像頭功能,包含一個服務端和一個客戶端,服務端用于將USB攝像頭轉換為一個IP攝像頭,當有客戶端連接時,將其捕獲到的圖像通過TCP發送出去;客戶端運行在Linux板子上,用于查看攝像頭的實時畫面。

1 必備基礎知識

本篇需要編寫一個服務器和客戶端。

注意,Qt中對Socket的操作進行了進一步的封裝,其基本思想還是一樣的。

下面就來看一下Qt中如何實現TCP Socket通信

1.1 QTcpSocket與QTcpServer

QTcpSocket,在Qt中,Socket被封裝成了QTcpSocket,可以用它實現TCP客戶端的功能,以及服務端接收到客戶端后,對客戶端的處理。

QTcpServer,對于TCP服務端的功能,可以使用QTcpServer來完成。

這里整理Qt中TCP Socket的使用方法,配合Qt的信號與槽機制,即可實現服務端/客戶端數據的收發處理。

pYYBAGMgke-AS-cqAABRBCZsiFA664.png

1.2 QCamera相關

QCamer,獲取當前系統可用的攝像頭 類似獲取串口

QCamerInfo,獲取當前系統可用的攝像頭 類似獲取串口

QCameraViewfinder,取景框類,攝像頭的實時畫面顯示到這個里面

QCameraImageCapture,圖像錄制類,與QCamer 配合使用可進行拍照

2 Win平臺上測試

首先在Windows平臺上用Qt Creator編寫服務端和客戶端程序,并運行測試。

2.1 服務器端

先來看下服務器端的最終效果:

左側是攝像頭的顯示界面

可以切換不同的攝像頭作為視頻源(筆記本自帶的攝像頭與USB外接的攝像頭)

可以切換攝像頭的顯示分辨率

可以選擇開啟或關閉攝像頭的IP服務

poYBAGMgkgCAchMbAAIIP9aGJfc341.png

2.1.1 攝像頭畫面顯示

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    QComboBox *pCamType = new QComboBox();
    m_pComboBox = ui->cbBox_resolution;
    pCamType = ui->cbBox_cameras;
    pCamType->clear();

    cameraList = QCameraInfo::availableCameras();
    foreach(const QCameraInfo &cameraInfo, cameraList)
    {
        qDebug() << "CameraInfo:" << cameraInfo;
        pCamType->addItem(cameraInfo.description());
    }

    m_pCamViewFind = new QCameraViewfinder(this);
    m_pCamViewFind->setGeometry(10, 10, W, H);
    m_pCamViewFind->show();

    m_pCam = new QCamera(this);
    m_pCam->setViewfinder(m_pCamViewFind);
    m_pCam->start();
}

2.1.2 創建Socket服務

void Widget::on_btn_IPServer_toggled(bool checked)
{
    if (checked)
    {
        m_pServer = new QTcpServer(this);
        if (!m_pServer->listen(QHostAddress::Any, 12345))
        {
            QMessageBox::critical(this, "error", "listen port failed");
            exit(0);
        }
        qDebug() << "start IP server";

        m_pTimer = new QTimer(this);
        connect(m_pServer, SIGNAL(newConnection()), this, SLOT(new_client()));
        connect(m_pTimer, SIGNAL(timeout()), this, SLOT(timer_slot()));
        m_pTimer->start(100);

        ui->btn_IPServer->setText("關閉IP服務");
    }
    else
    {
        qDebug() << "stop IP server";
        m_pServer->close();
        delete m_pServer;

        ui->btn_IPServer->setText("開啟IP服務");
    }
}

2.1.3 讀取圖像并發送給客戶端

先定義一下圖像傳送結構體和傳送狀態:

enum TransStatus{
    TS_IDLE,       //空閑(圖像數據可以更新)
    TS_RUNNING,    //圖像數據傳輸中(還不可以更新圖像數據)
    TS_FIRST_DATA, //需要發出圖像數據的第一部分
};

class ImgData {
public:
    char data[LEN] = {0}; //圖像數據
    int  totalLen = 0; //圖像大小
    int  hasSentLen = 0; //已發出的數據長度
    TransStatus  stats = TS_IDLE; //工作狀態
};

具體的實現過程:

void Widget::read_data()
{
    QString str = m_pClient->readAll();
    ImgData *pData = (ImgData*)m_pClient->userData(0);
    QString s("newImage:%1");

    if (str == "new_request")
    {
        qDebug() << "read_data, new_request, d->len:" << pData->totalLen << "d->stats:" << pData->stats;
        if ((pData->totalLen > 0) && (pData->stats==TS_IDLE)) //圖像大小不為0,表示已更新圖像數據了
        {
            pData->stats = TS_RUNNING;
            m_pClient->write(s.arg(pData->totalLen).toUtf8());
            pData->hasSentLen = 0;
        }
        else //圖像數據還沒有更新
        {
            pData->stats = TS_FIRST_DATA; //在定時器的槽函數里發出"newImage..."
        }
    }
    else if (str == "ack")
    {
        int len_send = P_LEN; //本次需要發送的長度

        if (pData->hasSentLen >= pData->totalLen) //如果圖像已傳輸完畢
        {
            qDebug() << "read_data, send done! lenSent:" << pData->hasSentLen << "len" << pData->totalLen;
            return;
        }

        // 最后1包數據(不滿P_LEN)
        if ((pData->hasSentLen + P_LEN) > pData->totalLen)
        {
            len_send = pData->totalLen - pData->hasSentLen;
        }

        qDebug() << "read_data, ack, write len:" << len_send;

        // 發送數據
        pData->hasSentLen += m_pClient->write(pData->data + pData->hasSentLen, len_send);
        if (pData->hasSentLen >= pData->totalLen)
        {
            pData->stats = TS_IDLE; //傳輸完畢后,把狀態改為可更新
            pData->totalLen = 0;
        }
    }
}

需要注意的是,圖像是需要分包傳送的,最后一包一般都不是設定的最大長度,需要計算一下最后一包的數據長度。

2.2 客戶端

先來看下客戶端的最終效果:

右側是攝像頭畫面的顯示框

可以修改要連接的服務端的IP地址

可以選擇開啟或關閉網絡攝像頭

pYYBAGMgkmmAfG1cAACzHDLq1qM978.png

2.2.1 創建Socket連接

void Widget::on_pushButton_toggled(bool checked)
{
    if (checked)
    {
        QString ip = ui->lineEdit->text();
        m_pSocket->connectToHost(ip, 12345);
        if (!m_pSocket->waitForConnected(1000))
        {
            QMessageBox::critical(this, "error", "server connection failed");
            return;
        }

        ui->pushButton->setText("關閉");
        m_iRecvLen = 0;
        m_pSocket->write("new_request");
        qDebug("on_bnt_connect_clicked, new_request");
    }
    else
    {
        m_pSocket->close();
        ui->pushButton->setText("打開");
    }
}

2.3.2 接收服務端的圖像

void Widget::read_data()
{
    int ret;
    QTime qTime;
    static int i = 0;

    ret = m_pSocket->read(m_pData + m_iRecvLen, P_LEN);
    if (0 == strncmp("newImage", m_pData + m_iRecvLen, 8))
    {
        m_iImgLen = atoi(m_pData + m_iRecvLen + 9);
        i++;
    }
    else
    {
        m_iRecvLen += ret;
        if (m_iRecvLen >= m_iImgLen)
        {
            QString timestamp = QString::number(QDateTime::currentMSecsSinceEpoch());
            update();

            return;
        }
    }

    //圖像傳輸完畢
    m_pSocket->write("ack");
}

2.3.3 將圖像顯示出來

void Widget::paintEvent(QPaintEvent *event)
{
    QPixmap map;

    if ((m_iRecvLen >= m_iImgLen) && (m_iImgLen > 0))
    {
        map.loadFromData((uchar *)m_pData, m_iImgLen);
        QPainter p(this);
        p.drawPixmap(140, 0, 640, 480, map);
        m_pSocket->write("new_request");
        m_iRecvLen = 0;
    }
}

3 嵌入式Linux平臺上測試

3.1 交叉編譯

將客戶端程序的源代碼拷貝到Ubunu中進行交叉編譯,具體編譯過程可參考之前的文章:

嵌入式Qt-動手編寫并運行自己的第1個ARM-Qt程序

本篇的實驗環境,繼續使用的是燒錄了野火i.MX6ULL自帶的系統固件Linux板子,需要通過SSH的方式將編譯的程序再發送到板子中,SSH傳輸文件的操作可參考上篇文章:

嵌入式Qt-控制硬件:滑動條控制RGB燈

3.2 實驗演示

https://www.bilibili.com/video/BV12G4y1a7za

poYBAGMgkvKAGzXjAA2qetEAwRE119.png

4 總結

本篇介紹了如何用Qt實現一個網絡攝像頭功能,通過服務端將USB攝像頭轉換為一個IP攝像頭,Linux板子中的客戶端來連接服務器,將攝像頭的實時畫面顯示出來。

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 嵌入式
    +關注

    關注

    5089

    文章

    19170

    瀏覽量

    306800
  • 攝像頭
    +關注

    關注

    60

    文章

    4860

    瀏覽量

    96082
  • Qt
    Qt
    +關注

    關注

    1

    文章

    308

    瀏覽量

    38009
收藏 人收藏

    評論

    相關推薦

    嵌入式Qt-表格使用測試

    本篇介紹了Qt中QTable Widget這個表格組件的使用,后續可增加SQLite數據庫功能,利用表格可以直觀的展示出嵌入式設備的數據庫中的數據信息。
    的頭像 發表于 05-14 12:27 ?1643次閱讀
    <b class='flag-5'>嵌入式</b><b class='flag-5'>Qt-</b>表格使用測試

    監控攝像頭的選型方法

    監控攝像頭的選用原則做以下簡單說明,希望對您的項目有所幫助:      1)根據安裝方式選擇。如固定安裝,監控攝像頭多選用普通槍
    發表于 02-05 16:23

    網絡攝像頭監控的系統優勢

    軟件系統即可;  可靠性:主要設備網絡攝像頭采用了嵌入式實時操作系統,所需設備簡單,而圖像的傳輸是通過綜合布線網絡實現的,系統可靠性相當高;  網絡
    發表于 03-25 15:26

    【OK210申請】基于嵌入式LinuxQT開發的攝像頭監控系統

    開發板提供的資料進行學習,然后自己移植一個全新的Linux內核,及移植基于QT5.0版本以上的文件系統來開發一個攝像頭監控項目,項目的功能主要是能實現攝像頭的拍照,及錄像,達到
    發表于 06-25 12:01

    【OK210申請】簡易攝像頭監控系統

    ,之前用過一款,很喜歡。項目描述:項目就是做一個簡易攝像頭監控系統,其功能主要類似于小區攝像頭監控的系統,在實現基本功能之后,希望能對小區的
    發表于 07-26 09:55

    【OK210申請】基于arm嵌入式監控智能小車的設計與實現

    經驗目前正在做的項目是基于嵌入式arm平臺的監控智能小車的設計與實現該項目的的功能是:1、手機app操作小車的運動2、手機app可觀看到小車攝像頭發回的視頻手機app實現用到的是Qt
    發表于 08-03 09:40

    【AWorks280試用申請】u***監控攝像頭

    申請理由:物聯網的興起,導致嵌入式設備需要更強大的采集和通信功能,普通單片機開發難度過高。本人想通過這次活動,嘗試使用arm9+linux來實現攝像頭驅動和一些網絡應用。項目描述:使用這塊280板子枚舉u***
    發表于 10-23 10:09

    【NanoPi NEO Plus2開發板試用申請】u***攝像頭遠程監控

    項目名稱:u***攝像頭遠程監控試用計劃:最近工業自動化開發上有一個工業攝像頭的遠程wifi監控項目。該攝像頭的驅動對于處理器有較大要求,需
    發表于 08-09 10:08

    教你做一個用嵌入式linux開發板和web端來實現的視頻監控系統

    node.js html QT硬件:開發板:ARM開發板、樹莓派、jetson nano...等跑linux系統的開發板,連接一個攝像頭;電腦:Web前端,可查看監控畫面;功能介紹:開發板與電腦通過
    發表于 11-05 07:38

    嵌入式視頻監控的相關資料分享

    上利用USB 攝像頭采集視頻圖像,通過視頻圖像壓縮及結合網絡進行視頻圖像傳輸,使遠程監控成為可能。文章目錄嵌入式視頻監控1 系統介紹1.1
    發表于 11-08 07:10

    監控攝像頭的種類

    監控攝像頭的種類:監控攝像頭一般有幾種?有很多種,監控攝像頭的效果,主要看他的芯片和線數。一般買
    發表于 03-17 12:04

    嵌入式工控板上接一個攝像頭進行視頻監控

    嵌入式工控板上接一個攝像頭進行視頻監控,看起來比較容易實現,但是往往是理想很豐滿、現實很骨感歷經千辛萬苦效果卻不是很理想,本文就給大家介紹各種解決方案。 這里給大家介紹的是既對外設有需求,又要連接
    發表于 10-15 12:13 ?0次下載

    如何使用ARM進行嵌入式監控系統的設計

    本文利用網絡嵌入式設備實現遠程視頻監控的系統。攝像頭采集模擬的視頻信號轉化為數字信號后,通過局域網傳送到網內的任何一臺計算機, 從而實現異地的監控
    發表于 03-13 18:07 ?7次下載
    如何使用ARM進行<b class='flag-5'>嵌入式</b><b class='flag-5'>監控</b>系統的設計

    嵌入式視頻監控

    上利用USB 攝像頭采集視頻圖像,通過視頻圖像壓縮及結合網絡進行視頻圖像傳輸,使遠程監控成為可能。文章目錄嵌入式視頻監控1 系統介紹1.1
    發表于 11-02 21:06 ?31次下載
    <b class='flag-5'>嵌入式</b>視頻<b class='flag-5'>監控</b>

    嵌入式日記:破解RPi攝像頭以與Zynq FPGA配合使用

    電子發燒友網站提供《嵌入式日記:破解RPi攝像頭以與Zynq FPGA配合使用.zip》資料免費下載
    發表于 06-27 11:15 ?1次下載
    <b class='flag-5'>嵌入式</b>日記:破解RPi<b class='flag-5'>攝像頭</b>以與Zynq FPGA配合使用
    主站蜘蛛池模板: 国产亚洲精品久久77777| 午夜日本大胆裸艺术| 无限资源在线观看8| 成人免费观看国产高清| 美女gif趴跪式动态图| 2019精品国产品在线不卡| 看80后操| 99久久国产极品蜜臀AV酒店| 美女脱光app| 99久久999久久久综合精品涩| 免费看片A级毛片免费看| 99久久精品国产亚洲AV| 暖暖日本在线手机免费完整版 | 日本妈妈JMZZZZZ| 成人人猿泰山| 香蕉在线播放| 国内精品久久| 一二三四韩国免费观看| 老色哥网站| 99精品视频在线观看免费播放| 欧美互交人妖247| 丰满人妻按磨HD| 亚洲国产精品VA在线看黑人| 久草大| 99精品视频在线观看| 日韩综合网| 中文字幕在线观看亚洲视频| 久久性生大片免费观看性| 97亚洲狠狠色综合久久久久| 日本xxxx裸体xxxx| 国产一卡 二卡三卡四卡无卡乱码视频 | 老师的玉足高跟鞋满足我| SM调教贱屁股眼哭叫求饶H| 天天国产在线精品亚洲| 精品高潮呻吟99AV无码视频| 91系列在线观看免费| 京香在线观看| 99精品在线| 性感尼姑风流寺| 美女穿丝袜被狂躁动态图| 成人1000部免费观看视频|