otto
otto

Reputation: 2033

c++ writing data to a given position in an array

I am reading an image with opencv and I want to have an array of images. This is how I init my array. I need to do it with the new keyword because the array is really big.

  unsigned char* imageStack = new unsigned char[frame.cols * frame.rows * channels * numberOfImages];

Now I want to write my image to a position in this array. This is how I tried to do it

int imageStackIndex = imageIndexPosition * frame.cols * frame.rows *channels;
imageStack[imageStackIndex] = frame.data;

But I get this error: error: a value of type "uchar *" cannot be assigned to an entity of type "unsigned char"

Upvotes: 0

Views: 116

Answers (2)

m88
m88

Reputation: 1988

Just so you know the possibility exists, there's safer (and faster, since you don't reallocate) ways to access your matrices content.

std::vector<cv::Mat> mats;
mats.push_back(cv::imread("image1.png"));
mats.push_back(cv::imread("image2.png"));
// etc...
// I would check that mats.back().type() == CV_8UC1 after each push_back so we're sure the following code works...

// reference on the [x=10,y=20] pixel from the 5th matrix in my collection
uchar& pixelRef = mats.at(4).at<uchar>(20,10);

And that's it, you're done.


Anyhow, in your current implementation I'd suggest you to perform a few checks on your frame matrix before copying it to your buffer:

  • assert(frame.data) to make sure your imread (or acquisition through cv::VideoCapture or whatever) didn't fail
  • assert(frame.type() == CV_8UC1) since your copy assumes 8bits pixels
  • assert(frame.isContinuous()) so you're certain there's no gap in memory at the end of each row (although it shouldn't happen if directly read from imread)
  • assert(frame.cols == N && frame.rows == M) with N and M predetermined, since your buffer currently doesn't work with images of varying sizes.

Upvotes: 3

Eric Postpischil
Eric Postpischil

Reputation: 222362

imageStack is a pointer to to the first of some number of unsigned char. imageStack[imageStackIndex] selects one of those char (or attempts to; it may be out of bounds). Therefore, it is an unsigned char.

frame.data is presumably a pointer to unsigned char or is an array, which is automatically converted to a pointer to unsigned char.

Therefore imageStack[imageStackIndex] = frame.data; attempts to assign a pointer to unsigned char to an unsigned char, and that is what the error message complains about.

C++ does not have any feature for copying an entire array by an assignment. If you want to copy the frame.cols * frame.rows * channels bytes of image data pointed to by frame.data to imageStack at the starting offset imageStackIndex, then one way is:

std::memcpy(&imageStack[imageStackIndex], frame.data, frame.cols * frame.rows * channels);

Upvotes: 1

Related Questions