微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Windows 窗体 - C++/CLR (.NET Framework) - 如何使用按钮事件

如何解决Windows 窗体 - C++/CLR (.NET Framework) - 如何使用按钮事件

我正在构建一个应用程序,该应用程序使用计算机视觉通过网络摄像头检测对象。

  1. 为了实现这个想法,我使用了 OpenCV 库和 C++。
  2. 为了构建 Windows 窗体,我将 C++/CLR (.NET Framework) 与 Visual Studio 2019 结合使用。

我已经让程序运行起来,但我想改进我的代码

我的问题简介:
我想在“按钮事件”中编写更少和更高效的代码,您可以在“代码 1”中看到。这样做的原因,是因为我几乎对所有三个按钮都使用了相同的代码(它占用了大量空间并且很丑陋)。

我的想法是围绕您可以在按钮事件中看到的代码构建一个类,并在每个按钮事件中创建该类的实例。问题是,我还需要能够按下退出按钮并控制我在 CODE 1 中的成员变量。

CODE 1中的三个私有成员变量如下:

    //// private member variables
    private:
        bool CamWhileLoop1;
        bool CamWhileLoop2;
        bool CamWhileLoop3;

我使用它们在每个按钮事件中打开和关闭 while 循环,以便在按下新事件时关闭网络摄像头窗口。

(当您按下三个按钮之一时,网络摄像头窗口由 OpenCV 库提供)。

我的问题:

  1. 实现这一目标的最佳和最有效方法是什么。
  2. 这样好吗?
  3. 我正在使用 OpenCV 库中已训练的 Haar Cascade 文件来检测对象。我的程序很慢,网络摄像头滞后很多。如何摆脱这种滞后? (我想我需要使用 YOLO 或人工智能 (AI) 部分的其他一些实现,但我不确定)
  4. 这样好吗?我是否需要在按下另一个按钮事件时自行关闭一个事件,还是在 C++/CLR 库中自动发生?

CODE 1 和 CODE 2 如下。

enter image description here

代码 1:这是我的“Windows 窗体代码”,名为 MyForm.h

#pragma once

// Include OpenCV
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
// Include C++ libraries
#include <iostream>
#include <thread>
#include <chrono>
#include <vector>

//#include <opencv2/opencv.hpp>


namespace ObjectCounter {

    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;

