title: Accessing to OpenCv cell values of Mat from native c++ function of android app
body: <p>:)
  I'm programming an algorithm for detect symmetric radial center of an image, to detect eyes position into face framePicture. I know that already exist a project of public domain that do this work, but i would base my work about another kind of studies.</p>
  
  <p>This is the scenario:</p>
  
  <p>Doing by hand this manipulation frame by frame, i have seen that writting code on java layer, like this:</p>
  
  <pre><code>private Mat mGray = new Mat(height,width,CvType.CV_8U);
  private Mat mOut = new Mat(height,width,CvType.CV_8U);
  private Mat mIntermediateMat = Mat.zeros(height,width,CvType.CV_32F);   
  
  [...common methods of opencv app...]
  
  public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
  
      switch (ImageManipulationsActivity.viewMode) {
      case ImageManipulationsActivity.VIEW_MODE_RGBA:
          mOut = inputFrame.rgba();
          break;
  
      case ImageManipulationsActivity.VIEW_MODE_MODIFY:
          mGray = inputFrame.gray();
  
          int h = mGray.rows();
          int w = mGray.cols();
  
          int sobxVal,sobyVal;    
  
          /** 
          * Appling manually sobel filtering to calculate dx and dy image, 
          * moreover calculate magnitudo matrix and cosValue and sinValue
          * matrices for computing, using lut techniques.
          */
          for(int i = 1; i &lt; h-1; i++)
              for(int j = 1; j &lt; w-1; j++) {
                  sobxVal = (int) (
                          ((int)mGray.get(i-1,j)[0] &lt;&lt; 1) +
                          mGray.get(i-1,j-1)[0] +
                          mGray.get(i-1,j+1)[0] - (
                          ((int)mGray.get(i+1,j)[0] &lt;&lt; 1) +
                          mGray.get(i+1,j-1)[0] +
                          mGray.get(i+1,j+1)[0] ) );
                  sobyVal = (int) (
                          ((int)mGray.get(i,j-1)[0] &lt;&lt; 1) +
                          mGray.get(i-1,j-1)[0] +
                          mGray.get(i+1,j-1)[0] - (
                          ((int)mGray.get(i,j+1)[0] &lt;&lt; 1) +
                          mGray.get(i-1,j+1)[0] +
                          mGray.get(i+1,j+1)[0] ) );
  //      compute magnitudo and atan2
              }
  
  //      ...other calculations...
  
          Core.convertScaleAbs(mIntermediateMat, mOut);
  
      }
  
      return mOut;
  }
  </code></pre>
  
  <p>is not all efficient! So I decided to write c++ for a native function to manipulate matrix in this way:</p>
  
  <p>Code by c++ side</p>
  
  <pre><code>#include &lt;jni.h&gt;
  #include &lt;opencv2/core/core.hpp&gt;
  #include &lt;opencv2/imgproc/imgproc.hpp&gt;
  #include &lt;opencv2/features2d/features2d.hpp&gt;
  #include &lt;opencv2/highgui/highgui.hpp&gt;
  #include &lt;math.h&gt;
  #include &lt;vector&gt;
  
  #include &lt;android/log.h&gt;
  
  #define LOG_TAG "Example Filter"
  #define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
  
  #define RADIUS 10
  #define _K      9.9
  #define _A      2   //radial strictness parameter, found experimentally
  using namespace std;
  
  using namespace cv;
  
  extern "C" {
  JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial2_Tutorial2Activity_FindFeatures(
          JNIEnv* env, 
          jobject, 
          jlong addrGray, 
          jlong addrRgba, 
          jlong addrlutCosSin,
          jlong addrlutM );
  
  JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial2_Tutorial2Activity_FindFeatures(
          JNIEnv* env, 
          jobject, 
          jlong addrGray, 
          jlong addrOut, 
          jlong addrlutCosSin,
          jlong addrlutM )
  {
      Mat&amp; mGr  = *(Mat*)addrGray;
      Mat&amp; mOut = *(Mat*)addrOut;
      Mat&amp; lutCosSin = *(Mat*)addrlutCosSin;
      Mat&amp; lutM = *(Mat*)addrlutM;
      int w = mGr.cols;
      int h = mGr.rows;
      double sobelxVal,sobelyVal,angle;
  
      Mat magnitudo(h,w,CV_32F,Scalar(0));
      Mat xMat(h,w,CV_8S,Scalar(0));
      Mat yMat(h,w,CV_8S,Scalar(0));
      Mat oMat(h,w,CV_32F,Scalar(0));
      Mat mMat(h,w,CV_32F,Scalar(0));
      /*
       * Convolves Matrix with Sobel ky kernel and Sobel kx kernel
       *ky = [ 1  2  1 ;
       *       0  0  0 ;
       *      -1 -2 -1 ]
       *
       *kx = [ 1  0 -1 ;
       *       2  0 -2 ;
       *       1  0 -1 ]
       *
       * doing dedicated computation 
       */
      for( int i = 1; i &lt; h-1; i++ )
      {
          for (int j = 1; j &lt; w-1; j++ )
          {
              sobelxVal = (mGr.at&lt;int&gt;(i-1,j) &lt;&lt; 1) +
                      mGr.at&lt;int&gt;(i-1,j-1) +
                      mGr.at&lt;int&gt;(i-1,j+1) - (
                      (mGr.at&lt;int&gt;(i+1,j) &lt;&lt; 1) +
                      mGr.at&lt;int&gt;(i+1,j-1) +
                      mGr.at&lt;int&gt;(i+1,j+1) );
              sobelyVal = (mGr.at&lt;int&gt;(i,j-1) &lt;&lt; 1) +
                      mGr.at&lt;int&gt;(i-1,j-1) +
                      mGr.at&lt;int&gt;(i+1,j-1) - (
                      (mGr.at&lt;int&gt;(i,j+1) &lt;&lt; 1) +
                      mGr.at&lt;int&gt;(i-1,j+1) +
                      mGr.at&lt;int&gt;(i+1,j+1) );
              magnitudo.at&lt;double&gt;(i,j) = lutM.at&lt;double&gt;((int)sobelxVal+255/4,(int)sobelxVal+255/4);
              angle = floor(atan2(sobelyVal,sobelxVal)*180/M_PI);
              xMat.at&lt;double&gt;(i,j) = lutCosSin.at&lt;double&gt;(0,angle);
              yMat.at&lt;double&gt;(i,j) = lutCosSin.at&lt;double&gt;(1,angle);
          }
      }
  
  // other code calculation to determine mOut matrix values
  
  }
  }
  </code></pre>
  
  <p>By java code side</p>
  
  <pre><code>private Mat mRgba;
  private Mat mGray;
  /*
   * Matrix of 360 cols and 2 rows
   * row[0] cos values
   * row[1] sin values
   */
  private static Mat lutCosSin;
  
  /*
   * Matrix 510 x 510 
   * where lutM(i,j) = atan2(i,j)
   */
  private static Mat lutMagnitudo
  
  // common methods and declarations...
  
  public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
      final int viewMode = mViewMode;
      switch (viewMode) {
      case VIEW_MODE_RGBA:
          // input frame has RBGA format
          mRgba = inputFrame.rgba();
          break;
      case VIEW_MODE_FEATURES:
          // input frame has RGBA format
          mGray = inputFrame.gray();
          mRgba = Mat.zeros(mGray.rows(), mGray.cols(), mGray.type());
          FindFeatures(
          mGray.getNativeObjAddr(), 
          mRgba.getNativeObjAddr(), 
          lutCosSin.getNativeObjAddr(), 
          lutMagnitudo.getNativeObjAddr()
          );
  
          //Core.convertScaleAbs(mRgba, mRgba);
  //            Log.d(TAG, "Called native function :"+mRgba.submat(new Range(0,5), new Range(0,5)).toString()+
  //                  "\nAngles matrix:"+mGray);
          break;
      }
  
      return mRgba;
  }
  
  public native void FindFeatures(long matAddrGr, long matAddrRgba, long matAddrlutCS, long matAddrlutM);
  </code></pre>
  
  <p>the first important issue of this snipped code is that on accessing to mGr cells with "at" method  in this way:</p>
  
  <pre><code>mGr.at&lt;int&gt;(i,j)
  </code></pre>
  
  <p>previus check that mGr type is int, the returned values isn't the effective gray level pixel of gray frame (i saw it by log).</p>
  
  <p>I suppose that there are linkin bug of matrix from java code to c++ code, but i'm not sure for this.</p>
  
  <p>I hope may anyone help me to solve this issue XD !!</p>