I'm trying to read an image by opencv then pass it from java language to my native library written by C Language not C++. I'm using JNI function and I've seen many samples of c++ code in which Mat Object is used. but my problem is that there isn't any Mat object in "C Language" and the only object I have is CvMat.So when I get my image in my native codes it is a wrong image. I should mention that I can not use c++ for many reasons and the C is my only option to write native code.
My Java Code:
Mat img = Imgcodecs.imread("./mypic.jpg", Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
myClass.getImg(img.getNativeObjAddr())
My Native Code:
JNIEXPORT jfloat JNICALL Java_PredictJNI_getImg
(JNIEnv *env, jobject thisObj, jlong imgPtr)
{
CvMat* img = (CvMat*)imgPtr;
printf("Image Width:%d:" , img->cols);
}
So don't pass whole Mat
structure. Pass just pointer to raw data instead.
//uchar* ptr2imgData = dynamic_cast<uchar *>( imgPtr );
//cv::Mat img( cv::Size{ WIDTH, HEIGHT }, CV_8UC3, ptr2imgData ); // C++
uchar* ptr2imgData = (uchar *)imgPtr; // uchar is unsigned char
CvMat* img = cvCreateMat( WIDTH, HEIGHT, CV_8UC3 );
img->ptr = imgPtr;
If type of matrix and/or matrix size may differ, pass additional info in another argument(s). If type of matrix is always the same, leave it hardcoded and pass just pointer to data.
Then construct new Mat
from these data.
I have never written line of Java and I'm proud of it - anyway I know there are no pointers. I found you may use get()
method
myClass.getImg(img.get(0, 0)); // Beginning of the array
or your mentioned getNativeObjAddr()
method
myClass.getImg(img.getNativeObjAddr());
Your solution can't work and invokes undefined behavior, because cvMat
and Mat
are totally different types.