当前位置:网站首页>Infrared thermometer based on STM32 single chip microcomputer (with face detection)

Infrared thermometer based on STM32 single chip microcomputer (with face detection)

2022-07-06 20:42:00 DS brother Bruce Lee

Due to the need of medical development , In many cases , The general thermometer can't meet the requirements of fast and accurate temperature measurement , for example : Station 、 metro 、 Human body temperature measurement is carried out in places with large population density such as airports .

The current design of this infrared non-contact thermometer consists of temperature measurement hardware + The upper computer software is combined , Mainly used in subway 、 Station entrance and other places , It can accurately recognize the face for temperature measurement , If someone's temperature exceeds the standard, it will give a voice prompt and save the current face photo .

1、 Hardware selection and design ideas

(1). Device end

The main control single-chip microcomputer adopts STM32F103C8T6, The human body temperature measurement function adopts the non-contact infrared temperature measurement module .

imgimg

(2). Design idea of upper computer

The upper computer adopts Qt5 Design ,Qt5 It's a set of bases C++ Language cross platform software library , Very powerful performance , At present, many mainstream desktop software uses QT Development . such as : Under Jinshan office -WPS, Byte hopping flag of - Cut and reflect , Blizzard Entertainment company - Multiple game logins, etc .Qt It is also widely used in the field of Internet of vehicles , such as , harvard , tesla , The entire system of the central control screen of many cars, such as BYD, uses Qt Design .

In the temperature measurement project , The upper computer and STM32 Serial port protocol is used for communication between , The upper computer can open the default camera of the laptop , Face detection ; When a face is detected , control STM32 Measure the real-time temperature of the current human body , Then the temperature is transmitted to the upper computer for display ; When the temperature is normal , A green prompt is displayed on the upper computer “ The temperature is normal ”, And there is a voice broadcast , The sound of voice broadcast is generated by the sound card of the notebook . If the temperature is too high , The upper computer displays a red prompt “ Abnormal temperature , Please re measure ”, And there are voice broadcast prompts . When the temperature is too high , Will automatically save the current face photo , The photos are stored in the current software directory “face” Directory , The naming rule for files is “38.8_2022-01-05-22-12-34.jpg”, among 38.8 Indicates the temperature value , Followed by the date ( Mm / DD / yyyy HHM / S ).

(3) The running effect of upper computer

img

img

The upper computer needs to be connected STM32 The temperature data can only be obtained after the equipment , Click the open camera button on the software , Turn on camera , When a face is detected , The current measured temperature... Will be displayed below . If there is no connection STM32 equipment , A normal fixed temperature value will be displayed by default . Red characters on the right side of the interface , Indicates the time taken to process one frame of image , The better the computer performance , The faster the detection .

(4) How to run after getting the executable file ?

Decompress the package first , Get into “ Upper computer of thermometer - Executable file ” Catalog , take “haarcascade_frontalface_alt2.xml” copy to C Packing list .

img

img

Then double click. “FaceTemperatureCheck.exe” Run the program .

img

Device not connected , You can also turn on the camera to detect faces , But the temperature value is a fixed normal temperature range .

Two 、 Host computer design

2.1 Installation and compilation environment

If you need to compile and run the source code yourself , You need to install Qt5 development environment .

Download address : https://download.qt.io/official_releases/qt/5.12/5.12.0/

img

After downloading , First disconnect the computer network ( Otherwise, you will be prompted to enter QT Account number ), Then double click the installation package to install .

Installation can be done by selecting only one MinGW 32 Bit compilers are enough , See the screenshot below for details , choice “MinGW 7.3.0 32-bit” after , Just click next , Then wait for the installation to complete .

img

2.2 The overall effect of software code

If a complete project is required , You can download it here :
https://download.csdn.net/download/xiaolong1126626497/85892490
img

After opening the project ( The suffix of engineering documents is xxx.pro), Click the green triangle button in the lower left corner to compile and run the program .

img

2.3 UI Design interface

img

2.4 Face detection core code

