Недавно на Хабре была опубликована статья со съёмками ночного неба «Ночная жизнь неба или в поисках Персеид». Но самих метеоров авторы не смогли обнаружить из-за большого количества спутников, которые в данном случае являются ложными объектами. Я не смог пройти мимо, решил обработать видео, и посмотреть, есть ли на нём Персеиды или нет.

Для начала я построил видео без фона звёзд при помощи инструмента BackgroundSubtractorMOG2 из OpenCV. Для подавления «шумовых» срабатываний, обусловленных сжатием видео, к каждому кадру применил усредняющий фильтр с окном 3x3, а к изображению движущихся объектов применил операцию opening, для подавления мелких срабатываний. Без предварительной фильтрации на карте движения отчётливо просматривались «шашечки». Первые три кадра убрал из обработки, т.к. алгоритм BackgroundSubtractorMOG2 на них ещё не накопил информацию о движении.

код
int generate_meteor_lines()
{
    cv::VideoCapture cap;

    cap.open(videoname);

    if(!cap.isOpened())
    {
        printf("can not open video file\n");
        return -1;
    }

    cv::namedWindow("foreground image", cv::WINDOW_NORMAL);

    cv::BackgroundSubtractorMOG2    bg_model;
    double                          learning_rate = 0.1;

    bg_model.setBool("detectShadows", false);
    bg_model.setDouble("backgroundRatio", 0.95);
    bg_model.setInt("history", 5);
    bg_model.setInt("fVarInit", 20);

    cv::Mat img, fgmask, fgimg;
    std::cerr << "\n";
    for(int frames_count = 0;; ++frames_count)
    {
        cap >> img;

        if(img.empty())
        {
            break;
        }
        cv::blur(img, img, cv::Size(3, 3));
        if(fgimg.empty())
        {
            fgimg.create(img.size(), img.type());
        }

        bg_model(img, fgmask, learning_rate);

        fgimg = cv::Scalar::all(0);

        img.copyTo(fgimg, fgmask);
        cv::threshold(fgimg, fgimg, 20, 255, cv::THRESH_BINARY);
        cv::Mat mask(cv::Mat::ones(3, 3, CV_8UC1));
        mask.at<char>(0, 0) = 0;
        mask.at<char>(2, 0) = 0;
        mask.at<char>(0, 2) = 0;
        mask.at<char>(2, 2) = 0;
        cv::erode(fgimg, fgimg, mask);
        cv::dilate(fgimg, fgimg, mask);

        if(frames_count > 3)
        {
            detect_lines(fgimg);
        }

        imshow("foreground image", fgimg);

        std::cerr << "Frame ##" << frames_count << "\n";

        char k = (char)cv::waitKey(30);
        if(k == 27) { break; }
    }

    return 0;
}


Видео после вычитания фона


После просмотра стало понятно, что метеоры на видео есть, но их скорость много выше (согласно википедии, видимая скорость метеора из Персеид около 59 км/c), чем скорость спутников, и они проявляютса на одном-двух последовательных кадрах в виде короткой линии. Так что глаз просто не успевает среагировать на них на фоне ярких звёзд.

Метеор после вычитания фона
Метеор

Далее, чтобы было удобнее искать метеоры, я сделал простейший детектор на основе преобразования Хафа, который подсвечивал метеоры на оригинальном видео.

Код
std::vector<cv::Vec4i> detect_lines(cv::Mat& img)
{
    cv::Mat                 coi;
    std::vector<cv::Vec4i>  lines;
    cv::extractChannel(img, coi, 0);
    double rho_res = 1;
    double theta_res = CV_PI / 180;
    double ithreshold = 50;
    double minLinLength = 50;
    double maxLineGap = 2;
    cv::HoughLinesP(coi, lines, rho_res, theta_res, ithreshold, minLinLength, maxLineGap);
    draw_line_circles(lines, img);
    return lines;
}



И даже с подсветкой трудно понять, был ли метеор или нет. Только если просматривать в режиме стоп кадров. Но после наложения всех следов метеоров на фоновое изображение мы имеем более целостную картину. Видно, что большая часть объектов «вылетает» из правой нижней части изображения.

Все обнаруженные метеоры


