通过尝试使用OpenCV优化java中的以下函数,我变得疯狂了:
static Mat testPossibleCentersFormula(int x, int y, Mat weight, double gx, double gy, Mat outSum){
Mat out = outSum;//new Mat(weight.rows(), weight.cols(), CvType.CV_64F);
float weight_array [] = new float [weight.rows()*weight.cols()];
weight.get(0,0,weight_array);
double out_array [] = new double [weight.rows()*weight.cols()];
out.get(0,0,out_array);
for (int cy = 0; cy < out.rows(); ++cy) {
for (int cx = 0; cx < out.cols(); ++cx) {
if (x == cx && y == cy) {
continue;
}
// create a vector from the possible center to the gradient origin
double dx = x - cx;
double dy = y - cy;
// normalize d
double magnitude = Math.sqrt((dx * dx) + (dy * dy));
dx = dx / magnitude;
dy = dy / magnitude;
double dotProduct = dx*gx + dy*gy;
dotProduct = Math.max(0.0,dotProduct);
// square and multiply by the weight
if (kEnableWeight) {
out_array[cy*out.cols()+cx] = out_array[cy*out.cols()+cx] +dotProduct * dotProduct * (weight_array[cy*out.cols()+cx]/kWeightDivisor);
} else {
out_array[cy*out.cols()+cx] = out_array[cy*out.cols()+cx] +dotProduct * dotProduct;
}
} }
out.put(0, 0, out_array);
return out;
}
该功能为视频中的每个帧逐个像素地访问某些图片的值,并且无法实时使用它。
我已经将Mat操作转换为数组操作,这已经产生了很大的不同,但它仍然非常慢。你有没有办法替换嵌套的for循环?
非常感谢,
答案 0 :(得分:-1)
正如我在上面的评论中提到的那样,我认为weight_array
和out_array
的分配非常可疑:我可以找到Mat
mat.get(...)
当你调用float[] weight_array = new float[weight.depth()];
double[] out_array = new double[out.depth()];
for (int cy = 0; cy < out.rows(); ++cy) {
for (int cx = 0; cx < out.cols(); ++cx) {
// Use weight.get(cx, cy, weight_array)
// instead of weight_array[cy*out.cols()+cx].
// Use out.get(cx, cy, out_array) and out.put(cx, cy, out_array)
// instead of out_array[cy*out.cols()+cx] += ...
}
}
时,对于放入比图像深度更大的数组中的内容是无益的,这就像滥用API一样,假设它会返回整个图像的数据。
每次调用方法时都不需要分配这样大的数组。您可以分配一个更小的数组,并在每次迭代时重用它:
weight_array
请注意,这仍然会在每次迭代时分配(可能非常小)数组。如果需要,可以在方法外部分配out_array
和after
,并将其作为参数传递;但我会先按照此处的建议进行尝试,并在必要时进一步优化。