266 lines
8.1 KiB
C++
266 lines
8.1 KiB
C++
|
#include "yolo.h"
|
|||
|
#include "kalmanboxtracker.h"
|
|||
|
#include <iostream>
|
|||
|
#include <opencv2/opencv.hpp>
|
|||
|
#include <vector>
|
|||
|
#include <time.h>
|
|||
|
#include "sort.h"
|
|||
|
using namespace std;
|
|||
|
using namespace cv;
|
|||
|
using namespace cv::dnn;
|
|||
|
|
|||
|
int main()
|
|||
|
{
|
|||
|
string img_path = "D:/VS/yoloSORT/images/test.mp4";
|
|||
|
string model_path = "D:/VS/yoloSORT/models/yolov5s.onnx";
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD>Yolov5ģ<35>ͺ<CDBA><CDB8><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Yolov5 yolo;
|
|||
|
Net net;
|
|||
|
Sort mot_tracker = Sort(1, 3, 0.3); // <20><><EFBFBD><EFBFBD>Sort<72><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
// <20><>ȡYoloģ<6F><C4A3>
|
|||
|
if (!yolo.readModel(net, model_path, true)) {
|
|||
|
cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Yoloģ<EFBFBD><EFBFBD>" << endl;
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧһ<D3A6><D2BB><EFBFBD><EFBFBD>ɫ
|
|||
|
vector<Scalar> colors;
|
|||
|
srand(42); // <20>̶<EFBFBD><CCB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD>ȷ<EFBFBD><C8B7>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫһ<C9AB><D2BB>
|
|||
|
for (int i = 0; i < 80; i++) { // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>80<38><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
int b = rand() % 256;
|
|||
|
int g = rand() % 256;
|
|||
|
int r = rand() % 256;
|
|||
|
colors.push_back(Scalar(b, g, r));
|
|||
|
}
|
|||
|
|
|||
|
// <20><>ȡ<EFBFBD><C8A1>Ƶ
|
|||
|
VideoCapture cap(img_path);
|
|||
|
if (!cap.isOpened()) {
|
|||
|
cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>ļ<EFBFBD>" << endl;
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
VideoWriter writer;
|
|||
|
writer = VideoWriter("D:/VS/yoloSORT/images/detect.mp4", CAP_OPENCV_MJPEG, 20, Size(2560, 1440), true);
|
|||
|
|
|||
|
clock_t start, end; //<2F><>ʱ<EFBFBD><CAB1>
|
|||
|
start = clock();
|
|||
|
int num = 0;
|
|||
|
|
|||
|
Mat frame;
|
|||
|
int frame_counter = 0;
|
|||
|
int detect_interval = 3; // ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD><D6A1><EFBFBD>µ<EFBFBD><C2B5><EFBFBD>һ<EFBFBD><D2BB>YOLO<4C><4F><EFBFBD>м<EFBFBD><D0BC><EFBFBD>
|
|||
|
vector<Rect> detection_rects;
|
|||
|
|
|||
|
while (cap.read(frame)) {
|
|||
|
cap >> frame;
|
|||
|
|
|||
|
if (frame.empty()) {
|
|||
|
cout << "<EFBFBD><EFBFBD>Ƶ<EFBFBD>ѽ<EFBFBD><EFBFBD><EFBFBD>" << endl;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
vector<Output> result;
|
|||
|
|
|||
|
// ÿ<><C3BF> detect_interval ֡<><D6A1><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> YOLO <20><><EFBFBD><EFBFBD>
|
|||
|
if (frame_counter % detect_interval == 0) {
|
|||
|
detection_rects.clear(); // <20><><EFBFBD><EFBFBD>֮ǰ<D6AE>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if (yolo.Detect(frame, net, result)) {
|
|||
|
for (int i = 0; i < result.size(); i++) {
|
|||
|
int x = result[i].box.x;
|
|||
|
int y = result[i].box.y;
|
|||
|
int w = result[i].box.width;
|
|||
|
int h = result[i].box.height;
|
|||
|
Rect rect(x, y, w, h);
|
|||
|
detection_rects.push_back(rect);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݸ<EFBFBD> SORT <20><><EFBFBD>г<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
vector<vector<float>> trackers = mot_tracker.update(detection_rects);
|
|||
|
// <20><><EFBFBD>Ƹ<EFBFBD><C6B8>ٽ<EFBFBD><D9BD><EFBFBD>
|
|||
|
for (int i = 0; i < trackers.size(); i++) {
|
|||
|
Rect rect(trackers[i][0], trackers[i][1], trackers[i][2] - trackers[i][0], trackers[i][3] - trackers[i][1]);
|
|||
|
|
|||
|
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŷ<EFBFBD>
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFA3AC><EFBFBD>Ǽ<EFBFBD><C7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŷ<EFBFBD>û<EFBFBD>б仯
|
|||
|
int class_id = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ID Ϊ 0<><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>
|
|||
|
float confidence = 0.8f; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŷ<EFBFBD>Ϊ 0.8<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD>
|
|||
|
|
|||
|
// ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>л<EFBFBD>ȡ<EFBFBD><C8A1>ɫ
|
|||
|
Scalar color = colors[class_id % colors.size()]; // ʹ<><CAB9><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>е<EFBFBD><D0B5><EFBFBD>ɫ
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǩ<EFBFBD><C7A9><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> + <20><><EFBFBD>Ŷ<EFBFBD>
|
|||
|
string label = "box";
|
|||
|
|
|||
|
// <20><><EFBFBD>ƾ<EFBFBD><C6BE>ο<EFBFBD><CEBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǩ
|
|||
|
rectangle(frame, rect, color, 2); // <20><><EFBFBD>ƾ<EFBFBD><C6BE>ο<EFBFBD>
|
|||
|
putText(frame, label, Point(rect.x, rect.y), FONT_HERSHEY_SIMPLEX, 1, color, 2); // <20><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƺ<EFBFBD><C6BA><EFBFBD><EFBFBD>Ŷ<EFBFBD>
|
|||
|
}
|
|||
|
}
|
|||
|
else {
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǽ<EFBFBD><C7BC><EFBFBD>֡<EFBFBD><D6A1>ʹ<EFBFBD><CAB9> SORT <20><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD><CDB8><EFBFBD>
|
|||
|
vector<vector<float>> trackers = mot_tracker.update(detection_rects);
|
|||
|
|
|||
|
// <20><><EFBFBD>Ƹ<EFBFBD><C6B8>ٽ<EFBFBD><D9BD><EFBFBD>
|
|||
|
for (int i = 0; i < trackers.size(); i++) {
|
|||
|
Rect rect(trackers[i][0], trackers[i][1], trackers[i][2] - trackers[i][0], trackers[i][3] - trackers[i][1]);
|
|||
|
|
|||
|
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŷ<EFBFBD>
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFA3AC><EFBFBD>Ǽ<EFBFBD><C7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŷ<EFBFBD>û<EFBFBD>б仯
|
|||
|
int class_id = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ID Ϊ 0<><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>
|
|||
|
float confidence = 0.8f; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŷ<EFBFBD>Ϊ 0.8<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD>
|
|||
|
|
|||
|
// ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>л<EFBFBD>ȡ<EFBFBD><C8A1>ɫ
|
|||
|
Scalar color = colors[class_id % colors.size()]; // ʹ<><CAB9><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>е<EFBFBD><D0B5><EFBFBD>ɫ
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǩ<EFBFBD><C7A9><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> + <20><><EFBFBD>Ŷ<EFBFBD>
|
|||
|
string label = "box";
|
|||
|
|
|||
|
// <20><><EFBFBD>ƾ<EFBFBD><C6BE>ο<EFBFBD><CEBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǩ
|
|||
|
rectangle(frame, rect, color, 2); // <20><><EFBFBD>ƾ<EFBFBD><C6BE>ο<EFBFBD>
|
|||
|
putText(frame, label, Point(rect.x, rect.y), FONT_HERSHEY_SIMPLEX, 1, color, 2); // <20><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƺ<EFBFBD><C6BA><EFBFBD><EFBFBD>Ŷ<EFBFBD>
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// <20><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡
|
|||
|
imshow("img", frame);
|
|||
|
writer << frame;
|
|||
|
|
|||
|
if (waitKey(10) == 27) {
|
|||
|
break; // <20>˳<EFBFBD>ѭ<EFBFBD><D1AD>
|
|||
|
}
|
|||
|
|
|||
|
frame_counter++;
|
|||
|
num++;
|
|||
|
}
|
|||
|
|
|||
|
end = clock();
|
|||
|
cout << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl; // <20><><EFBFBD><EFBFBD>ʱ<EFBFBD>䣨<EFBFBD><E4A3A8>λ<EFBFBD><CEBB>s<EFBFBD><73>
|
|||
|
cout << "frame num: " << num << endl;
|
|||
|
cout << "Speed = " << double(end - start) * 1000 / CLOCKS_PER_SEC / num << "ms" << endl; // <20><><EFBFBD><EFBFBD>ʱ<EFBFBD>䣨<EFBFBD><E4A3A8>λ<EFBFBD><CEBB>ms<6D><73>
|
|||
|
|
|||
|
cap.release();
|
|||
|
destroyAllWindows();
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
#include "yolo.h"
|
|||
|
#include "kalmanboxtracker.h"
|
|||
|
#include <iostream>
|
|||
|
#include <opencv2/opencv.hpp>
|
|||
|
#include <vector>
|
|||
|
#include <time.h>
|
|||
|
#include "sort.h"
|
|||
|
using namespace std;
|
|||
|
using namespace cv;
|
|||
|
using namespace cv::dnn;
|
|||
|
|
|||
|
int main()
|
|||
|
{
|
|||
|
string img_path = "D:/VS/yoloTest/images/1.mp4";
|
|||
|
string model_path = "D:/VS/yoloTest/models/yolov5s.onnx";
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD>Yolov5ģ<35>ͺ<CDBA><CDB8><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Yolov5 yolo;
|
|||
|
Net net;
|
|||
|
Sort mot_tracker = Sort(1, 3, 0.3); // <20><><EFBFBD><EFBFBD>Sort<72><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
// <20><>ȡYoloģ<6F><C4A3>
|
|||
|
if (!yolo.readModel(net, model_path, true)) {
|
|||
|
cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Yoloģ<EFBFBD><EFBFBD>" << endl;
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ
|
|||
|
srand(time(0));
|
|||
|
vector<Scalar> colors;
|
|||
|
for (int i = 0; i < 80; i++) {
|
|||
|
int b = rand() % 256;
|
|||
|
int g = rand() % 256;
|
|||
|
int r = rand() % 256;
|
|||
|
colors.push_back(Scalar(b, g, r));
|
|||
|
}
|
|||
|
|
|||
|
// <20><>ȡ<EFBFBD><C8A1>Ƶ
|
|||
|
VideoCapture cap(img_path);
|
|||
|
if (!cap.isOpened()) {
|
|||
|
cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>ļ<EFBFBD>" << endl;
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
VideoWriter writer;
|
|||
|
writer = VideoWriter("D:/VS/yoloTest/images/test.mp4", CAP_OPENCV_MJPEG, 20, Size(2560, 1440), true);
|
|||
|
|
|||
|
clock_t start, end; //<2F><>ʱ<EFBFBD><CAB1>
|
|||
|
start = clock();
|
|||
|
int num = 0;
|
|||
|
|
|||
|
Mat frame;
|
|||
|
while (cap.read(frame)) {
|
|||
|
cap >> frame;
|
|||
|
|
|||
|
if (frame.empty()) {
|
|||
|
cout << "<EFBFBD><EFBFBD>Ƶ<EFBFBD>ѽ<EFBFBD><EFBFBD><EFBFBD>" << endl;
|
|||
|
break;
|
|||
|
}
|
|||
|
// <20><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
vector<Output> result;
|
|||
|
if (yolo.Detect(frame, net, result)) {
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѽ<EFBFBD><D1BC><EFBFBD><E2B5BD>Ŀ<EFBFBD><C4BF>
|
|||
|
vector<Rect> detection_rects; // <20>洢<EFBFBD><E6B4A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><C4BE>ο<EFBFBD>
|
|||
|
for (int i = 0; i < result.size(); i++) {
|
|||
|
int x = result[i].box.x;
|
|||
|
int y = result[i].box.y;
|
|||
|
int w = result[i].box.width;
|
|||
|
int h = result[i].box.height;
|
|||
|
Rect rect(x, y, w, h);
|
|||
|
detection_rects.push_back(rect);
|
|||
|
}
|
|||
|
// <20><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
vector<vector<float>> trackers = mot_tracker.update(detection_rects);//x,y,w,h,id
|
|||
|
// <20><><EFBFBD>Ƹ<EFBFBD><C6B8>ٽ<EFBFBD><D9BD><EFBFBD>
|
|||
|
for (int i = 0; i < trackers.size(); i++) {
|
|||
|
Rect rect(trackers[i][0], trackers[i][1], trackers[i][2] - trackers[i][0], trackers[i][3] - trackers[i][1]);
|
|||
|
//cout << "0:" << trackers[i][0] << endl; //<2F><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD> x <20><><EFBFBD>꣨<EFBFBD><EAA3A8><EFBFBD>Ͻǵ<CFBD> x <20><><EFBFBD>꣩<EFBFBD><EAA3A9>
|
|||
|
//cout << "1:" << trackers[i][1] << endl; //<2F><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD> y <20><><EFBFBD>꣨<EFBFBD><EAA3A8><EFBFBD>Ͻǵ<CFBD> y <20><><EFBFBD>꣩<EFBFBD><EAA3A9>
|
|||
|
//cout << "2:" << trackers[i][2] << endl; //<2F><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD>Ŀ<EFBFBD><C4BF>ȡ<EFBFBD>
|
|||
|
//cout << "3:" << trackers[i][3] << endl; //<2F><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD>ĸ߶ȡ<DFB6>
|
|||
|
//cout << "4:" << trackers[i][4] << endl; //<2F><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD> ID<49><44>
|
|||
|
int id = static_cast<int>(trackers[i][4]);
|
|||
|
//cout << "id:" << id << endl;
|
|||
|
//string label = yolo.className[result[id].id] + ":" + to_string(result[id].confidence);
|
|||
|
rectangle(frame, rect, Scalar(0, 255, 0), 2);
|
|||
|
cout << trackers[i][5] << endl;
|
|||
|
putText(frame, "id:" + to_string(int(trackers[i][4])), Point(rect.x, rect.y), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 255, 0), 2);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
imshow("img", frame);
|
|||
|
writer << frame;
|
|||
|
if (waitKey(10) == 27) {
|
|||
|
break; // <20>˳<EFBFBD>ѭ<EFBFBD><D1AD>
|
|||
|
}
|
|||
|
|
|||
|
num++;
|
|||
|
}
|
|||
|
|
|||
|
end = clock();
|
|||
|
cout << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl; //<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD>䣨<EFBFBD><E4A3A8>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
cout << "frame num: " << num << endl;
|
|||
|
cout << "Speed = " << double(end - start) * 1000 / CLOCKS_PER_SEC / num << "ms" << endl; //<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD>䣨<EFBFBD><E4A3A8>λ<EFBFBD><CEBB>m<EFBFBD><6D><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
cap.release();
|
|||
|
destroyAllWindows();
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
*/
|