// Face detection code 
bool ImageHandle::opencv_face(QImage qImage)
{
    
    bool check_flag=0;

    QTime time;
    time.start();
    static CvMemStorage* storage = nullptr;
    static CvHaarClassifierCascade* cascade = nullptr;

    // Model file path 
    QString face_model_file = QCoreApplication::applicationDirPath()+"/"+FACE_MODEL_FILE;

    // Load classifier : Frontal face detection 
    cascade = (CvHaarClassifierCascade*)cvLoad(face_model_file.toUtf8().data(), 0, 0, 0 );
    if(!cascade)
    {
    
        qDebug()<<" Classifier loading error .\n";
        return check_flag;
    }

    // Create memory space 
    storage = cvCreateMemStorage(0);

    // Load the image to be detected 
    IplImage* img = QImageToIplImage(&qImage);

    if(img ==nullptr )
    {
    
        qDebug()<<" Picture loading error .\n";
        return check_flag;
    }

    double scale=1.2;

    // Create image header address , And allocate storage space 
    IplImage* gray = cvCreateImage(cvSize(img->width,img->height),8,1);

    // Create image header address , And allocate storage space 
    IplImage* small_img=cvCreateImage(cvSize(cvRound(img->width/scale),cvRound(img->height/scale)),8,1);
    cvCvtColor(img,gray, CV_BGR2GRAY);
    cvResize(gray, small_img, CV_INTER_LINEAR);
    cvEqualizeHist(small_img,small_img); // Histogram equalization 
    /* *  Specify the corresponding face feature detection classifier , You can detect all the faces in the picture , And return the detected face through a rectangle . *  All in all 8 Parameters , Function description :  Parameters 1: Represents the input image , Try to use grayscale images to speed up the detection .  Parameters 2: Express Haar Feature classifier , It can be used cvLoad() Function to load... From disk xml File as Haar Feature classifier .  Parameters 3: The memory cache area used to store the detected candidate targets .  Parameters 4: In two successive scans , The scale factor of the search window . The default is 1.1 That is to say, the search window expands in turn each time 10%  Parameters 5: Represents the minimum number of adjacent rectangles forming the detection target ( The default is 3 individual ). If the sum of the number of small rectangles constituting the detection target is less than  min_neighbors - 1  Will be excluded . If min_neighbors  by  0,  Then the function returns all checked candidate rectangles without any operation , This setting value is generally used in the user-defined combination program of test results .  Parameters 6: Either use the default , Or use CV_HAAR_DO_CANNY_PRUNING, If set to CV_HAAR_DO_CANNY_PRUNING, So the function will use Canny Edge detection to exclude areas with too many or too few edges , Therefore, these areas are usually not the area where the face is located .  Parameters 7: Indicates the minimum value of the detection window , Generally, it can be set as the default .  Parameters 8: Indicates the maximum value of the detection window , Generally, it can be set as the default .  Function return value : Function will return CvSeq object , This object contains a series of CvRect Represents the detected face rectangle . */
    CvSeq* objects = cvHaarDetectObjects(small_img,
                                           cascade,
                                           storage,
                                           1.1,
                                           3,
                                           0/*CV_HAAR_DO_CANNY_PRUNING*/,
                                           cvSize(50,50)/* Size determines how much time it takes to detect */);

    qDebug()<<" Number of faces :"<<objects->total;

    // Traverse to find the object and the surrounding painting box 
    QPainter painter(&qImage);// structure  QPainter  Drawing objects 
    QPen pen;
    pen.setColor(Qt::blue); // Brush color 
    pen.setWidth(5); // The width of the brush 
    painter.setPen(pen); // Set brush 

    CvRect *max=nullptr;

    for(int i=0;i<(objects->total);++i)
    {
    
        // Get the coordinate position, width and height information of the face 
        CvRect* r=(CvRect*)cvGetSeqElem(objects,i);

        if(max==nullptr)max=r;
        else
        {
    
            if(r->width > max->width || r->height > max->height)
            {
    
                max=r;
            }
        }
    }

    // If you find the biggest target face 
    if(max!=nullptr)
    {
    
        check_flag=true;
        // Draw a rectangle around the face area 
        painter.drawRect(max->x*scale,max->y*scale,max->width*scale,max->height*scale);
    }

    cvReleaseImage(&gray);  // Free picture memory 
    cvReleaseImage(&small_img);  // Free picture memory 
    cvReleaseHaarClassifierCascade(&cascade); // Free memory --> classifier 
    cvReleaseMemStorage(&objects->storage); // Free memory --> Detect all the faces in the picture 

    // Release picture 
    cvReleaseImage(&img);

    qint32 time_ms=0;
    time_ms=time.elapsed();

    // Time consuming 
    emit ss_log_text(QString("%1").arg(time_ms));

    // Save results 
    m_image=qImage.copy();

    return check_flag;
}

2.5 The configuration file ( Modify the parameters - Very important )

img

Parameter description :

If there are multiple cameras on the computer , You can modify the camera number in the configuration file , The specific quantity will be automatically queried when the program starts , Print the code to the terminal .

If you compile and run the source code for the first time , After running ,

(1) You need to add the software source code in the directory “haarcascade_frontalface_alt2.xml” File copy to C Packing list , Or other non Chinese directories , The specific path can be modified in the configuration file , The default is C Packing list .

(2) You need to add the software source code in the directory “OpenCV-MinGW-Build-OpenCV-3.4.7\x86\mingw\bin” Copy all files in the directory to , The generated program execution file is in the same level directory .

Only in this way can the program run normally .

Threshold range of alarm temperature , You can also change , There are descriptions in the configuration file .

2.6 Voice prompt file and background image

Voice prompt file , The background image is loaded through the resource file .

The source file is stored in , Source code “FaceTemperatureCheck\res” Under the table of contents .

img

You can also replace yourself , Recompile the program to take effect .

2.7 Voice broadcast and image display processing code

