Ask Your Question
0

Convert Mat to char array (and vice-versa)

asked 2015-01-29 05:49:52 -0600

updated 2015-01-29 05:53:58 -0600

Hi,

I tried converting a grayscale, single channel Mat (type: 8UC1) to a char[] array but somewhere it crashes. I am using android ndk and I'm coding in c++ in one of the native classes. I only get fatal signal 11 as error (probably refers to wrong memory access?).

Here's the code I am using:

unsigned char buffer[height * width];

for (int j = 0; j < height; j++) {
    for (int i = 0; i < width; i++) {
        uchar& uxy = myMat.at<uchar>(j, i);
        int color = (int) uxy;
        buffer[j * width + i] = color;
        }
}

I want to use a byte[] buffer to store the image (mat) and I need to access it's elements like this: y * width + x (where y=row index, x=column index). Because I don't have a byte[] structure in Android native, I decided to use a char[] array.

Is there any faster option? And I also want to convert the byte[] array (in my case, char[] array) back to a Mat. Thanks!

Edit:

Converting back code (untested!):

Mat convertToMat(unsigned char *buffer) {
    Mat tmp(width, height, CV_8UC1);
    for (int x = 0; x < height; x++) {
        for (int y = 0; y < width; y++) {
            int value = (int) buffer[x * width + y];
            tmp.at<int>(y, x) = value; 
        }
    }
    return tmp;
}

myMat = convertToMat(buffer);
edit retag flag offensive close merge delete

Comments

I don't really see what you are trying to do with casting it from/to int. Do you know that an int is 4 bytes? Further I would suggest you to find the "somewhere" it crashes with a debugger.

boaz001 gravatar imageboaz001 ( 2015-01-29 09:34:51 -0600 )edit

2 answers

Sort by ยป oldest newest most voted
0

answered 2015-01-29 06:02:38 -0600

updated 2015-01-29 06:03:00 -0600

Why would you go by all this trouble if Mat already has a field contain its data in the form of an unsigned char*?

cv::Mat test;

test = imread("somepath");

unsigned char* dataMat = test.data;

Now, dataMat is pointing to the first element of test's pixel data.

edit flag offensive delete link more

Comments

I have a complex algorithm that accesses data from a byte[] (char[]) array in the way I described in my question. It will take too long to convert the entire algo.. Also, if I change data in the array, I will want to convert back to a Mat at a later phase.

razvan gravatar imagerazvan ( 2015-01-29 06:42:51 -0600 )edit

Well, let me just point out that you shouldn't want to keep a inefficient implementation just because you spent so much time on it. Why would you go through all pixels of a Mat, a very slow process, when you can just assign pointers?! That doesn't make any sense.

To convert back the bytes to the Mat you just need to assign again: test.data = (unsigned char*) bytes;

Pedro Batista gravatar imagePedro Batista ( 2015-01-29 10:41:39 -0600 )edit

Anyway, your code is crashing probably because of the following line:

tmp.at<int>(y, x) = value;

Your Mat is of type unsigned char (CV_8UC1), and you are trying to access it as integers. So change it to

tmp.at<uchar>(y, x) = value;

Pedro Batista gravatar imagePedro Batista ( 2015-01-29 10:44:28 -0600 )edit

I only process a small portion of the entire Mat, but I will take into account your suggestion with mat.data() . Thanks for the answer, I will check the code and get back to you!

razvan gravatar imagerazvan ( 2015-01-29 10:53:13 -0600 )edit
0

answered 2015-02-08 18:18:10 -0600

Eventually I changed the conversion to use pointers:

Convert mat to buffer:

unsigned char buffer[height * width];

uchar* p;
for (i = 0; i < height; ++i) {
    p = myMat.ptr<uchar>(i);
    for (j = 0; j < width; ++j) {
        buffer[i * width + j] = p[j];
    }
}
edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2015-01-29 05:49:52 -0600

Seen: 38,042 times

Last updated: Feb 08 '15