VS2015+Qt+OpenCV+open62541 development process (07_VS2015+Qt+OpenCV+OPC UA programming)

The previous chapters completed the programming environment configuration and testing of opencv, OPCUA, and Qt in VS2015. The following is the joint programming of these tools, and finally an executable user program is realized. The application scenario is to use industrial cameras to capture images for image processing. processing, with the following functions:

  1. Read and write field PLC variable function
  2. According to the PLC variable value, take pictures from Hikvision industrial cameras
  3. Use opencv to process images and communicate with PLC
  4. The user interface can display the currently processed image

According to the steps in the previous chapter, first test whether opencv is available in the Qt program framework.

Double-click the .ui file in the project Form files to open the Qt designer design window

Put a graphview control in the control library on the left to the middle window. This control can be used as a container for picture display.

Add another pushbutton button to trigger the execution of the program, and you need to add the slot function start. Add the slot function declaration in the .h file, and add the slot function implementation in the .cpp file. Subsequent image acquisition communication, image processing, and interface display are all implemented in the slot function.

The header file corresponding to the control added by Qt also needs to be added to the code. If the graphicView control is used to display pictures, you need to add the #include header file, otherwise the name of the control cannot be read.

After adding the control, right-click the project point in VS to re-scan the solution, otherwise the added control class cannot be found in the code (personal understanding is to add the control and apply it, and the control will be added to the UI header file in VS)

Add the association between the pushbutton control and the slot function. The function is to click the start button when running the program, trigger the clicked event, call the slot function on_start_clicked() to execute the code in it

Slot function implementation and interpretation:

void Qt_test01::on_start_clicked()

{

    QGraphicsScene *scene = new QGraphicsScene; //Define the display scene control, which is used to display pictures to the main window. The scene control is used as a container to transfer pictures to the picture control. The scene control is in the background and will not be displayed on the user interface

    img = cv::imread("..\pic_test.jpg"); //Read a picture from the hard disk

    h_imgorg = (int)ui.graphicsView->height() - 5; //Set the size of the picture, which is a little smaller than the picture container of the UI interface

    w_imgorg = (int)ui.graphicsView->width() - 5;

    cv::resize(img, img, Size(w_imgorg, h_imgorg)); //Change the image size to fit the size of the image display control

    Qimg_org = QImage((const unsigned char*)(img.data), img.cols, img.rows, img.step, QImage::Format_RGB888); //Mat format image converted to Qt format image

    scene->clear(); //Scene space and label space should be cleared before displaying pictures or text, otherwise they will be overwritten and memory usage will increase

    scene->addPixmap(QPixmap::fromImage(Qimg_org)); //Scene control add picture

    ui.graphicsView->setScene(scene); //The picture in the scene control container is added to the picture control

    ui.graphicsView->show(); //The picture control displays pictures

   

}

Press Ctrl + F5 to debug, click the start button, and the picture will be displayed, indicating that opencv is ok and can be used

Continue the experiment, read the Hikvision industrial camera, capture and display the picture in the user window, and add the code for reading the camera to the on_start_clicked() slot function.

void Qt_test01::on_start_clicked()