    /// <summary>
    /// Summary for MyForm
    /// </summary>
    public ref class MyForm : public System::Windows::Forms::Form
    {
    public:
        MyForm(void)
        {
            InitializeComponent();
            //
            //Todo: Add the constructor code here
            //
        }

    protected:
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        ~MyForm()
        {
            if (components)
            {
                delete components;
            }
        }
    
    protected:

    //// private member variables
    private:
        bool CamWhileLoop1;
        bool CamWhileLoop2;
        bool CamWhileLoop3;

    private: System::Windows::Forms::Label^ label1;
    private: System::Windows::Forms::Label^ label2;
    private: System::Windows::Forms::Button^ button1;
    private: System::Windows::Forms::Button^ button2;
    private: System::Windows::Forms::Button^ button3;
    private: System::Windows::Forms::Button^ button4;

    private:
        /// <summary>
        /// required designer variable.
        /// </summary>
        System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
        /// <summary>
        /// required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        void InitializeComponent(void)
        {
            this->button1 = (gcnew System::Windows::Forms::Button());
            this->label1 = (gcnew System::Windows::Forms::Label());
            this->label2 = (gcnew System::Windows::Forms::Label());
            this->button2 = (gcnew System::Windows::Forms::Button());
            this->button3 = (gcnew System::Windows::Forms::Button());
            this->button4 = (gcnew System::Windows::Forms::Button());
            this->SuspendLayout();
            // 
            // button1
            // 
            this->button1->Location = System::Drawing::Point(113,64);
            this->button1->Name = L"button1";
            this->button1->Size = System::Drawing::Size(459,65);
            this->button1->TabIndex = 0;
            this->button1->Text = L"Count Faces";
            this->button1->UseVisualStyleBackColor = true;
            this->button1->Click += gcnew System::EventHandler(this,&MyForm::button1_Click);
            // 
            // label1
            // 
            this->label1->AutoSize = true;
            this->label1->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif",20,System::Drawing::FontStyle::Regular,System::Drawing::GraphicsUnit::Point,static_cast<System::Byte>(0)));
            this->label1->Location = System::Drawing::Point(83,422);
            this->label1->Name = L"label1";
            this->label1->Size = System::Drawing::Size(297,39);
            this->label1->TabIndex = 1;
            this->label1->Text = L"Amount of objects:";
            // 
            // label2
            // 
            this->label2->AutoSize = true;
            this->label2->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif",30,static_cast<System::Byte>(0)));
            this->label2->Location = System::Drawing::Point(477,403);
            this->label2->Name = L"label2";
            this->label2->Size = System::Drawing::Size(53,58);
            this->label2->TabIndex = 2;
            this->label2->Text = L"0";
            this->label2->Click += gcnew System::EventHandler(this,&MyForm::label2_Click);
            // 
            // button2
            // 
            this->button2->Location = System::Drawing::Point(113,135);
            this->button2->Name = L"button2";
            this->button2->Size = System::Drawing::Size(459,65);
            this->button2->TabIndex = 3;
            this->button2->Text = L"Count Eyes";
            this->button2->UseVisualStyleBackColor = true;
            this->button2->Click += gcnew System::EventHandler(this,&MyForm::button2_Click);
            // 
            // button3
            // 
            this->button3->Location = System::Drawing::Point(113,206);
            this->button3->Name = L"button3";
            this->button3->Size = System::Drawing::Size(459,65);
            this->button3->TabIndex = 4;
            this->button3->Text = L"Count Russian License Plates";
            this->button3->UseVisualStyleBackColor = true;
            this->button3->Click += gcnew System::EventHandler(this,&MyForm::button3_Click);
            // 
            // button4
            // 
            this->button4->Location = System::Drawing::Point(240,301);
            this->button4->Name = L"button4";
            this->button4->Size = System::Drawing::Size(214,39);
            this->button4->TabIndex = 5;
            this->button4->Text = L"Exit";
            this->button4->UseVisualStyleBackColor = true;
            this->button4->Click += gcnew System::EventHandler(this,&MyForm::button4_Click);
            // 
            // MyForm
            // 
            this->AutoScaleDimensions = System::Drawing::Sizef(8,16);
            this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
            this->ClientSize = System::Drawing::Size(680,560);
            this->Controls->Add(this->button4);
            this->Controls->Add(this->button3);
            this->Controls->Add(this->button2);
            this->Controls->Add(this->label2);
            this->Controls->Add(this->label1);
            this->Controls->Add(this->button1);
            this->Name = L"MyForm";
            this->Text = L"Artificial Intelligence Counter";
            this->ResumeLayout(false);
            this->Performlayout();

        }
#pragma endregion


    private: System::Void label2_Click(System::Object^ sender,System::EventArgs^ e) {
    }


    private: System::Void button1_Click(System::Object^ sender,System::EventArgs^ e) { // Count Faces
        //Initialize variables
        unsigned int ObjectCounter1 = 0;
        this->CamWhileLoop1 = true;
        this->CamWhileLoop2 = false;
        this->CamWhileLoop3 = false;


        cv::VideoCapture Video_Capture1(0); // Create an instance of the cv::VideoCapture class
        cv::Mat image1;                     // Create an instance of the cv:Mat class (creating an empty image)
        cv::CascadeClassifier faceCascade1; // Create an instance of the cv::CascadeClassifier class
        faceCascade1.load("Resources/haarcascade_frontalface_alt.xml"); // Load haar cascade file

        if (!Video_Capture1.isOpened()) {   // Check if camera opened successfully
            std::cout << "Error opening video stream or file" << std::endl;
            //return -1;
        }

        if (faceCascade1.empty()) {         // Check if the XML file has been loaded properly or not
            std::cout << "XML file not loaded." << std::endl;
        }

        std::vector<cv::Rect> Rectangles_for_objects1;  // Storing rectangles in a vector 

        std::this_thread::sleep_for(std::chrono::milliseconds(200)); //Giving the webcam time to start

        while (this->CamWhileLoop1) {
            Video_Capture1.read(image1);    //Create matrix from the webcam
            faceCascade1.detectMultiScale(image1,Rectangles_for_objects1,1.1,10);

            for (int i = 0; i < Rectangles_for_objects1.size(); i++) {  // Iterate over all objects and print them
                //Code for rectangle around faces
                cv::rectangle(image1,Rectangles_for_objects1[i].tl(),Rectangles_for_objects1[i].br(),cv::Scalar(255,255),3);
                //tl = top left and br = bottom right
            }
            
            // For the counter part
            if (Rectangles_for_objects1.size() != ObjectCounter1) {
                if (Rectangles_for_objects1.size() == 0) {
                    std::cout << "There is no person in the image" << std::endl;
                }
                else if (Rectangles_for_objects1.size() == 1) {
                    std::cout << "There is " << Rectangles_for_objects1.size() << " person in the image" << std::endl;
                }
                else {
                    std::cout << "There are " << Rectangles_for_objects1.size() << " persons in the image" << std::endl;
                }
                ObjectCounter1 = Rectangles_for_objects1.size();
                label2->Text = ObjectCounter1.ToString();
            }
            cv::imshow("Video",image1);
            cv::waitKey(1);

        }
        //Show the image in a window. name of the window="Video". The Image to be shown= img (p.209)

    }
    
private: System::Void button2_Click(System::Object^ sender,System::EventArgs^ e) {
    //Initialize variables
    unsigned int ObjectCounter2 = 0;
    this->CamWhileLoop1 = false;
    this->CamWhileLoop2 = true;
    this->CamWhileLoop3 = false;

    cv::VideoCapture Video_Capture2(0); // Create an instance of the cv::VideoCapture class
    cv::Mat image2;                     // Create an instance of the cv:Mat class (creating an empty image)
    cv::CascadeClassifier faceCascade2; // Create an instance of the cv::CascadeClassifier class
    faceCascade2.load("Resources/haarcascade_eye_tree_eyeglasses.xml"); // Load haar cascade file

    if (!Video_Capture2.isOpened()) {   // Check if camera opened successfully
        std::cout << "Error opening video stream or file" << std::endl;
        //return -1;
    }

    if (faceCascade2.empty()) {         // Check if the XML file has been loaded properly or not
        std::cout << "XML file not loaded." << std::endl;
    }

    std::vector<cv::Rect> Rectangles_for_objects2;  // Storing rectangles in a vector 

    std::this_thread::sleep_for(std::chrono::milliseconds(200)); //Giving the webcam time to start

    while (this->CamWhileLoop2) {
        Video_Capture2.read(image2);
        faceCascade2.detectMultiScale(image2,Rectangles_for_objects2,10);

        //if(Main_Window.textBox1->Text )

        for (int i = 0; i < Rectangles_for_objects2.size(); i++) {  // Iterate over all objects and print them
            //Code for rectangle around faces
            cv::rectangle(image2,Rectangles_for_objects2[i].tl(),Rectangles_for_objects2[i].br(),3);
            //tl = top left
            //br = bottom right
        }

        // For the counter part
        if (Rectangles_for_objects2.size() != ObjectCounter2) {
            if (Rectangles_for_objects2.size() == 0) {
                std::cout << "There is no person in the image" << std::endl;
            }
            else if (Rectangles_for_objects2.size() == 1) {
                std::cout << "There is " << Rectangles_for_objects2.size() << " person in the image" << std::endl;
            }
            else {
                std::cout << "There are " << Rectangles_for_objects2.size() << " persons in the image" << std::endl;
            }
            ObjectCounter2 = Rectangles_for_objects2.size();
            label2->Text = ObjectCounter2.ToString();
        }

        //Show the image in a window. name of the window="Video". The Image to be shown= img (p.209)
        cv::imshow("Video",image2);
        cv::waitKey(1);
    }
}
private: System::Void button3_Click(System::Object^ sender,System::EventArgs^ e) {
    //Initialize variables
    unsigned int ObjectCounter3 = 0;
    this->CamWhileLoop1 = false;
    this->CamWhileLoop2 = false;
    this->CamWhileLoop3 = true;


    cv::VideoCapture Video_Capture(0);  // Create an instance of the cv::VideoCapture class
    cv::Mat image;                      // Create an instance of the cv:Mat class (creating an empty image)
    cv::CascadeClassifier faceCascade;  // Create an instance of the cv::CascadeClassifier class
    faceCascade.load("Resources/haarcascade_russian_plate_number.xml"); // Load haar cascade file

    if (!Video_Capture.isOpened()) {    // Check if camera opened successfully
        std::cout << "Error opening video stream or file" << std::endl;
        //return -1;
    }

    if (faceCascade.empty()) {          // Check if the XML file has been loaded properly or not
        std::cout << "XML file not loaded." << std::endl;
    }

    std::vector<cv::Rect> Rectangles_for_objects;   // Storing rectangles in a vector 

    std::this_thread::sleep_for(std::chrono::milliseconds(200)); //Giving the webcam time to start

    while (this->CamWhileLoop3) {
        Video_Capture.read(image);
        faceCascade.detectMultiScale(image,Rectangles_for_objects,10);

        //if(Main_Window.textBox1->Text )

        for (int i = 0; i < Rectangles_for_objects.size(); i++) {   // Iterate over all objects and print them
            //Code for rectangle around faces
            cv::rectangle(image,Rectangles_for_objects[i].tl(),Rectangles_for_objects[i].br(),3);
            //tl = top left
            //br = bottom right
        }

        // For the counter part
        if (Rectangles_for_objects.size() != ObjectCounter3) {
            if (Rectangles_for_objects.size() == 0) {
                std::cout << "There is no person in the image" << std::endl;
            }
            else if (Rectangles_for_objects.size() == 1) {
                std::cout << "There is " << Rectangles_for_objects.size() << " person in the image" << std::endl;
            }
            else {
                std::cout << "There are " << Rectangles_for_objects.size() << " persons in the image" << std::endl;
            }
            ObjectCounter3 = Rectangles_for_objects.size();
            label2->Text = ObjectCounter3.ToString();
        }

        //Show the image in a window. name of the window="Video". The Image to be shown= img (p.209)
        cv::imshow("Video",image);
        cv::waitKey(1);
    }
}
private: System::Void button4_Click(System::Object^ sender,System::EventArgs^ e) {
    this->CamWhileLoop1 = false;
    this->CamWhileLoop2 = false;
    this->CamWhileLoop3 = false;

    this->Close();
}
};
}

代码 2:这是我的“源代码”,名为 Source.cpp

#include "MyForm.h"
using namespace ObjectCounter;
[STAThreadAttribute]

int main()
{
    MyForm MainWindow;
    MainWindow.ShowDialog();

    return 0;
}

感谢您阅读问题!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。