
рд╣рд╛рд▓ рд╣реА рдореЗрдВ Habr├й рдкрд░ рдПрдХ рд▓реЗрдЦ рд░рд╛рдд рдХреЗ рдЖрдХрд╛рд╢ рдХреЗ рдлрд┐рд▓реНрдорд╛рдВрдХрди рдХреЗ рд╕рд╛рде рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛
" рдЖрдХрд╛рд╢
рдХреА рд░рд╛рдд рдХрд╛ рдЬреАрд╡рди рдпрд╛ рдкрд┐рд░рд╛рдорд┐рдб рдХреА рдЦреЛрдЬ рдореЗрдВ ред
" рд▓реЗрдХрд┐рди рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдЙрдкрдЧреНрд░рд╣реЛрдВ рдХреЗ рдХрд╛рд░рдг рд▓реЗрдЦрдХ рд╕реНрд╡рдпрдВ рдЙрд▓реНрдХрд╛рдУрдВ рдХрд╛ рдкрддрд╛ рдирд╣реАрдВ рд▓рдЧрд╛ рд╕рдХреЗ, рдЬреЛ рдХрд┐ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдЭреВрдареА рд╡рд╕реНрддреБрдПрдВ рд╣реИрдВред рдореИрдВ рдкрд╛рд╕ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рдерд╛, рдореИрдВрдиреЗ рд╡реАрдбрд┐рдпреЛ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рдФрд░ рджреЗрдЦрд╛ рдХрд┐ рдЙрд╕ рдкрд░ рдкрд░реНрд╕рд┐рдбреНрд╕ рд╣реИрдВ рдпрд╛ рдирд╣реАрдВред
рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ OpenCV рд╕реЗ BackgroundCubtractorMOG2 рдЯреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рд╕реНрдЯрд╛рд░ рдкреГрд╖реНрдарднреВрдорд┐ рдХреЗ рдмрд┐рдирд╛ рдПрдХ рд╡реАрдбрд┐рдпреЛ рдмрдирд╛рдпрд╛ред рд╡реАрдбрд┐рдпреЛ рд╕рдВрдкреАрдбрд╝рди рдХреЗ рдХрд╛рд░рдг "рд╢реЛрд░" рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рджрдмрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдкреНрд░рддреНрдпреЗрдХ рдлреНрд░реЗрдо рдореЗрдВ рдПрдХ 3x3 рд╡рд┐рдВрдбреЛ рдХреЗ рд╕рд╛рде рдПрдХ рдФрд╕рдд рдлрд╝рд┐рд▓реНрдЯрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛, рдФрд░ рдЫреЛрдЯреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рджрдмрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЪрд▓рддреА рд╡рд╕реНрддреБрдУрдВ рдХреА рдЫрд╡рд┐ рдХреЗ рд▓рд┐рдП
рдЙрджреНрдШрд╛рдЯрди рдСрдкрд░реЗрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ред рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдХреЗ рдмрд┐рдирд╛, "рдЪреЗрдХрд░реНрд╕" рдореЛрд╢рди рдореИрдк рдкрд░ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рджрд┐рдЦрд╛рдИ рджреЗ рд░рд╣реЗ рдереЗред рдореИрдВрдиреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд╕реЗ рдкрд╣рд▓реЗ рддреАрди рдлрд╝реНрд░реЗрдо рд╣рдЯрд╛ рджрд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдЙрди рдкрд░ 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 рдХрд┐рдореА / рдШрдВрдЯрд╛ рд╣реИ), рдФрд░ рд╡реЗ рдПрдХ рдЫреЛрдЯреА рд░реЗрдЦрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдпрд╛ рджреЛ рд▓рдЧрд╛рддрд╛рд░ рдлреНрд░реЗрдо рдХреЗ рд░реВрдк рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВред рддреЛ рдЖрдВрдЦ рдХреЗ рдкрд╛рд╕ рдЙрдЬреНрдЬреНрд╡рд▓ рд╕рд┐рддрд╛рд░реЛрдВ рдХреА рдкреГрд╖реНрдарднреВрдорд┐ рдХреЗ рдЦрд┐рд▓рд╛рдл рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордп рдирд╣реАрдВ рд╣реИред
рдкреГрд╖реНрдарднреВрдорд┐ рдХреЛ рдШрдЯрд╛рдиреЗ рдХреЗ рдмрд╛рдж рдЙрд▓реНрдХрд╛ рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЙрд▓реНрдХрд╛рдУрдВ рдХреА рдЦреЛрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рд╣реВрдк рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдореЗрд╢рди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдбрд┐рдЯреЗрдХреНрдЯрд░ рдмрдирд╛рдпрд╛, рдЬрд┐рд╕рдиреЗ рдореВрд▓ рд╡реАрдбрд┐рдпреЛ рдореЗрдВ рдЙрд▓реНрдХрд╛рдУрдВ рдкрд░ рдкреНрд░рдХрд╛рд╢ рдбрд╛рд▓рд╛ред
рдХреЛрдб 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; }
рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдмреИрдХрд▓рд╛рдЗрдЯрд┐рдВрдЧ рдХреЗ рд╕рд╛рде, рдпрд╣ рджреЗрдЦрдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ рдХрд┐ рдХреЛрдИ рдЙрд▓реНрдХрд╛ рдерд╛ рдпрд╛ рдирд╣реАрдВред рдЕрдЧрд░ рдлреНрд░реАрдЬ рдлреНрд░реЗрдо рдореЛрдб рдореЗрдВ рджреЗрдЦрд╛ рдЬрд╛рдП рддреЛ рд╣реАред рд▓реЗрдХрд┐рди рдкреГрд╖реНрдарднреВрдорд┐ рдЫрд╡рд┐ рдореЗрдВ рдЙрд▓реНрдХрд╛ рдХреЗ рд╕рднреА рдирд┐рд╢рд╛рди рд▓рдЧрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдЕрдзрд┐рдХ рд╕рдордЧреНрд░ рдЪрд┐рддреНрд░ рд╣реИред рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдЕрдзрд┐рдХрд╛рдВрд╢ рдСрдмреНрдЬреЗрдХреНрдЯ рдЫрд╡рд┐ рдХреЗ рдирд┐рдЪрд▓реЗ рджрд╛рдПрдВ рд╕реЗ "рдордХреНрдЦрд┐рдпреЛрдВ" рд╣реЛрддреЗ рд╣реИрдВред
рд╕рднреА рдХрд╛ рдЙрд▓реНтАНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдирдХреНрд╖рддреНрд░ рдкрд░реНрд╕рд┐рдпрд╕ рд╣реИ?
рдореИрдВ рддрд╛рд░реЛрдВ рд╡рд╛рд▓реЗ рдЖрдХрд╛рд╢ рдХрд╛ рдПрдХ рдордЬрдмреВрдд рдкрд╛рд░рдЦреА рдирд╣реАрдВ рд╣реВрдВ, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдХреЗрдВрджреНрд░ рдореЗрдВ рдкрд░реНрд╕рд┐рдбреНрд╕ рдХреЗ рд╕рд╛рде
рд╕реНрдЯреЗрд▓реИрд░рд┐рдпрдо рдХрд╛рд░реНрдпрдХреНрд░рдо рд╕реЗ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рд▓рд┐рдпрд╛ред рдореИрдВрдиреЗ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдХрдИ рд╕рд┐рддрд╛рд░реЛрдВ рдХрд╛ рдЪрдпрди рдХрд┐рдпрд╛ рд╣реИ рдЬреЛ рдореИрдВ рд╡реАрдбрд┐рдпреЛ рд╕реЗ "рдФрд╕рдд" рдкреГрд╖реНрдарднреВрдорд┐ рдЫрд╡рд┐ рдФрд░ рд╕реНрдЯреЗрд▓реЗрд░рд┐рдпрдо рд╕реЗ рдПрдХ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рдкрд░ рдореИрдЪ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред рдЯрд╛рдИ рдмрд┐рдВрджреБрдУрдВ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдореИрдВрдиреЗ рддреАрд╕рд░реА рдбрд┐рдЧреНрд░реА рдХрд╛ рдПрдХ рджреЛ рдЖрдпрд╛рдореА рдмрд╣реБрдкрдж рдмрдирд╛рдпрд╛ рдФрд░ рд╕рдВрджрд░реНрдн рдЫрд╡рд┐ рд╕реЗ рдкреГрд╖реНрдарднреВрдорд┐ рд╕реЗ рд╡реАрдбрд┐рдпреЛ рдХреЗ рд▓рд┐рдП рдкреЙрд░рд┐рдб рд╕реНрд░реЛрдд рдХреА рд╕реНрдерд┐рддрд┐ рдЧрд┐рдирд╛ред Perseid рд╕реНрд░реЛрдд, рдореЗрд░реЗ рдЖрд╢реНрдЪрд░реНрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╕ рдирд┐рдЪрд▓реЗ рджрд╛рд╣рд┐рдиреЗ рдХреЛрдиреЗ рдореЗрдВ рдирд┐рдХрд▓рд╛ред
рд╕реНрдЯрд╛рд░ рдЯреИрдЧ рдХреЗ рд╕рд╛рде 'рд╕рдВрджрд░реНрдн рдЖрдХрд╛рд╢' рд╕реНрдЯрд╛рд░ рд▓реЗрдмрд▓ рдХреЗ рд╕рд╛рде рдкрд░реНрд╕рд┐рдб рдХреА рдЫрд╡рд┐ рдЗрд╕рд▓рд┐рдП рд▓реЗрдЦ рдХреЗ рд▓реЗрдЦрдХ рд╡реНрдпрд░реНрде рдирд╣реАрдВ рдереЗред рдкрд░реНрд╕рд┐рдбреНрд╕ рдереЗ!