Como posso reescrever esse warp-affine usando o OpenCV?

Estou tentando otimizaresta código, em particular:

bool interpolate(const Mat &im, float ofsx, float ofsy, float a11, float a12, float a21, float a22, Mat &res)
{         
   bool ret = false;
   // input size (-1 for the safe bilinear interpolation)
   const int width = im.cols-1;
   const int height = im.rows-1;
   // output size
   const int halfWidth  = res.cols >> 1;
   const int halfHeight = res.rows >> 1;
   float *out = res.ptr<float>(0);
   for (int j=-halfHeight; j<=halfHeight; ++j)
   {
      const float rx = ofsx + j * a12;
      const float ry = ofsy + j * a22;
      for(int i=-halfWidth; i<=halfWidth; ++i)
      {
         float wx = rx + i * a11;
         float wy = ry + i * a21;
         const int x = (int) floor(wx);
         const int y = (int) floor(wy);
         if (x >= 0 && y >= 0 && x < width && y < height)
         {
            // compute weights
            wx -= x; wy -= y;
            // bilinear interpolation
            *out++ = 
               (1.0f - wy) * ((1.0f - wx) * im.at<float>(y,x)   + wx * im.at<float>(y,x+1)) +
               (       wy) * ((1.0f - wx) * im.at<float>(y+1,x) + wx * im.at<float>(y+1,x+1));
         } else {
            *out++ = 0;
            ret =  true; // touching boundary of the input            
         }
      }
   }
   return ret;
}

De acordo com o Intel Advisor, essa é uma função que consome muito tempo. Noesta pergunta eu perguntei como eu poderia otimizar isso, ealguém me fez notar que isso é uma transformação de distorção.

Agora, como não sou o responsável pelo processamento de imagens, tive que leresta artigo para entender o que é uma transformação afinada por urdidura.

No meu entender, dado um pontop=(x,y), você aplica uma transformaçãoA (uma matriz 2x2) e depois traduza-a por um vetorb. Então, o ponto obtido após a transformaçãop' pode ser expresso comop' = A*p+b. Por enquanto, tudo bem.

No entanto, estou um pouco confuso sobre como aplicarcv::warpAffine() para este caso. Primeiro de tudo, a partir da função acimainterpolate() Eu posso ver apenas os 4A componentes (a11, a12, a21, a22), enquanto eu não consigo ver os 2b componentes ... eles sãoofsx eofy?

além do que, além do mais Observe que essa função retorna um valor bool, que não é retornado porwarpAffine (esse valor booleano é usadoaqui na linha 126), então não sei se consegui isso com a função OpenCV.

Mas acima de tudo, estou tão confuso comfor (int j=-halfHeight; j<=halfHeight; ++j) efor(int i=-halfWidth; i<=halfWidth; ++i) e toda a porcaria que acontece lá dentro.

Eu entendi aquilo:

        // bilinear interpolation
        *out++ = 
           (1.0f - wy) * ((1.0f - wx) * im.at<float>(y,x)   + wx * im.at<float>(y,x+1)) +
           (       wy) * ((1.0f - wx) * im.at<float>(y+1,x) + wx * im.at<float>(y+1,x+1));

É o queINTER_LINEAR faz, mas além disso, estou totalmente perdido.

