工作項目中需要完成圖像平移的操作,由於是突然加入的需求,其他部分已經占用大量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.