// The result of image processing 
void Widget::slot_HandleImage(bool flag,QImage image)
{
    
    bool temp_state=0;

    // Face detected 
    if(flag)
    {
    
        // Judge whether the temperature is normal 
        if(current_temp<MAX_TEMP && current_temp>MIN_TEMP)
        {
    
            temp_state=true;
            // The display temperature is normal 
            ui->label_temp->setStyleSheet("color: rgb(0, 255, 127);font: 20pt \"Arial\";");
            ui->label_temp->setText(QString("%1℃").arg(current_temp));
        }
        else // Voice Announcements , Abnormal temperature 
        {
    
            temp_state=false;
            // Display abnormal temperature 
            ui->label_temp->setStyleSheet("color: rgb(255, 0, 0);font: 20pt \"Arial\";");
            ui->label_temp->setText(QString("%1℃").arg(current_temp));
        }

        // Get current ms Time 
        long long currentTime = QDateTime::currentDateTime().toMSecsSinceEpoch();

        // Determine whether the time interval has arrived 
        if(currentTime-old_currentTime>AUDIO_RATE_MS)
        {
    
            // Change the current time 
            old_currentTime=currentTime;
            // The temperature is normal 
            if(temp_state)
            {
    
                // Voice Announcements , The temperature is normal 
                QSound::play(":/res/ok.wav");
            }
            // Abnormal temperature 
            else
            {
    
                // Voice Announcements , Abnormal temperature 
                QSound::play(":/res/error.wav");

                // Photo retention 
                QString dir_str = QCoreApplication::applicationDirPath()+"/face";

                // Check that the directory exists , If not, create a new 
                QDir dir;
                if (!dir.exists(dir_str))
                {
    
                    bool res = dir.mkpath(dir_str);
                    qDebug() << " New directory status :" << res;
                }

                // Save the pictures when the directory exists 
                QDir dir2;
                if (dir2.exists(dir_str))
                {
    
                    // Splice name 
                    QDateTime dateTime(QDateTime::currentDateTime());
                    // Time effect : 2020-03-05 16:25::04  Monday 
                    QString qStr=QString("%1/%2_").arg(dir_str).arg(current_temp);
                    qStr+=dateTime.toString("yyyy-MM-dd-hh-mm-ss-ddd");
                    image.save(qStr+".jpg");
                }
            }
        }
    }
    else  // Do not display temperature 
    {
    
        ui->label_temp->setStyleSheet("color: rgb(0, 255, 127);font: 20pt \"Arial\";");
        ui->label_temp->setText("----");
    }

    // The result screen of the processing image 
    ui->widget_player->slotGetOneFrame(image);
}

2.8 STM32 Temperature receiving and processing code

// Refresh the serial port 
void Widget::on_pushButton_flush_uart_clicked()
{
    
    QList<QSerialPortInfo> UartInfoList=QSerialPortInfo::availablePorts(); // Get the available serial port information 
    ui->comboBox_ComSelect->clear();
    if(UartInfoList.count()>0)
    {
    
        for(int i=0;i<UartInfoList.count();i++)
        {
    
             if(UartInfoList.at(i).isBusy()) // If the current serial port  COM  If you are busy, you will return to the truth , Otherwise return false 
             {
    
                   QString info=UartInfoList.at(i).portName();
                   info+="( Occupy )";
                   ui->comboBox_ComSelect->addItem(info); // Add new entry options 
             }
             else
             {
    
                  ui->comboBox_ComSelect->addItem(UartInfoList.at(i).portName()); // Add new entry options 
             }
        }
    }
    else
    {
    
        ui->comboBox_ComSelect->addItem(" No available COM mouth "); // Add new entry options 
    }
}

// Connect the temperature measuring equipment 
void Widget::on_pushButton_OpenUart_clicked()
{
    
    if(ui->pushButton_OpenUart->text()==" Connect the temperature measuring equipment ")  // Open the serial port 
    {
    
        ui->pushButton_OpenUart->setText(" disconnect ");

        /* Configure serial port information */
        UART_Config->setPortName(ui->comboBox_ComSelect->currentText());  //COM The name of 
        if(!(UART_Config->open(QIODevice::ReadWrite)))      // Open attribute permissions 
        {
    
            QMessageBox::warning(this, tr(" Status hint "),
                                           tr(" Device connection failed !\n Please choose the right COM mouth "),
                                           QMessageBox::Ok);
                ui->pushButton_OpenUart->setText(" Connect the temperature measuring equipment ");
                return;
        }
    }
    else // Turn off the serial port 
    {
    
        ui->pushButton_OpenUart->setText(" Connect the temperature measuring equipment ");
        /* Turn off the serial port -*/
        UART_Config->clear(QSerialPort::AllDirections);
        UART_Config->close();
    }
}

// Read the signal 
void Widget::ReadUasrtData()
{
    
    /* Returns the number of readable bytes */
    if(UART_Config->bytesAvailable()<=0)
    {
    
        return;
    }

    /* Define byte array */
    QByteArray rx_data;

    /* Read all data in the serial port buffer */
    rx_data=UART_Config->readAll();

    // Conversion temperature 
    current_temp=rx_data.toDouble();
}
原网站

版权声明
本文为[DS brother Bruce Lee]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/187/202207061239113208.html