Então, para testar minha abordagem, tentei fazer o equivalente à linha 131 deesta Como:

     bool touchesBoundary = interpolate(smoothed, (float)(patchImageSize>>1), (float)(patchImageSize>>1), imageToPatchScale, 0, 0, imageToPatchScale, patch);
     Mat warp_mat( 2, 3, CV_32FC1 );
     float a_11 = imageToPatchScale;
     float a_12 = 0;
     float a_21 = 0;
     float a_22 = imageToPatchScale;
     float ofx = (float)(patchImageSize>>1);
     float ofy = (float)(patchImageSize>>1);
     float ofx_new = ofx - a12*halfHeight - a11*halfWidth;
     float ofy_new = ofy - a22*halfHeight - a21*halfWidth;
     warp_mat.at<float>(0,0) = imageToPatchScale;
     warp_mat.at<float>(0,1) = 0;
     warp_mat.at<float>(0,2) = ofx_new;
     warp_mat.at<float>(1,0) = 0;
     warp_mat.at<float>(1,1) = imageToPatchScale;
     warp_mat.at<float>(1,2) = ofy_new;
     cv::Mat myPatch;
     std::cout<<"Applying warpAffine"<<std::endl;
     warpAffine(smoothed, myPatch, warp_mat, patch.size());
     std::cout<<"WarpAffineApplied patch size="<<patch.size()<<" myPatch size="<<myPatch.size()<<std::endl;
     cv::Mat diff = patch!=myPatch;
     if(cv::countNonZero(diff) != 0){
         throw std::runtime_error("Warp affine doesn't work!");
     }
     else{
         std::cout<<"It's working!"<<std::endl;
     }

E, é claro, na primeira vez que isso é executado, a exceção é lançada (portanto, os dois métodos não são equivalentes) ... Como posso resolver isso?

Alguém pode me ajudar, por favor?

Como já escrevi nos comentários, a matriz resultante, usando o código acima, é uma matriz zero. Enquanto isso émaPatch obtido usandoofx eofy ao invés deofx_new eofy_new, enquantopatch tem todos os valores diferentes de zero:

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 229.78679, 229.5752, 229.11732, 229.09612, 229.84615, 230.28633, 230.35257, 230.70955, 230.99368, 231.00777, 231.20511, 231.63196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230.60367, 230.16417, 230.07034, 230.06793, 230.02016, 230.14925, 230.60413, 230.84822, 230.92368, 231.02249, 230.99162, 230.9149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232.76547, 231.39716, 231.26674, 231.34512, 230.746, 230.25253, 229.65276, 227.83998, 225.43642, 229.57695, 230.31363, 230.16011, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234.01663, 232.88118, 232.15475, 231.40129, 223.21553, 208.22626, 205.58975, 214.53882, 220.32681, 228.11552, 229.31509, 228.86545, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234.04565, 233.00443, 231.9902, 230.14912, 198.0849, 114.86175, 97.901344, 160.0218, 217.38528, 231.07045, 231.13109, 231.10185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233.293, 232.69095, 217.03873, 190.56714, 167.61592, 94.968391, 81.302032, 150.72263, 194.79535, 215.15564, 230.01717, 232.37894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 231.70988, 227.81319, 207.59377, 173.35149, 113.88276, 73.171112, 71.523285, 103.05875, 160.05588, 194.65132, 226.4287, 231.45871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 231.93924,, 224.24269, 199.1693, 150.65695, 103.33984, 79.489555, 77.509094, 87.893059, 122.01918, 168.37506, 219.22086, 231.05161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232.2706, 232.12926, 206.97635, 127.69308, 92.714355, 81.512207, 74.89402, 75.968353, 84.518105, 157.07962, 223.18773, 229.92766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232.64882, 222.16704, 161.95021, 92.577881, 83.757164, 76.764214, 67.041054, 66.195595, 71.112335, 131.66878, 188.27278, 217.6635, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234.77202, 231.75511, 178.64326, 104.27015, 95.664223, 82.791382, 67.68969, 72.78054, 72.355469, 104.77696, 172.32361, 204.92691, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 236.49684, 235.5802, 185.34337, 115.96995, 106.85963, 82.980408, 61.703068, 69.540627, 76.200562, 82.429321, 101.46993, 119.75877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Example of smoothed:

