3480 views|14 replies

291

Posts

5

Resources
The OP
 

Embedded Qt-Simple Network Surveillance Camera [Copy link]

 


This article uses Qt to implement a network camera function, which includes a server and a client. The server is used to convert the USB camera into an IP camera. When a client is connected, the captured image is sent out through TCP; the client runs on a Linux board and is used to view the real-time image of the camera.

1. Required basic knowledge

This article requires writing a server and a client

1.1 QTcpSocket and QTcpServer

  • QTcpSocket , in Qt, Socket is encapsulated into QTcpSocket, which can be used to implement the functions of TCP client, as well as the processing of the client after the server receives the client.

  • QTcpServer , for the TCP server functions, you can use QTcpServer to complete.

Here is a summary of how to use TCP Socket in Qt. By combining it with Qt's signal and slot mechanism, you can implement the sending and receiving of server/client data.

1.2 QCamera related

  • QCamer , get the cameras available in the current system similar to getting the serial port

  • QCamerInfo , get the camera available in the current system similar to getting the serial port

  • QCameraViewfinder , viewfinder class, the real-time image of the camera is displayed in it

  • QCameraImageCapture , image recording class, can be used with QCamer to take pictures

2 Test on Win platform

First, use Qt Creator on the Windows platform to write the server and client programs and run the test.

2.1 Server

Let's first look at the final effect on the server side:

  • The left side is the camera display interface

  • You can switch between different cameras as video sources (the built-in camera of the laptop and the USB external camera)

  • You can switch the camera display resolution

  • You can choose to turn on or off the camera's IP service

2.1.1 Camera screen display

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 Creating a Socket Service

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("Close IP service");
   }
  else
   {
    qDebug() << "stop IP server";
    m_pServer->close();
    delete m_pServer;

    ui->btn_IPServer->setText("Enable IP service");
   }
}

2.1.3 Read the image and send it to the client

First define the image transmission structure and transmission status:

enum TransStatus{
  TS_IDLE, //Idle (image data can be updated)
  TS_RUNNING, //Image data is being transmitted (image data cannot be updated yet)
  TS_FIRST_DATA, //The first part of the image data needs to be sent
};

class ImgData {
public:
  char data[LEN] = {0}; //image data
  int totalLen = 0; //image size
  int hasSentLen = 0; //The length of the data sent
  TransStatus stats = TS_IDLE; //Working status
};

Specific implementation process:

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)) //The image size is not 0, indicating that the image data has been updated
     {
      pData->stats = TS_RUNNING;
      m_pClient->write(s.arg(pData->totalLen).toUtf8());
      pData->hasSentLen = 0;
     }
    else //The image data has not been updated
     {
      pData->stats = TS_FIRST_DATA; //Send "newImage..." in the timer slot function
     }
   }
  else if (str == "ack")
   {
    int len_send = P_LEN; //The length to be sent this time

    if (pData->hasSentLen >= pData->totalLen) //If the image has been transmitted
     {
      qDebug() << "read_data, send done! lenSent:" << pData->hasSentLen << "len" << pData->totalLen;
      return;
     }

    // The last packet of data (less than P_LEN)
    if ((pData->hasSentLen + P_LEN) > pData->totalLen)
     {
      len_send = pData->totalLen - pData->hasSentLen;
     }

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

    // Send data
    pData->hasSentLen += m_pClient->write(pData->data + pData->hasSentLen, len_send);
    if (pData->hasSentLen >= pData->totalLen)
     {
      pData->stats = TS_IDLE; //After the transfer is completed, change the status to updateable
      pData->totalLen = 0;
     }
   }
}

It should be noted that images need to be transmitted in packets, and the last packet is usually not the maximum length set, so the data length of the last packet needs to be calculated.

2.2 Client

Let’s first look at the final effect of the client:

  • On the right is the display frame of the camera image

  • You can modify the IP address of the server to connect to

  • You can choose to turn the webcam on or off

2.2.1 Create a Socket Connection

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("Close");
    m_iRecvLen = 0;
    m_pSocket->write("new_request");
    qDebug("on_bnt_connect_clicked, new_request");
   }
  else
   {
    m_pSocket->close();
    ui->pushButton->setText("Open");
   }
}

