工作项目中需要完成图像平移的操作,由于是突然加入的需求,其他部分已经占用大量CPU时间,因此为了完成视频的同步,平移操作的效率要求很高
最开始采用仿射变换的API,时间很长,740*440分辨率大概需要个5ms左右,考虑到Mat中存在部分行复制的方法,就试了下
// TestMatSubCopy.cpp: 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <opencv\cv.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <chrono>
using namespace std;
using namespace cv ;
inline void shiftLeftRightUpDown(Mat & src, Mat & dst,Mat & temp , int w, int h, int x, int y) {
int x1, x2, y1, y2;
int X1, X2, Y1, Y2;
if (x > 0) {
x1 = x; x2 = w;
X1 = 0; X2 = w - x;
}
else{
x1 = 0; x2 = w + x;
X1 = -x; X2 = w;
}
if (y > 0) {
y1 = y; y2 = h;
Y1 = 0; Y2 = h - y;
}
else {
y1 = 0; y2 = h + y;
Y1 = -y; Y2 = h;
}
src.colRange(X1, X2).copyTo(dst.colRange(x1, x2));
dst.rowRange(Y1, Y2).copyTo(temp.rowRange(0, Y2 - Y1));
temp.rowRange(0, Y2 - Y1).copyTo(dst.rowRange(y1, y2));
}
int main()
{
Mat inImage = imread("pic1.jpg", 1);//= Mat::zeros(1920, 1080, CV_8UC3);
Mat src;
resize(inImage,src,cv::Size(740, 440));
Mat dst = Mat::zeros(src.rows, src.cols, CV_8UC3);
Mat temp = Mat::zeros(src.rows, src.cols, CV_8UC3);
imshow("src", src);
cv::waitKey(0);
auto t1 = std::chrono::steady_clock::now();
auto t2 = std::chrono::steady_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count();
int time = 25000;
auto total_duration = duration - duration;
int count = time;
t1 = std::chrono::steady_clock::now();
while (time > 0) {
--time;
shiftLeftRightUpDown(src, dst,temp, src.cols, src.rows, 10, 10);
}
t2 = std::chrono::steady_clock::now();
total_duration = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count();
cout << "average cost time :" << total_duration / count << endl;
imshow("dst", dst);
cv::waitKey(0);
return 0;
}
在3.5GHZ的cpu上740*440分辨率图片实现速度大概在175us左右,平移像素越多,速度越快,大概能提高5-10us左右的速度,将主要函数中变量声明为静态变量可以提高3us左右
对于1080P视频,运行时间在3-4ms.