Reputation: 31
I have problem with access to data from Mat.data. I perform operations on picture and I need access to every pixel separately. I have to necessairly operate on simple types (float, int etc). The way I am accesing data is like below:
for (int idx = 0; idx < image.rows; idx++) {
for (int idy = 0; idy < image.cols; idy++) {
int color_tid = idx * image.cols * image.channels() + idy * image.channels();
uint8_t blue = image.data[color_tid];
uint8_t green = image.data[color_tid + 1];
uint8_t red = image.data[color_tid + 2];
float pixelVal = (int) blue + (int) green + (int) red;
(...)
}
}
This approach is working correctly only to square images (NxN pixels), but for NxM there are anomalies outside the square area (smaller edge). Do anyone know any other way to acces data of the picture Mat? Example image (correct result):
anomalies (my problem)
Upvotes: 1
Views: 1609
Reputation: 41765
I recommend to follow the data layout in a Mat
so your loop becomes:
for (int r = 0; r < img.rows; ++r)
{
for (int c = 0; c < img.cols; ++c)
{
uchar* ptr = img.data + img.step[0] * r + img.step[1] * c;
uchar blue = ptr[0];
uchar green = ptr[1];
uchar red = ptr[2];
float pixelVal = blue + green + red;
}
}
You can eventually perform a little less operations like:
for (int r = 0; r < img.rows; ++r)
{
uchar* pt = img.data + img.step[0] * r;
for (int c = 0; c < img.cols; ++c)
{
uchar* ptr = pt + img.step[1] * c;
uchar blue = ptr[0];
uchar green = ptr[1];
uchar red = ptr[2];
float pixelVal = blue + green + red;
}
}
Upvotes: 1
Reputation: 6882
The code in your question contains a few flaws:
Using Mat::at<>
makes the code much simpler:
for(int row = 0; row < image.rows; ++row)
{
for(int col = 0; col < image.cols; ++col)
{
const Vec3b& pt = image.at<Vec3b>(row, col);
float pixelVal = pt[0] + pt[1] + pt[2];
...
}
}
Upvotes: 1