{

    capture = VideoCapture(0); //Open the camera

    capture.set(CAP_PROP_FRAME_WIDTH, 2448); // Set image width

    capture.set(CAP_PROP_FRAME_HEIGHT, 2048); // set image height

    capture.set(CAP_PROP_FPS, 5); // set frame rate

    if (!capture.isOpened())

    {

        QMessageBox::information(this, "information", "Open camera failed!");

        capture. release();

        return;

    }

    capture >> img; // read a frame in the video stream, write img

    QGraphicsScene *scene = new QGraphicsScene; //Define the display scene control, which is used to display pictures to the main window. The scene control is used as a container to transfer pictures to the picture control. The scene control is in the background and will not be displayed on the user interface

    //img = cv::imread("..\pic_test.jpg"); //Read a picture from the hard disk

    h_imgorg = (int)ui.graphicsView->height() - 5; //Set the size of the picture, which is a little smaller than the picture container of the UI interface

    w_imgorg = (int)ui.graphicsView->width() - 5;

    cv::resize(img, img, Size(w_imgorg, h_imgorg)); //Change the image size to fit the size of the image display control

    Qimg_org = QImage((const unsigned char*)(img.data), img.cols, img.rows, img.step, QImage::Format_BGR888); //Mat format image converted to Qt format image

    scene->clear(); //Scene space and label space should be cleared before displaying pictures or text, otherwise they will be overwritten and memory usage will increase

    scene->addPixmap(QPixmap::fromImage(Qimg_org)); //Scene control add picture

    ui.graphicsView->setScene(scene); //The picture in the scene control container is added to the picture control

    ui.graphicsView->show(); //The picture control displays pictures

}

Press Ctrl + F5 to debug and run, click the start button, the graphicView control will display the current picture of the camera successfully

Continue to test OPC UA to read PLC variables, and take pictures according to the changes in variable values. Here, use the “test.test.OPC_test” point of the previous experiment. When it is equal to 1, the picture will be taken and displayed, and when it is equal to 0, the picture will be read from the hard disk and displayed. . Add two more label controls to display the read OPC_test value in real time.

The program adds a do loop to read the value of the OPC variable in a loop; a closeevent slot function needs to be added to exit the do loop and release the OPC interface and camera when clicking to close the application, otherwise the do loop cannot exit the program and enter an infinite loop.

The two slot functions are modified as follows:

void Qt_test01::on_start_clicked()

{

    QGraphicsScene *scene = new QGraphicsScene; //Define the display scene control, which is used to display pictures to the main window. The scene control is used as a container to transfer pictures to the picture control. The scene control is in the background and will not be displayed on the user interface

    client = UA_Client_new(); //create opcua client

    UA_ClientConfig_setDefault(UA_Client_getConfig(client)); //Set the client as the default configuration

    status = UA_Client_connect(client, "opc.tcp://127.0.0.1:49320"); //Connect to the server, connect to KEPServer here, the URL can be viewed by right-clicking the KEPServer software on the taskbar and selecting "OPC UA Configuration"

                                                                         //Judge the connection status of the opcua client

    if (status != UA_STATUSCODE_GOOD)

    {

        QMessageBox::information(this, "information", "Connect OPC UA Sever Failed");

        return;

    }

    else

    {

        QMessageBox::information(this, "information", "Connect OPC UA Sever Successful");

    }

    UA_Variant value; //opcua variable type

    UA_Variant_init( & amp;value); //Initialization, note that the value of value.data cannot be read directly after initialization, which will cause memory pointer errors, and value.data must be read or assigned through opcua

    capture = VideoCapture(0); //Open the camera

    capture.set(CAP_PROP_FRAME_WIDTH, 2448); // Set image width

    capture.set(CAP_PROP_FRAME_HEIGHT, 2048); // set image height

    capture.set(CAP_PROP_FPS, 5); // set frame rate

    if (!capture.isOpened())

    {

        QMessageBox::information(this, "information", "Open camera failed!");

        capture. release();

        return;

    }

    do

    {

        status = UA_Client_readValueAttribute(client, UA_NODEID_STRING(2, "test.test.OPC_test"), & amp;value);

        if (status != UA_STATUSCODE_GOOD)

        {

             QMessageBox::information(this, "information", "OPC UA read Failed");

             return;

        }

        OPC_test = *(UA_UInt32*)value.data;

        if (OPC_test == 1)

        {

             capture >> img; // read a frame in the video stream, write img

             h_imgorg = (int)ui.graphicsView->height() - 5; //Set the size of the picture, which is a little smaller than the picture container of the UI interface

             w_imgorg = (int)ui.graphicsView->width() - 5;

             cv::resize(img, img, Size(w_imgorg, h_imgorg)); //Change the image size to fit the size of the image display control

             Qimg_org = QImage((const unsigned char*)(img.data), img.cols, img.rows, img.step, QImage::Format_BGR888); //Mat format image converted to Qt format image

             scene->clear(); //Scene space and label space should be cleared before displaying pictures or text, otherwise they will be overwritten and memory usage will increase

             scene->addPixmap(QPixmap::fromImage(Qimg_org)); //Scene control add picture

             ui.graphicsView->setScene(scene); //The picture in the scene control container is added to the picture control

             ui.graphicsView->show(); //The picture control displays pictures

        }

        else if(OPC_test == 0)

        {

             img = cv::imread("..\pic_test.jpg"); //Read a picture from the hard disk

             h_imgorg = (int)ui.graphicsView->height() - 5; //Set the size of the picture, which is a little smaller than the picture container of the UI interface

             w_imgorg = (int)ui.graphicsView->width() - 5;

             cv::resize(img, img, Size(w_imgorg, h_imgorg)); //Change the image size to fit the size of the image display control

             Qimg_org = QImage((const unsigned char*)(img.data), img.cols, img.rows, img.step, QImage::Format_BGR888); //Mat format image converted to Qt format image

             scene->clear(); //Scene space and label space should be cleared before displaying pictures or text, otherwise they will be overwritten and memory usage will increase

             scene->addPixmap(QPixmap::fromImage(Qimg_org)); //Scene control add picture

             ui.graphicsView->setScene(scene); //The picture in the scene control container is added to the picture control

             ui.graphicsView->show(); //The picture control displays pictures

        }

        ui.label_2->setText(QString::number(OPC_test));

        cv::waitKey(100); //waitKey() waiting time, this function must be added to opencv display pictures, otherwise it will not be displayed

    } while (Flag);

    UA_Client_delete(client); //Release opcua client

    capture.release(); //Release the camera

    return;

}

