【发布时间】:2023-04-01 00:45:01
【问题描述】:
我正在开展一个使用光流算法估计无人机位置的项目。我目前正在为此使用cv::calcOpticalFlowFarneback。
我的硬件是Odroid U3,最终将连接到无人机飞行控制器。
问题是这种方法对于这个硬件来说真的很重,我正在寻找其他一些方法来优化/加速它。
我已经尝试过的事情:
- 将分辨率降低到 320x240 甚至 160x120。
- 使用 OpenCV TBB(使用
WITH_TBB=ON BUILD_TBB=ON编译并添加-ltbb)。 - 按照建议更改光流参数here
添加我的代码的相关部分:
int opticalFlow(){
// capture from camera
VideoCapture cap(0);
if( !cap.isOpened() )
return -1;
// Set Resolution - The Default Resolution Is 640 x 480
cap.set(CV_CAP_PROP_FRAME_WIDTH,WIDTH_RES);
cap.set(CV_CAP_PROP_FRAME_HEIGHT,HEIGHT_RES);
Mat flow, cflow, undistortFrame, processedFrame, origFrame, croppedFrame;
UMat gray, prevgray, uflow;
currLocation.x = 0;
currLocation.y = 0;
// for each frame calculate optical flow
for(;;)
{
// take out frame- still distorted
cap >> origFrame;
// Convert to gray
cvtColor(origFrame, processedFrame, COLOR_BGR2GRAY);
// rotate image - perspective transformation
rotateImage(processedFrame, gray, eulerFromSensors.roll, eulerFromSensors.pitch, 0, 0, 0, 1, cameraMatrix.at<double>(0,0),
cameraMatrix.at<double>(0,2),cameraMatrix.at<double>(1,2));
if( !prevgray.empty() )
{
// calculate flow
calcOpticalFlowFarneback(prevgray, gray, uflow, 0.5, 3, 10, 3, 3, 1.2, 0);
uflow.copyTo(flow);
// get average
calcAvgOpticalFlow(flow, 16, corners);
/*
Some other calculations
.
.
.
Updating currLocation struct
*/
}
//break conditions
if(waitKey(1)>=0)
break;
if(end_run)
break;
std::swap(prevgray, gray);
}
return 0;
}
注意事项:
- 我已经运行了
callgrind,瓶颈正如预期的那样是calcOpticalFlowFarneback函数。 - 我在运行程序时检查了 CPU 内核负载,它并没有大量使用所有 4 个内核,在给定时间只有一个内核处于 100% 状态(即使是 TBB):
【问题讨论】:
标签: c++ opencv image-processing optimization opticalflow