Ночная жизнь неба или в поисках Персеид — обработка

в 20:14, , рубрики: opencv, астрономия, Научно-популярное, ночное небо, обработка изображений, персеиды

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

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

код

int generate_meteor_lines()
{
    cv::VideoCapture cap;

    cap.open(videoname);

    if(!cap.isOpened())
    {
        printf("can not open video filen");
        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;
}

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

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

Ночная жизнь неба или в поисках Персеид — обработка - 3

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

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

Ночная жизнь неба или в поисках Персеид — обработка - 4

Изображение Персеид с метками звёзд
Ночная жизнь неба или в поисках Персеид — обработка - 5

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

Автор: AndrewSu

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js