在java中优化嵌套for循环

时间:2016-07-08 07:05:16

标签: java opencv for-loop optimization

通过尝试使用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循环?

非常感谢,

1 个答案:

答案 0 :(得分:-1)

正如我在上面的评论中提到的那样,我认为weight_arrayout_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_arrayafter,并将其作为参数传递;但我会先按照此处的建议进行尝试,并在必要时进一步优化。