mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 00:03:03 +04:00
Minor refactoring in several C++ samples:
- bgfg_segm - peopledetect - opencv_version - dnn/colorization - tapi/opencl_custom_kernel - tapi/dense_optical_flow (renamed tvl1_optical_flow)
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
|
||||
#include "opencv2/core/ocl.hpp"
|
||||
#include "opencv2/core/utility.hpp"
|
||||
#include "opencv2/imgcodecs.hpp"
|
||||
#include "opencv2/videoio.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/video.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
static Mat getVisibleFlow(InputArray flow)
|
||||
{
|
||||
vector<UMat> flow_vec;
|
||||
split(flow, flow_vec);
|
||||
UMat magnitude, angle;
|
||||
cartToPolar(flow_vec[0], flow_vec[1], magnitude, angle, true);
|
||||
magnitude.convertTo(magnitude, CV_32F, 0.2);
|
||||
vector<UMat> hsv_vec;
|
||||
hsv_vec.push_back(angle);
|
||||
hsv_vec.push_back(UMat::ones(angle.size(), angle.type()));
|
||||
hsv_vec.push_back(magnitude);
|
||||
UMat hsv;
|
||||
merge(hsv_vec, hsv);
|
||||
Mat img;
|
||||
cvtColor(hsv, img, COLOR_HSV2BGR);
|
||||
return img;
|
||||
}
|
||||
|
||||
static Size fitSize(const Size & sz, const Size & bounds)
|
||||
{
|
||||
CV_Assert(sz.area() > 0);
|
||||
if (sz.width > bounds.width || sz.height > bounds.height)
|
||||
{
|
||||
double scale = std::min((double)bounds.width / sz.width, (double)bounds.height / sz.height);
|
||||
return Size(cvRound(sz.width * scale), cvRound(sz.height * scale));
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
const char* keys =
|
||||
"{ h help | | print help message }"
|
||||
"{ c camera | 0 | capture video from camera (device index starting from 0) }"
|
||||
"{ a algorithm | fb | algorithm (supported: 'fb', 'tvl')}"
|
||||
"{ m cpu | | run without OpenCL }"
|
||||
"{ v video | | use video as input }"
|
||||
"{ o original | | use original frame size (do not resize to 640x480)}"
|
||||
;
|
||||
CommandLineParser parser(argc, argv, keys);
|
||||
parser.about("This sample demonstrates using of dense optical flow algorithms.");
|
||||
if (parser.has("help"))
|
||||
{
|
||||
parser.printMessage();
|
||||
return 0;
|
||||
}
|
||||
int camera = parser.get<int>("camera");
|
||||
string algorithm = parser.get<string>("algorithm");
|
||||
bool useCPU = parser.has("cpu");
|
||||
string filename = parser.get<string>("video");
|
||||
bool useOriginalSize = parser.has("original");
|
||||
if (!parser.check())
|
||||
{
|
||||
parser.printErrors();
|
||||
return 1;
|
||||
}
|
||||
|
||||
VideoCapture cap;
|
||||
if(filename.empty())
|
||||
cap.open(camera);
|
||||
else
|
||||
cap.open(filename);
|
||||
if (!cap.isOpened())
|
||||
{
|
||||
cout << "Can not open video stream: '" << (filename.empty() ? "<camera>" : filename) << "'" << endl;
|
||||
return 2;
|
||||
}
|
||||
|
||||
cv::Ptr<cv::DenseOpticalFlow> alg;
|
||||
if (algorithm == "fb")
|
||||
alg = cv::FarnebackOpticalFlow::create();
|
||||
else if (algorithm == "tvl")
|
||||
alg = cv::DualTVL1OpticalFlow::create();
|
||||
else
|
||||
{
|
||||
cout << "Invalid algorithm: " << algorithm << endl;
|
||||
return 3;
|
||||
}
|
||||
|
||||
ocl::setUseOpenCL(!useCPU);
|
||||
|
||||
cout << "Press 'm' to toggle CPU/GPU processing mode" << endl;
|
||||
cout << "Press ESC or 'q' to exit" << endl;
|
||||
|
||||
UMat prevFrame, frame, input_frame, flow;
|
||||
for(;;)
|
||||
{
|
||||
if (!cap.read(input_frame) || input_frame.empty())
|
||||
{
|
||||
cout << "Finished reading: empty frame" << endl;
|
||||
break;
|
||||
}
|
||||
Size small_size = fitSize(input_frame.size(), Size(640, 480));
|
||||
if (!useOriginalSize && small_size != input_frame.size())
|
||||
resize(input_frame, frame, small_size);
|
||||
else
|
||||
frame = input_frame;
|
||||
cvtColor(frame, frame, COLOR_BGR2GRAY);
|
||||
imshow("frame", frame);
|
||||
if (!prevFrame.empty())
|
||||
{
|
||||
int64 t = getTickCount();
|
||||
alg->calc(prevFrame, frame, flow);
|
||||
t = getTickCount() - t;
|
||||
{
|
||||
Mat img = getVisibleFlow(flow);
|
||||
ostringstream buf;
|
||||
buf << "Algo: " << algorithm << " | "
|
||||
<< "Mode: " << (useCPU ? "CPU" : "GPU") << " | "
|
||||
<< "FPS: " << fixed << setprecision(1) << (getTickFrequency() / (double)t);
|
||||
putText(img, buf.str(), Point(10, 30), FONT_HERSHEY_PLAIN, 2.0, Scalar(0, 0, 255), 2, LINE_AA);
|
||||
imshow("Dense optical flow field", img);
|
||||
}
|
||||
}
|
||||
frame.copyTo(prevFrame);
|
||||
|
||||
// interact with user
|
||||
const char key = (char)waitKey(30);
|
||||
if (key == 27 || key == 'q') // ESC
|
||||
{
|
||||
cout << "Exit requested" << endl;
|
||||
break;
|
||||
}
|
||||
else if (key == 'm')
|
||||
{
|
||||
useCPU = !useCPU;
|
||||
ocl::setUseOpenCL(!useCPU);
|
||||
cout << "Set processing mode to: " << (useCPU ? "CPU" : "GPU") << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,3 +1,7 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
|
||||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/core/ocl.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
|
||||
@@ -1,233 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <iomanip>
|
||||
|
||||
#include "opencv2/core/ocl.hpp"
|
||||
#include "opencv2/core/utility.hpp"
|
||||
#include "opencv2/imgcodecs.hpp"
|
||||
#include "opencv2/videoio.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/video.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
typedef unsigned char uchar;
|
||||
#define LOOP_NUM 10
|
||||
int64 work_begin = 0;
|
||||
int64 work_end = 0;
|
||||
|
||||
static void workBegin()
|
||||
{
|
||||
work_begin = getTickCount();
|
||||
}
|
||||
static void workEnd()
|
||||
{
|
||||
work_end += (getTickCount() - work_begin);
|
||||
}
|
||||
static double getTime()
|
||||
{
|
||||
return work_end * 1000. / getTickFrequency();
|
||||
}
|
||||
|
||||
template <typename T> inline T clamp (T x, T a, T b)
|
||||
{
|
||||
return ((x) > (a) ? ((x) < (b) ? (x) : (b)) : (a));
|
||||
}
|
||||
|
||||
template <typename T> inline T mapValue(T x, T a, T b, T c, T d)
|
||||
{
|
||||
x = ::clamp(x, a, b);
|
||||
return c + (d - c) * (x - a) / (b - a);
|
||||
}
|
||||
|
||||
static void getFlowField(const Mat& u, const Mat& v, Mat& flowField)
|
||||
{
|
||||
float maxDisplacement = 1.0f;
|
||||
|
||||
for (int i = 0; i < u.rows; ++i)
|
||||
{
|
||||
const float* ptr_u = u.ptr<float>(i);
|
||||
const float* ptr_v = v.ptr<float>(i);
|
||||
|
||||
for (int j = 0; j < u.cols; ++j)
|
||||
{
|
||||
float d = max(fabsf(ptr_u[j]), fabsf(ptr_v[j]));
|
||||
|
||||
if (d > maxDisplacement)
|
||||
maxDisplacement = d;
|
||||
}
|
||||
}
|
||||
|
||||
flowField.create(u.size(), CV_8UC4);
|
||||
|
||||
for (int i = 0; i < flowField.rows; ++i)
|
||||
{
|
||||
const float* ptr_u = u.ptr<float>(i);
|
||||
const float* ptr_v = v.ptr<float>(i);
|
||||
|
||||
|
||||
Vec4b* row = flowField.ptr<Vec4b>(i);
|
||||
|
||||
for (int j = 0; j < flowField.cols; ++j)
|
||||
{
|
||||
row[j][0] = 0;
|
||||
row[j][1] = static_cast<unsigned char> (mapValue (-ptr_v[j], -maxDisplacement, maxDisplacement, 0.0f, 255.0f));
|
||||
row[j][2] = static_cast<unsigned char> (mapValue ( ptr_u[j], -maxDisplacement, maxDisplacement, 0.0f, 255.0f));
|
||||
row[j][3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
const char* keys =
|
||||
"{ h help | | print help message }"
|
||||
"{ l left | | specify left image }"
|
||||
"{ r right | | specify right image }"
|
||||
"{ o output | tvl1_output.jpg | specify output save path }"
|
||||
"{ c camera | 0 | enable camera capturing }"
|
||||
"{ m cpu_mode | | run without OpenCL }"
|
||||
"{ v video | | use video as input }";
|
||||
|
||||
CommandLineParser cmd(argc, argv, keys);
|
||||
|
||||
if (cmd.has("help"))
|
||||
{
|
||||
cout << "Usage: pyrlk_optical_flow [options]" << endl;
|
||||
cout << "Available options:" << endl;
|
||||
cmd.printMessage();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
string fname0 = cmd.get<string>("l");
|
||||
string fname1 = cmd.get<string>("r");
|
||||
string vdofile = cmd.get<string>("v");
|
||||
string outpath = cmd.get<string>("o");
|
||||
bool useCPU = cmd.get<bool>("m");
|
||||
bool useCamera = cmd.get<bool>("c");
|
||||
int inputName = cmd.get<int>("c");
|
||||
|
||||
UMat frame0, frame1;
|
||||
imread(fname0, cv::IMREAD_GRAYSCALE).copyTo(frame0);
|
||||
imread(fname1, cv::IMREAD_GRAYSCALE).copyTo(frame1);
|
||||
cv::Ptr<cv::DenseOpticalFlow> alg = cv::createOptFlow_DualTVL1();
|
||||
|
||||
UMat flow;
|
||||
Mat show_flow;
|
||||
vector<UMat> flow_vec;
|
||||
if (frame0.empty() || frame1.empty())
|
||||
useCamera = true;
|
||||
|
||||
if (useCamera)
|
||||
{
|
||||
VideoCapture capture;
|
||||
UMat frame, frameCopy;
|
||||
UMat frame0Gray, frame1Gray;
|
||||
UMat ptr0, ptr1;
|
||||
|
||||
if(vdofile.empty())
|
||||
capture.open( inputName );
|
||||
else
|
||||
capture.open(vdofile.c_str());
|
||||
|
||||
if(!capture.isOpened())
|
||||
{
|
||||
if(vdofile.empty())
|
||||
cout << "Capture from CAM " << inputName << " didn't work" << endl;
|
||||
else
|
||||
cout << "Capture from file " << vdofile << " failed" <<endl;
|
||||
goto nocamera;
|
||||
}
|
||||
|
||||
cout << "In capture ..." << endl;
|
||||
for(int i = 0;; i++)
|
||||
{
|
||||
if( !capture.read(frame) )
|
||||
break;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
frame.copyTo( frame0 );
|
||||
cvtColor(frame0, frame0Gray, COLOR_BGR2GRAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i%2 == 1)
|
||||
{
|
||||
frame.copyTo(frame1);
|
||||
cvtColor(frame1, frame1Gray, COLOR_BGR2GRAY);
|
||||
ptr0 = frame0Gray;
|
||||
ptr1 = frame1Gray;
|
||||
}
|
||||
else
|
||||
{
|
||||
frame.copyTo(frame0);
|
||||
cvtColor(frame0, frame0Gray, COLOR_BGR2GRAY);
|
||||
ptr0 = frame1Gray;
|
||||
ptr1 = frame0Gray;
|
||||
}
|
||||
|
||||
alg->calc(ptr0, ptr1, flow);
|
||||
split(flow, flow_vec);
|
||||
|
||||
if (i%2 == 1)
|
||||
frame1.copyTo(frameCopy);
|
||||
else
|
||||
frame0.copyTo(frameCopy);
|
||||
getFlowField(flow_vec[0].getMat(ACCESS_READ), flow_vec[1].getMat(ACCESS_READ), show_flow);
|
||||
imshow("tvl1 optical flow field", show_flow);
|
||||
}
|
||||
|
||||
char key = (char)waitKey(10);
|
||||
if (key == 27)
|
||||
break;
|
||||
else if (key == 'm' || key == 'M')
|
||||
{
|
||||
ocl::setUseOpenCL(!cv::ocl::useOpenCL());
|
||||
cout << "Switched to " << (ocl::useOpenCL() ? "OpenCL" : "CPU") << " mode\n";
|
||||
}
|
||||
}
|
||||
|
||||
capture.release();
|
||||
}
|
||||
else
|
||||
{
|
||||
nocamera:
|
||||
if (cmd.has("cpu_mode"))
|
||||
{
|
||||
ocl::setUseOpenCL(false);
|
||||
std::cout << "OpenCL was disabled" << std::endl;
|
||||
}
|
||||
for(int i = 0; i <= LOOP_NUM; i ++)
|
||||
{
|
||||
cout << "loop" << i << endl;
|
||||
|
||||
if (i > 0) workBegin();
|
||||
|
||||
alg->calc(frame0, frame1, flow);
|
||||
split(flow, flow_vec);
|
||||
|
||||
if (i > 0 && i <= LOOP_NUM)
|
||||
workEnd();
|
||||
|
||||
if (i == LOOP_NUM)
|
||||
{
|
||||
if (useCPU)
|
||||
cout << "average CPU time (noCamera) : ";
|
||||
else
|
||||
cout << "average GPU time (noCamera) : ";
|
||||
cout << getTime() / LOOP_NUM << " ms" << endl;
|
||||
|
||||
getFlowField(flow_vec[0].getMat(ACCESS_READ), flow_vec[1].getMat(ACCESS_READ), show_flow);
|
||||
imshow("PyrLK [Sparse]", show_flow);
|
||||
imwrite(outpath, show_flow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
waitKey();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user