2.3.2 Receiving images from the server

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;
     }
   }

  //Image transfer completed
  m_pSocket->write("ack");
}

2.3.3 Display the image

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 Testing on Embedded Linux Platform

3.1 Cross-compilation

Copy the source code of the client program to Ubunu for cross-compilation. For the specific compilation process, please refer to the previous article:

Embedded Qt - Write and run your first ARM-Qt program

The experimental environment of this article continues to use the Linux board with the system firmware of WildFire i.MX6ULL burned. The compiled program needs to be sent to the board through SSH. The operation of SSH file transfer can refer to the previous article:

Embedded Qt-Control Hardware: Slide bar controls RGB lights

3.2 Experimental Demonstration


4 Conclusion

This article introduces how to use Qt to implement a network camera function, convert a USB camera into an IP camera through the server, and use the client in the Linux board to connect to the server to display the real-time image of the camera.

This post is from ARM Technology

Latest reply

Good learning, thanks for sharing   Details Published on 2022-10-10 11:27
 

6555

Posts

0

Resources
2
 

It seems that it is quite complicated to implement a webcam function using Qt. Thanks for sharing.

This post is from ARM Technology
 
 
 

4764

Posts

12

Resources
3
 

Isn't Qt used for pages?

Web pages should be simpler

This post is from ARM Technology

Comments

The requirements for the browser under the MPU in the embedded system are very high, and usually it must be supported by the operating system, so the operating cost is relatively high, but the embedded system often does not have an operating system.  Details Published on 2022-9-3 15:09
 
 
 

6818

Posts

11

Resources
4
 

What is the price of Wildfire boards? I want to learn about them recently.

This post is from ARM Technology

Comments

Do you want the STM32 series or the Linux series?  Details Published on 2022-8-30 13:13
 
 
 

6742

Posts

2

Resources
5
 

There doesn't seem to be much delay when watching videos, is it because it's a local area network so the delay is small?

This post is from ARM Technology
 
 
 

6742

Posts

2

Resources
6
 
lugl4313820 posted on 2022-8-30 08:37 What is the price of the Wildfire board? I want to learn about it recently.

Do you want the STM32 series or the Linux series?

This post is from ARM Technology

Comments

Linux, I have already bought the book, but I don’t have the matching development board.  Details Published on 2022-8-30 15:50
 
 
 

6818

Posts

11

Resources
7
 
wangerxian posted on 2022-8-30 13:13 Do you want the STM32 series or the Linux series?

Linux, I have already bought the book, but I don’t have the matching development board.

This post is from ARM Technology
 
 
 

2865

Posts

4

Resources
8
 
Azuma Simeng posted on 2022-8-30 08:24 Isn't Qt for web pages? Web pages should be simpler, right?

The requirements for the browser under the MPU in the embedded system are very high, and usually it must be supported by the operating system, so the operating cost is relatively high, but the embedded system often does not have an operating system.

This post is from ARM Technology
 
 
 

3

Posts

0

Resources
9
 

Does this consume a lot of power on the development board? If it is powered by batteries, will the design not last long?

This post is from ARM Technology

Comments

The power consumption issue has not been considered carefully yet.  Details Published on 2022-9-5 22:40
 
 
 

291

Posts

5

Resources
10
 
shanyinglee posted on 2022-9-5 12:21 Does this consume a lot of power on the development board? If it is powered by a battery, will the design not last for a long time?

The power consumption issue has not been considered carefully yet.

This post is from ARM Technology
 
 
 

2

Posts

0

Resources
11
 

Not bad, it has inspired my passion for learning. I will learn and master the knowledge of C++, Qt, Linux, network programming, cameras, etc.

This post is from ARM Technology
 
 
 

210

Posts

3

Resources
12
 

Very good, thanks for sharing

This post is from ARM Technology
 
 
 

4764

Posts

12

Resources
13
 

Not bad, not bad, study

This post is from ARM Technology
 
 
 

994

Posts

3

Resources
14
 

I remembered my old board and took it out to have a look.

This post is from ARM Technology
 
 
 

7

Posts

0

Resources
15
 

Good learning, thanks for sharing

This post is from ARM Technology
 
 
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list