/
RDA
/
STZ
Обзор
Документация
Войти
/
RDA
/
STZ
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
lab6/lab6_detect_video.cpp
143 строки
5 KB
daniil rybyakov
pre show changes
11 мар 2025, 13:36
11 мар 2025, 13:36
e0a96e9
Код
Авторство
О чём код?
#include <opencv2/opencv.hpp> #include <iostream> #include <vector> #include <Eigen/Dense> #include <opencv2/ximgproc.hpp> #include "skelet.hpp" double degree_to_rad(double angle) { return angle * M_PI / 180; } cv::Scalar bar_to_hsv(int hb, int sb, int vb) { double h = (double)hb / 360 * 180; double s = (double)sb / 100 * 255; double v = (double)vb / 100 * 255; return cv::Scalar(h, s, v); } int draw_circle(cv::Mat& input_img, cv::Point p) { cv::circle(input_img, p, 3, cv::Scalar(0, 0, 0), cv::FILLED); return 0; } int draw_map(cv::Mat& input_img, int step, const cv::Mat base_img) { cv::Mat img(base_img.size(), CV_8UC3, cv::Scalar(200, 200, 200)); // Вертикальные и горизонтальные линии for(int l = 0; l < img.rows; l += step) { cv::line(img, cv::Point(0, l), cv::Point(img.cols, l), cv::Scalar(150, 150, 150), 1); cv::putText(img, std::to_string((img.rows - l - 1)/3), cv::Point(5, l-5), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0), 1); } for(int c = 0; c < img.cols; c += step*2) { cv::line(img, cv::Point(c, 0), cv::Point(c, img.rows), cv::Scalar(150, 150, 150), 1); } input_img = img; return 0; } cv::Point sk2(cv::Point p, cv::Mat img) // переворот координаты y { return cv::Point(p.x, img.rows-1 - p.y); } int main() { std::string filePath = "src/2.avi"; int h_low = 80; int s_low = 0; int v_low = 60; int h_height = 209; int s_height = 100; int v_height = 100; cv::VideoCapture cap(filePath); if (!cap.isOpened()) { std::cerr << "Ошибка открытия видеофайла или камеры!" << std::endl; return -1; } cv::namedWindow("map_img", cv::WINDOW_AUTOSIZE); // трекбар int d_int = 100; cv::createTrackbar("d_int", "map_img", &d_int, 1000); while (1) { cv::Mat frame1, frame2, frame3; cap >> frame1; cap >> frame2; cap >> frame3; if (frame1.empty() || frame2.empty() || frame3.empty()) { std::cerr << "Пустой кадр!" << std::endl; return -1; } cv::Mat img_src = (frame1 + frame2 + frame3) / 3; // усреднение трех кадров для снижения шума cv::imshow("img", img_src); cv::Mat img_hsv; cv::cvtColor(img_src, img_hsv, cv::COLOR_BGR2HSV); cv::Mat mask; // маска для зеленого cv::inRange(img_hsv, bar_to_hsv(h_low, s_low, v_low), bar_to_hsv(h_height, s_height, v_height), mask); cv::imshow("green mask", mask); // морфологическое расширение int morph_size = 2; cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(2 * morph_size + 1, 2 * morph_size + 1), cv::Point(morph_size, morph_size)); cv::dilate (mask, mask, element, cv::Point(-1, -1), 1); // скелетизация cv::Mat img_skelet; cv::ximgproc::thinning(mask, img_skelet); cv::imshow("img_skelet", img_skelet); cv::Mat map_img; draw_map(map_img, 30, img_skelet); // создание карты с сеткой // фокусное расстояние для угла обзора 54 градуса double f = img_src.cols / (2 * tan(degree_to_rad(54) / 2)); for (int x = 0; x < img_skelet.cols; x++) for (int y = img_skelet.rows - 1; y > 0; --y) if (img_skelet.at<uchar>(cv::Point(x, y)) > 0){ // принадлежность скелету int yp = img_skelet.rows - y; // инверсия y int xp = img_skelet.cols / 2 - x; // координата отностительно центра double yl = img_skelet.rows/2 - yp; // расстояние от центра по y int L = (int)(f * (d_int/10 - yl) / yl + f); // рассчет глубины xp = (int)(xp * L / f * 6); // корректировка координаты с учетом глубины // рисование точки на карте draw_circle(map_img, sk2(cv::Point(img_skelet.rows/2 - xp, L*3), map_img)); break; } cv::imshow("map_img", map_img); char key = (char)cv::waitKey(20); if (key == 27) break; } cv::destroyAllWindows(); return 0; }