OpenCV / C — улучшить скорость цикла?

Недавно я реализовал метод деформации изображения, используя OpenCV 2.31 (C ++). Тем не менее, это
Метод довольно трудоемкий … После некоторых исследований и улучшений
Мне удается сократить время обработки с 400 мс до 120 мс, что довольно приятно.
Я достигаю этого результата, разворачивая цикл (он сокращает время с 400 мс до 330 мс)
затем я включил флаги оптимизации в моем экспресс-выпуске VC ++ 2008 Express Edition (флаг Enabled O2) — это последнее исправление улучшило обработку примерно до 120 мс.

Однако, поскольку у меня есть другая обработка, которая будет реализована вокруг этой деформации, я хотел бы сократить это время обработки еще больше до 20 мс — чем меньше это значение, тем лучше, но я не знаю, возможно ли это !! ! …

Еще одна вещь, я хотел бы сделать это с помощью свободно доступных библиотек.
Все предложения приветствуются.

Ниже, вы найдете метод, о котором я говорю.

Спасибо за вашу помощь

Ариэль Б.

cv::Mat Warp::pieceWiseWarp(const cv::Mat &Isource, const cv::Mat &s, TYPE_CONVERSION type)
{
cv::Mat Idest(roi.height,roi.width,Isource.type(),cv::Scalar::all(0));
float xi, xj, xk, yi, yj, yk, x, y;
float X2X1,Y2Y1,X2X,Y2Y,XX1,YY1,X2X1_Y2Y1,a1, a2, a3, a4,b1,b2,c1,c2;
int x1, y1, x2, y2;
char k;
int nc = roi.width;
int nr = roi.height;
int channels = Isource.channels();
int N = nr * nc;float *alphaPtr = alpha.ptr<float>(0);
float *betaPtr = beta.ptr<float>(0);
char *triMaskPtr = triMask.ptr<char>(0);
uchar *IdestPtr = Idest.data;for(int i = 0; i < N;  i++, IdestPtr += channels - 1)
if((k = triMaskPtr[i]) != -1)// the pixel do belong to delaunay
{

cv::Vec3b t = trianglesMap.row(k);

xi = s.col(1).at<float>(t[0]); yi = s.col(0).at<float>(t[0]);
xj = s.col(1).at<float>(t[1]); yj = s.col(0).at<float>(t[1]);
xk = s.col(1).at<float>(t[2]); yk = s.col(0).at<float>(t[2]);

x = xi + alphaPtr[i]*(xj - xi) + betaPtr[i]*(xk - xi);
y = yi + alphaPtr[i]*(yj - yi) + betaPtr[i]*(yk - yi);//...some bounds checking here...

x2 = ceil(x); x1 = floor(x);
y2 = ceil(y); y1 = floor(y);

//2. use bilinear interpolation on the pixel location - see wiki for formula...
//...3. copy the resulting intensity (GL) to the destination (i,j)

X2X1 = (x2 - x1);
Y2Y1 = (y2 - y1);
X2X  = (x2 - x);
Y2Y  = (y2 - y);
XX1  = (x - x1);
YY1  = (y - y1);

X2X1_Y2Y1 = X2X1*Y2Y1;
a1 = (X2X*Y2Y)/(X2X1_Y2Y1);
a2 = (XX1*Y2Y)/(X2X1_Y2Y1);
a3 = (X2X*YY1)/(X2X1_Y2Y1);
a4 = (XX1*YY1)/(X2X1_Y2Y1);

b1 = (X2X/X2X1);
b2 = (XX1/X2X1);

c1 = (Y2Y/Y2Y1);
c2 = (YY1/Y2Y1);

for(int c = 0; c < channels; c++)// Consider implementing this bilinear interpolation elsewhere in another function
{
if(x1 != x2 && y1 != y2)
IdestPtr[i + c] = Isource.at<cv::Vec3b>(y1,x1)[c]*a1
+ Isource.at<cv::Vec3b>(y2,x1)[c]*a2
+ Isource.at<cv::Vec3b>(y1,x2)[c]*a3
+ Isource.at<cv::Vec3b>(y2,x2)[c]*a4;
if(x1 == x2 && y1 == y2)
IdestPtr[i + c] = Isource.at<cv::Vec3b>(y1,x1)[c];

if(x1 != x2 && y1 == y2)
IdestPtr[i + c] = Isource.at<cv::Vec3b>(y1,x1)[c]*b1 + Isource.at<cv::Vec3b>(y1,x2)[c]*b2;

if(x1 == x2 && y1 != y2)
IdestPtr[i + c] = Isource.at<cv::Vec3b>(y1,x1)[c]*c1 + Isource.at<cv::Vec3b>(y2,x1)[c]*c2;
}
}

if(type == CONVERT_TO_CV_32FC3)
Idest.convertTo(Idest,CV_32FC3);
if(type == NORMALIZE_TO_1)
Idest.convertTo(Idest,CV_32FC3,1/255.);
return Idest;
}

2

Решение

Я бы предложил:

1. Измените деление по общему коэффициенту на умножение.
то есть из а = а1 / д; b = b1 / d до d_1 = 1 / d; а = а1 * д_1; b = b1 * d_1

2. Исключить четыре критерия if для одной билинейной интерполяции.

Я не уверен, поможет ли это вам. Вы могли бы попробовать.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector