opencv3.10光流法和前景提取法

    xiaoxiao2021-12-14  23

    //bgfg_segm.h #ifndef BGFG_SEGM_H #define BGFG_SEGM_H #include "opencv2/core.hpp" #include "opencv2/core/utility.hpp" using namespace cv; enum Method { MOG, MOG2, GMG, FGD_STAT }; extern void foregroundExtraction(const Mat &frmae, Method m); #endif

    //bgfg_segm.cpp #include <iostream> #include <string> #include "bgfg_segm.h" #include "opencv2/cudabgsegm.hpp" #include "opencv2/cudalegacy.hpp" #include "opencv2/video.hpp" #include "opencv2/highgui.hpp" using namespace std; using namespace cv::cuda; static void fgd_Stat(const Mat &frame) { const char *imageWindow = "image"; const char *foregroundMaskWindow = "foreground mask"; const char *foregroundImageWindow = "foreground image"; const char *meanBackgroundImage = "mean background image"; static bool isFirstFrame = true; static GpuMat d_frame; static Ptr<BackgroundSubtractor> fgd = cuda::createBackgroundSubtractorFGD(); static GpuMat d_fgmask; static GpuMat d_bgimg; static Mat fgmask; static Mat fgimg; static Mat bgimg; d_frame.upload(frame); static GpuMat d_fgimg(d_frame.size(), d_frame.type()); if (isFirstFrame) { fgd->apply(d_frame, d_fgmask); isFirstFrame = false; } else { int64 start = cv::getTickCount(); fgd->apply(d_frame, d_fgmask); fgd->getBackgroundImage(d_bgimg); double fps = cv::getTickFrequency() / (cv::getTickCount() - start); std::cout << "FPS : " << fps << std::endl; d_fgimg.setTo(Scalar::all(0)); d_frame.copyTo(d_fgimg, d_fgmask); d_fgmask.download(fgmask); d_fgimg.download(fgimg); d_bgimg.download(bgimg); imshow(imageWindow, frame); imshow(foregroundMaskWindow, fgmask); imshow(foregroundImageWindow, fgimg); imshow(meanBackgroundImage, bgimg); } } static void mog(const Mat &frame) { const char *imageWindow = "image"; const char *foregroundMaskWindow = "foreground mask"; const char *foregroundImageWindow = "foreground image"; const char *meanBackgroundImage = "mean background image"; static bool isFirstFrame = true; static GpuMat d_frame; static Ptr<BackgroundSubtractor> mog = cuda::createBackgroundSubtractorMOG(); static GpuMat d_fgmask; static GpuMat d_bgimg; static Mat fgmask; static Mat fgimg; static Mat bgimg; d_frame.upload(frame); static GpuMat d_fgimg(d_frame.size(), d_frame.type()); if (isFirstFrame) { mog->apply(d_frame, d_fgmask, 0.01); isFirstFrame = false; } else { int64 start = cv::getTickCount(); mog->apply(d_frame, d_fgmask, 0.01); mog->getBackgroundImage(d_bgimg); double fps = cv::getTickFrequency() / (cv::getTickCount() - start); std::cout << "FPS : " << fps << std::endl; d_fgimg.setTo(Scalar::all(0)); d_frame.copyTo(d_fgimg, d_fgmask); d_fgmask.download(fgmask); d_fgimg.download(fgimg); d_bgimg.download(bgimg); imshow(imageWindow, frame); imshow(foregroundMaskWindow, fgmask); imshow(foregroundImageWindow, fgimg); imshow(meanBackgroundImage, bgimg); } } static void mog2(const Mat &frame) { const char *imageWindow = "image"; const char *foregroundMaskWindow = "foreground mask"; const char *foregroundImageWindow = "foreground image"; const char *meanBackgroundImage = "mean background image"; static bool isFirstFrame = true; static GpuMat d_frame; static Ptr<BackgroundSubtractor> mog2 = cuda::createBackgroundSubtractorMOG2(); static GpuMat d_fgmask; static GpuMat d_bgimg; static Mat fgmask; static Mat fgimg; static Mat bgimg; d_frame.upload(frame); static GpuMat d_fgimg(d_frame.size(), d_frame.type()); if (isFirstFrame) { mog2->apply(d_frame, d_fgmask); isFirstFrame = false; } else { int64 start = cv::getTickCount(); mog2->apply(d_frame, d_fgmask); mog2->getBackgroundImage(d_bgimg); double fps = cv::getTickFrequency() / (cv::getTickCount() - start); std::cout << "FPS : " << fps << std::endl; d_fgimg.setTo(Scalar::all(0)); d_frame.copyTo(d_fgimg, d_fgmask); d_fgmask.download(fgmask); d_fgimg.download(fgimg); d_bgimg.download(bgimg); imshow(imageWindow, frame); imshow(foregroundMaskWindow, fgmask); imshow(foregroundImageWindow, fgimg); imshow(meanBackgroundImage, bgimg); } } static void gmg(const Mat &frame) { const char *imageWindow = "image"; const char *foregroundMaskWindow = "foreground mask"; const char *foregroundImageWindow = "foreground image"; static bool isFirstFrame = true; static GpuMat d_frame; static Ptr<BackgroundSubtractor> gmg = cuda::createBackgroundSubtractorGMG(40); static GpuMat d_fgmask; static Mat fgmask; static Mat fgimg; d_frame.upload(frame); static GpuMat d_fgimg(d_frame.size(), d_frame.type()); if (isFirstFrame) { gmg->apply(d_frame, d_fgmask); isFirstFrame = false; } else { int64 start = cv::getTickCount(); gmg->apply(d_frame, d_fgmask); double fps = cv::getTickFrequency() / (cv::getTickCount() - start); std::cout << "FPS : " << fps << std::endl; d_fgimg.setTo(Scalar::all(0)); d_frame.copyTo(d_fgimg, d_fgmask); d_fgmask.download(fgmask); d_fgimg.download(fgimg); d_fgmask.download(fgmask); d_fgimg.download(fgimg); imshow(imageWindow, frame); imshow(foregroundMaskWindow, fgmask); imshow(foregroundImageWindow, fgimg); } } void foregroundExtraction(const Mat &frmae, Method m) { assert(m >= MOG && m <= FGD_STAT); switch (m) { case FGD_STAT: fgd_Stat(frmae); break; case MOG: mog(frmae); break; case MOG2: mog2(frmae); break; case GMG: gmg(frmae); break; default: cout << "没有该方法,程序将退出." << endl; exit(1); break; } } //optical_flow.h #ifndef OPTICAL_FLOW_H #define OPTICAL_FLOW_H #include "opencv2/core.hpp" #include <opencv2/core/utility.hpp> using namespace cv; extern const char *optical_Flow_Name[]; extern Mat opticalFlowOut; extern void optical_flow(const Mat &frame0, const Mat &frame1, const char *optical_Flow_Name); #endif //optical_flow.cpp #include <iostream> #include <fstream> #include "optical_flow.h" #include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include "opencv2/highgui.hpp" #include "opencv2/cudaoptflow.hpp" #include "opencv2/cudaarithm.hpp" using namespace std; using namespace cv::cuda; Mat opticalFlowOut; //原始光流输出图片,三通道 CV_8UC3 inline bool isFlowCorrect(Point2f u) { return !cvIsNaN(u.x) && !cvIsNaN(u.y) && fabs(u.x) < 1e9 && fabs(u.y) < 1e9; } static Vec3b computeColor(float fx, float fy) { static bool first = true; // relative lengths of color transitions: // these are chosen based on perceptual similarity // (e.g. one can distinguish more shades between red and yellow // than between yellow and green) const int RY = 15; const int YG = 6; const int GC = 4; const int CB = 11; const int BM = 13; const int MR = 6; const int NCOLS = RY + YG + GC + CB + BM + MR; static Vec3i colorWheel[NCOLS]; if (first) { int k = 0; for (int i = 0; i < RY; ++i, ++k) colorWheel[k] = Vec3i(255, 255 * i / RY, 0); for (int i = 0; i < YG; ++i, ++k) colorWheel[k] = Vec3i(255 - 255 * i / YG, 255, 0); for (int i = 0; i < GC; ++i, ++k) colorWheel[k] = Vec3i(0, 255, 255 * i / GC); for (int i = 0; i < CB; ++i, ++k) colorWheel[k] = Vec3i(0, 255 - 255 * i / CB, 255); for (int i = 0; i < BM; ++i, ++k) colorWheel[k] = Vec3i(255 * i / BM, 0, 255); for (int i = 0; i < MR; ++i, ++k) colorWheel[k] = Vec3i(255, 0, 255 - 255 * i / MR); first = false; } const float rad = sqrt(fx * fx + fy * fy); const float a = atan2(-fy, -fx) / (float)CV_PI; const float fk = (a + 1.0f) / 2.0f * (NCOLS - 1); const int k0 = static_cast<int>(fk); const int k1 = (k0 + 1) % NCOLS; const float f = fk - k0; Vec3b pix; for (int b = 0; b < 3; b++) { const float col0 = colorWheel[k0][b] / 255.0f; const float col1 = colorWheel[k1][b] / 255.0f; float col = (1 - f) * col0 + f * col1; if (rad <= 1) col = 1 - rad * (1 - col); // increase saturation with radius else col *= .75; // out of range pix[2 - b] = static_cast<uchar>(255.0 * col); } return pix; } static void drawOpticalFlow(const Mat_<float>& flowx, const Mat_<float>& flowy, Mat& dst, float maxmotion = -1) { static bool isFirstTime = true; if (isFirstTime) { dst.create(flowx.size(), CV_8UC3); isFirstTime = false; } dst.setTo(Scalar::all(0)); // determine motion range: float maxrad = maxmotion; if (maxmotion <= 0) { maxrad = 1; for (int y = 0; y < flowx.rows; ++y) { for (int x = 0; x < flowx.cols; ++x) { Point2f u(flowx(y, x), flowy(y, x)); if (!isFlowCorrect(u)) continue; maxrad = max(maxrad, sqrt(u.x * u.x + u.y * u.y)); } } } for (int y = 0; y < flowx.rows; ++y) { for (int x = 0; x < flowx.cols; ++x) { Point2f u(flowx(y, x), flowy(y, x)); if (isFlowCorrect(u)) dst.at<Vec3b>(y, x) = computeColor(u.x / maxrad, u.y / maxrad); } } } static void showFlow(const char* name, const GpuMat& d_flow) { static GpuMat planes[2]; cuda::split(d_flow, planes); Mat flowx(planes[0]); Mat flowy(planes[1]); //drawOpticalFlow(flowx, flowy, opticalFlowOut, 10); drawOpticalFlow(flowx, flowy, opticalFlowOut); //-1 imshow(name, opticalFlowOut); } //Brox光流法 static void optical_flow_Brox(const Mat &frame0, const Mat &frame1) { static GpuMat d_frame0; static GpuMat d_frame1; d_frame0.upload(frame0); d_frame1.upload(frame1); static GpuMat d_flow(frame0.size(), CV_32FC2); static Ptr<cuda::BroxOpticalFlow> brox = cuda::BroxOpticalFlow::create(0.197f, 50.0f, 0.8f, 10, 77, 10); static GpuMat d_frame0f; static GpuMat d_frame1f; d_frame0.convertTo(d_frame0f, CV_32F, 1.0 / 255.0); d_frame1.convertTo(d_frame1f, CV_32F, 1.0 / 255.0); //int64 start = getTickCount(); brox->calc(d_frame0f, d_frame1f, d_flow); //double timeSec = (getTickCount() - start) / getTickFrequency(); //cout << "Brox : " << timeSec << " sec" << endl; showFlow("Brox", d_flow); } //LK光流法 static void optical_flow_LK(const Mat &frame0, const Mat &frame1) { static GpuMat d_frame0; static GpuMat d_frame1; d_frame0.upload(frame0); d_frame1.upload(frame1); static GpuMat d_flow(frame0.size(), CV_32FC2); static Ptr<cuda::DensePyrLKOpticalFlow> lk = cuda::DensePyrLKOpticalFlow::create(Size(7, 7)); //int64 start = getTickCount(); lk->calc(d_frame0, d_frame1, d_flow); //double timeSec = (getTickCount() - start) / getTickFrequency(); //cout << "LK : " << timeSec << " sec" << endl; showFlow("LK", d_flow); } //Farn光流法 static void optical_flow_Farn(const Mat &frame0, const Mat &frame1) { static GpuMat d_frame0; static GpuMat d_frame1; d_frame0.upload(frame0); d_frame1.upload(frame1); static GpuMat d_flow(frame0.size(), CV_32FC2); static Ptr<cuda::FarnebackOpticalFlow> farn = cuda::FarnebackOpticalFlow::create(); //int64 start = getTickCount(); farn->calc(d_frame0, d_frame1, d_flow); //double timeSec = (getTickCount() - start) / getTickFrequency(); //cout << "Farn : " << timeSec << " sec" << endl; showFlow("Farn", d_flow); } //TVL1光流法 static void optical_flow_TVL1(const Mat &frame0, const Mat &frame1) { static GpuMat d_frame0; static GpuMat d_frame1; d_frame0.upload(frame0); d_frame1.upload(frame1); static GpuMat d_flow(frame0.size(), CV_32FC2); static Ptr<cuda::OpticalFlowDual_TVL1> tvl1 = cuda::OpticalFlowDual_TVL1::create(); //int64 start = getTickCount(); tvl1->calc(d_frame0, d_frame1, d_flow); //double timeSec = (getTickCount() - start) / getTickFrequency(); //cout << "TVL1 : " << timeSec << " sec" << endl; showFlow("TVL1", d_flow); } typedef void(*optical_Flow)(const Mat &, const Mat &); static optical_Flow optical_Flow_Method[] = { optical_flow_Brox, \ optical_flow_LK, \ optical_flow_Farn, \ optical_flow_TVL1, \ NULL }; const char *optical_Flow_Name[] = { "Brox", "LK", "Farn", "TVL1", NULL }; static int getIndexOfOpticalFlowMethod(const char *methodName) { assert(methodName != NULL); for (int i = 0; i < sizeof(optical_Flow_Name) / sizeof(*optical_Flow_Name) - 1; i++) { if (strcmp(methodName, optical_Flow_Name[i]) == 0) { return i; } } return -1; } //fram0前一帧图像,frame1frame1当前帧图像,均为灰度图 void optical_flow(const Mat &frame0, const Mat &frame1, const char *optical_Flow_Name) { static bool isFirstTime = true; if (isFirstTime) { assert(optical_Flow_Name != NULL && !frame0.empty() && !frame1.empty() && frame0.size() == frame1.size()); isFirstTime = false; } /*if (optical_Flow_Name == NULL) { cout << "请指定正确的光流方法" << endl; return; }*/ //static int methodIndex = getIndexOfOpticalFlowMethod(optical_Flow_Name); static int methodIndex = getIndexOfOpticalFlowMethod(optical_Flow_Name); assert(methodIndex > -1); /*if (methodIndex == -1) { cout << "请指定正确的光流方法" << endl; return; }*/ optical_Flow_Method[methodIndex](frame0, frame1); } //main.cpp #include "bgfg_segm.h" #include "optical_flow.h" #include <cuda.h> #include <cuda_runtime.h> #include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include "opencv2/highgui.hpp" #include <iostream> int main(int argc, char *argv[]) { const char *orignalFrameWin = "原始视频帧流"; //char *fileName = "E:/opencv2.48/sources/samples/gpu/768x576.avi"; //char *fileName = "D:/FarnebackInGPU/myProject/myProject/data/car/MAH00152.MP4"; //char *fileName = "D:/FarnebackInGPU/myProject/myProject/data/car/MAH00153.MP4"; //char *fileName = "D:/FarnebackInGPU/myProject/myProject/data/car/20161101050502.MTS"; //char *fileName = "D:/FarnebackInGPU/myProject/myProject/data/car/MAH00151.MP4"; char *fileName = "D:/FarnebackInGPU/myProject/myProject/data/car/MAH00158.MP4"; //const char *fileName = "D:/FarnebackInGPU/myProject/myProject/data/car/MAH00152.MP4"; //const char *fileName = "D:/FarnebackInGPU/myProject/myProject/data/car/MAH00154.MP4"; Method foregroudExtMethod = MOG; //FGD_STAT, MOG, MOG2, GMG int frames = 0; Mat currentFrame, previousFrame; Mat currentGrayFrame, previousGrayFrame; bool isFirstFrame = true; VideoCapture cap; cap.open(fileName); if (!cap.isOpened()) { fprintf(stderr, "Video can't be opened!\n"); return 1; } cudaError_t cudaStatus; cudaStatus = cudaSetDevice(0); if (cudaStatus != cudaSuccess) { fprintf(stderr, "cudaSetDevice failed! Do you have a CUDA-capable GPU installed?"); return 1; } while (cap.isOpened()) { cap >> currentFrame; if (!currentFrame.data) { fprintf(stderr, "Frame is empty!\n"); break; } while (currentFrame.cols > 800) { resize(currentFrame, currentFrame, Size(currentFrame.cols / 2, currentFrame.rows / 2)); } frames++; cv::cvtColor(currentFrame, currentGrayFrame, CV_RGB2GRAY); std::cout << "第" << frames << "帧" << std::endl; imshow(orignalFrameWin, currentFrame); if (isFirstFrame) { swap(currentGrayFrame, previousGrayFrame); isFirstFrame = false; } else { //计算光流 //const char *optical_Flow_Method_Name[] = { "Brox", "LK", "Farn", "TVL1", NULL }; optical_flow(previousGrayFrame, currentGrayFrame, optical_Flow_Name[0]); swap(currentGrayFrame, previousGrayFrame); } //前景提取 foregroundExtraction(currentFrame, foregroudExtMethod); int key = cv::waitKey(1); if (key == 27) break; else if (key == 'p' || key == 'P') cv::waitKey(); } cudaStatus = cudaDeviceReset(); if (cudaStatus != cudaSuccess) { fprintf(stderr, "cudaDeviceReset failed!"); return 1; } return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-963382.html

    最新回复(0)