void Qt_test01::closeEvent(QCloseEvent * event)

{

    Flag = 0;

}

Press Ctrl + F5 to debug

Click to start (the initial value of OPC_test is 0, and the picture read from the hard disk is displayed)

Use the OPC Quick Client tool that comes with Kepsever to modify the OPC_test value to 1. At this time, the user interface picture automatically displays the current picture of the camera, and the current camera picture is a real-time dynamic video.

Summarize:

  1. Qt framework development windows application can develop the user interface graphically on the front end, and write the slot function on the background. In the experiment, it is an event-triggered mode, that is, it is executed after clicking the button corresponding slot function
  2. In the experiment, it is verified to read and write PLC variables through OPC UA (the analog channel of Kepsever is used here, and the actual PLC is not directly connected); it is also verified here The problem mentioned in the experiment of the previous article that using open62541 (using ws2_3lib) to verify OPC UA reading and writing can only be performed on a 32-bit (x86) platform, and an error will be reported when switching to 64-bit. Using the Qt framework to select a 64-bit platform can also perform OPC UA reading and writing, because Qt is cross-platform
  3. Kepsever software is used as a server in the experiment, and a license needs to be purchased. There is a time limit for using the trial version in the experiment
  4. Opencv and open62541 libraries are open source and free
  5. The friendly interface available for subsequent development of Qt needs to continue to learn, such as interface layout, menu bar, toolbar, status bar and other functions
  6. Using the opencv library to perform image processing and algorithms on camera images will require in-depth study of opencv
  7. Pay special attention to various variable type conversions, such as the opencv image is of Mat type, and it needs to be converted to QImage type for Qt interface display; OPCUA data is of UA_Variant type, C++ data is long type, need to be converted when assignment
  8. Pay special attention to the sequence of image channels, opencv defaults to BGR format, Hikvision camera output format can be selected and set through MVS software, which is required when developing with Hikvision SDK Convert the format, using opencv’s VideoCapture does not need to convert the format

The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge. OpenCV skill treeHomepageOverview 14800 people are studying systematically