Но действительно ли там и есть созвездие Персея?
Я не сильный знаток звёздного неба, поэтому я сделал снимок экрана из программы «Stellarium» с Персеидами в центре. Выбрал вручную некоторое количество звёзд, которые смог сопоставить на «усреднённом» фоновом изображении из видео и снимком экрана из Стеллариума. По координатам связующих точек построил двумерный полином третьей степени и пересчитал положение источника Персеид с опорного изображения на фон от видео. Источник Персеид, к моему удивлению, как раз и оказался в правом нижнем углу.

'Опорное небо' с метками звёзд


Изображение Персеид с метками звёзд


Так что авторы статьи не зря искали. Персеиды были!

Комментарии (14)


  1. super-guest
    28.08.2018 01:15

    Круто! А они все сгорают или на Землю падают всё-таки?


    1. genew
      28.08.2018 09:02

      Вроде, те что сгорают — это метеоры, а те что падают — метеориты.


  1. Flexey
    28.08.2018 08:19

    А что это пролетает с дымом на 55 секунде? Для самолёта, вроде, слишком ярко.


    1. AndrewSu Автор
      28.08.2018 22:06

      Ярко, потому что съёмка проведена камерой с очень высокой чувствительностью. Авторы статьи про Персеиды немного рассказывали про неё habr.com/post/374163.


      1. Pyhesty
        28.08.2018 23:48

        да, чувствительность обусловлена несколькими вещами:
        1. высокой интегральной квантовой эффективностью (не максимальной, а именно интегральной), что даёт квадратичный вклад в соотношение с/ш.
        2. низким уровнем шума чтения (хотя он всё равно тонет в фоне неба, но даёт свой небольшой эффект), около 2е
        3. низкий уровень темнового тока камеры, около 7е…
        4. отсутствием Луны…


  1. Almet
    28.08.2018 09:01

    Что такое было на 26 секунде? Пульсар?


    1. Caullerd
      28.08.2018 10:00

      Похоже на блик на линзе от чего-то яркого сбоку от камеры. Если присмотреться, видно как множество пятен на одной линии вращаются, следуя за источником где-то за кадром.


  1. fivehouse
    28.08.2018 09:03

    В свое время меня очень интересовали спорадические метеоры. Они тут тоже есть. Это те, которые прилетают незвестно от куда, нерегулярно и у них, соответственно, отсутствует кажущееся «место вылета» на небосводе. На полученном видео в общем все как и ожидалось. Но вот что обнаружил действительно странного: некоторые спорадические (и не только) метеоры имеют предельно близкие видимые следы пролета. Иногда до почти полного совпадения как по длине так и по направлению. Такое статистически не возможно, если процесс полностью случайный. А если не случайный, то что это? Это видно на последнем фото «Изображение Персеид с метками звёзд».


    1. AndrewSu Автор
      28.08.2018 10:10

      Совпадение треков метеоров по длине скорее обусловлено длиной выдержки при съёмке. Ещё нужно учитывать, что съёмка произведена с объективом «рыбий глаз», и треки метеоров идут к своему центру вдоль некоторых кривых, особенно на краях изображения. Также мной выбран самый тривиальный алгоритм выделения треков, и он выделил ложный объекты. Особенно в правом верхнем и нижнем углах. Там, судя по видео, линия горизонта.


  1. Pyhesty
    28.08.2018 10:45

    Ух-ты! от лица авторов оригинальной статьи выражаю огромную благодарность за проделанную работу =) Откровенно, мы радиотехники, и многие математические алгоритмы для нас не подвластны, а уж opencv, как инструмент — так и вообще (matlab — наше всё) =) Очень приятно, что удалось обработать исходный материал и выделить метеоры =) А так же показать то, что они действительно летят из Персеид. Ещё раз большое спасибо!


  1. gonzzza
    28.08.2018 12:52

    Плюсовать не могу, но за столь умелое орудование OpenCV — однозначно уважуха!
    А за код — отдельно спасибо.


    1. AndrewSu Автор
      28.08.2018 22:15

      В коде ничего необычного нет. Он не сильно отличается от того, что содержится в примерах по OpenCV. Непосредственно по вычитанию фона можно посмотреть здесь, а по фильтрации здесь и здесь.


  1. Vantela
    28.08.2018 14:12

    Офигеть. Я ж и оригинальную статью читал.
    Всячесский респект!
    Жаль плюсануть не могу:(


  1. dMac
    28.08.2018 14:39

    Снимаю шляпу в знак уважения. С OpenCV работал, но такие вещи вытворять не приходилось. респект.