[229.78679, 229.67955, 229.56825, 229.40576, 229.08748, 228.90848, 229.13086, 229.53154, 229.91875, 230.1864, 230.31964, 230.34709, 230.35471, 230.51445, 230.81174, 230.97459, 231.00513, 231.00487, 231.01001, 231.08649, 231.30977, 231.55736, 231.71651;
 229.71237, 229.63612, 229.65092, 229.72298, 229.65163, 229.58559, 229.68594, 229.8093, 229.91052, 230.0466, 230.22325, 230.43683, 230.67668, 230.87794, 230.98672, 231.02505, 231.03383, 231.03091, 231.02097, 231.03201, 231.09761, 231.17659, 231.23175;
 230.66309, 230.37627, 230.1866, 230.1675, 230.09061, 230.03766, 230.10495, 230.09256, 230.01401, 230.03775, 230.18376, 230.42041, 230.67554, 230.82742, 230.84885, 230.87372, 230.94225, 231.01442, 231.02843, 231.00027, 230.97455, 230.9254, 230.86211;
 232.00514, 231.33768, 230.82791, 230.77686, 230.84599, 230.88741, 230.84238, 230.58279, 230.27737, 230.22282, 230.2531, 230.28053, 230.33743, 230.24406, 229.8969, 229.53674, 229.66661, 230.42201, 230.86761, 230.84827, 230.7677, 230.72296, 230.69333;
 232.84413, 232.07454, 231.4113, 231.24339, 231.31792, 231.42, 231.39203, 231.09439, 230.71797, 230.52229, 230.16359, 229.71872, 229.5307, 228.81219, 226.98767, 224.92525, 225.05101, 228.29745, 230.37059, 230.39821, 230.14323, 230.08817, 230.12051;
 233.69714, 233.27977, 232.63216, 231.97507, 231.61856, 231.50835, 231.37958, 230.94897, 230.22003, 229.17024, 227.78331, 226.92528, 227.3483, 226.49516, 223.07671, 219.54231, 220.02966, 225.84485, 229.56601, 229.69946, 229.2941, 228.91028, 228.47911;
 234.07579, 233.56334, 232.87689, 232.33269, 232.23909, 232.26355, 231.24196, 227.51971, 220.59465, 210.97746, 202.39467, 198.75334, 202.68945, 209.23911, 214.57399, 218.0966, 221.80714, 226.69366, 229.27985, 229.35699, 229.21922, 229.04704, 228.72176;
 234.02943, 233.1526, 232.62421, 232.68416, 232.63794, 232.74126, 230.84375, 220.47586, 197.81956, 164.03839, 136.08931, 125.05849, 134.9079, 158.19888, 186.67014, 209.67909, 223.89606, 229.51706, 230.72685, 230.50046, 230.31461, 230.29973, 230.30855;
 234.04939, 233.55843, 233.05295, 232.52957, 231.76837, 231.33992, 229.65753, 220.00912, 191.89427, 140.79909, 97.534477, 80.921623, 93.553299, 127.26912, 171.24872, 205.13603, 224.29935, 230.74513, 231.68158, 231.38503, 231.22385, 231.26157, 231.31372;
 233.67462, 233.69278, 233.09642, 230.73448, 225.79077, 220.33292, 216.52835, 212.6403, 192.7964, 142.2917, 93.74559, 73.776016, 92.972778, 136.18417, 183.40891, 209.98003, 220.25392, 225.67984, 229.14565, 230.97379, 231.68997, 231.87923, 231.80464;
 233.16579, 232.95818, 232.5157, 227.84683, 212.53104, 193.47, 179.53844, 171.00941, 154.97589, 118.29485, 82.342369, 67.311531, 83.867973, 119.85723, 158.53325, 180.67912, 191.74194, 203.44008, 216.87592, 227.59789, 231.31285, 232.24002, 232.91658;
 232.21611, 231.93192, 231.80423, 227.06053, 208.82571, 183.86725, 160.27481, 136.63663, 112.56454, 89.978371, 73.328209, 66.652176, 73.406273, 90.259987, 113.70027, 138.08961, 159.2791, 178.08627, 201.78604, 223.79007, 230.86775, 231.59146, 232.17819;
 231.5118, 230.38042, 225.97289, 217.07312, 205.34308, 192.29631, 174.19812, 142.59843, 105.71719, 80.45845, 68.488274, 67.021088, 73.29406, 86.493896, 110.19484, 145.04185, 174.52554, 187.26851, 202.64322, 221.51042, 229.94238, 231.48595, 231.08746;
 231.67564, 229.07423, 217.57478, 197.87076, 181.8385, 167.48799, 148.19232, 124.3977, 100.57513, 83.081154, 73.410683, 71.723045, 77.010704, 85.107651, 98.029099, 121.88382, 145.77963, 161.43314, 184.43152, 212.01347, 227.27411, 231.84755, 231.33319;
 232.0773, 231.27109, 227.09813, 218.50165, 206.31781, 182.26494, 144.46196, 115.64604, 99.402679, 87.584351, 79.348366, 76.547188, 79.332504, 82.244148, 86.3069, 100.71764, 122.39668, 147.5081, 179.02258, 210.10269, 226.37909, 231.12947, 230.34335;
 232.11732, 231.67418, 231.89207, 229.20001, 213.83904, 180.2238, 134.82561, 107.20949, 97.260231, 88.765694, 80.533333, 75.941055, 76.372505, 77.851997, 78.464508, 81.875244, 96.896721, 131.28108, 175.47084, 213.05406, 227.81297, 230.31032, 229.60373;
 232.36255, 232.00981, 232.29773, 226.30051, 199.48029, 156.13557, 112.30969, 91.346344, 88.295509, 85.21006, 79.416222, 74.552238, 73.894844, 75.069275, 74.349594, 72.166176, 85.453522, 128.47208, 180.33452, 218.87312, 229.58446, 229.77406, 230.03587;
 232.52425, 231.2455, 226.65468, 210.90804, 174.35748, 128.79022, 92.861343, 79.050415, 78.796555, 76.526512, 71.317635, 67.324234, 67.506172, 69.193619, 68.941025, 67.913399, 82.488945, 124.88449, 171.48178, 203.84958, 215.13747, 221.22523, 228.15715;
 232.74571, 229.80283, 217.69687, 189.34862, 145.52664, 104.71513, 84.893997, 83.699814, 88.473457, 86.446617, 77.834595, 68.74688, 65.925613, 65.426163, 63.241882, 61.236107, 69.682426, 97.213646, 131.60564, 160.99944, 180.75278, 202.22523, 223.85883;
 233.80923, 232.82767, 227.83594, 209.05493, 166.58002, 120.64989, 94.880188, 89.971268, 93.209671, 90.605591, 80.354561, 69.243584, 67.490875, 70.700516, 72.353569, 70.053764, 70.773293, 86.577957, 121.76624, 160.51776, 182.91074, 203.17424, 224.06786;
 235.62155, 235.22169, 234.91901, 223.3783, 181.88362, 132.80327, 104.59508, 97.904762, 98.472153, 91.749123, 79.65731, 69.025223, 66.806007, 70.64135, 75.239159, 74.961838, 73.406227, 83.469612, 118.84832, 161.62743, 181.61127, 192.7933, 203.54196;
 236.851, 236.1096, 235.65253, 224.02559, 182.0352, 134.56085, 111.10134, 106.82736, 105.87054, 95.272148, 80.614365, 68.017456, 61.20583, 62.735069, 69.976379, 72.687195, 71.943336, 75.369637, 89.042145, 106.32064, 116.6455, 127.58019, 139.77493;
 236.09546, 235.84727, 235.44041, 223.06668, 180.65508, 134.57915, 114.13975, 110.49339, 107.15049, 93.355858, 77.559898, 65.277794, 58.067509, 62.642029, 76.700447, 81.800919, 80.054298, 80.085251, 82.980927, 87.177017, 92.031647, 100.26192, 109.12404]

questionAnswers(1)

yourAnswerToTheQuestion