Ask Your Question
2

vec3b has more than 3 elements?

asked 2019-06-05 10:41:19 -0600

ac17407 gravatar image

updated 2019-06-05 10:42:27 -0600

I was using imread to load a 3-channel png image and accessing the bgr pixel values through:

image.at<vec3b>(x,y)[0]

image.at<vec3b>(x,y)[1]

image.at<vec3b>(x,y)[2]

However, I found that vec3b[n] (n>=3) also contain some values. Any ideas on what these values indicate? Shouldn't vec3b only contain three values representing bgr channels?

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
2

answered 2019-06-05 11:21:01 -0600

sjhalayka gravatar image

updated 2019-06-05 11:32:48 -0600

Does image.at<vec3b>(x,y)[3] == image.at<vec3b>(x+1,y)[0], or image.at<vec3b>(x,y)[3] == image.at<vec3b>(x,y+1)[0], or something like that?

In any case, why would you do that when you know that'll cause a memory access violation / segfault?

And why not use the data member pointer, instead of the at function? See the following code that alters an OpenCV Mat by using the data member.

If you find my answer to be helpful, then please upvote it and mark it as correct. Thank you.

#include <opencv2/opencv.hpp>
using namespace cv;

#include <iostream>
using namespace std;

int main(void)
{
    Mat frame = imread("sparks.png");

    if (frame.empty())
    {
        cout << "Error loading image file" << endl;
        return -1;  
    }   

    const size_t num_channels = 3;

    for (int x = 0; x < frame.cols; x++)
    {
        for (int y = 0; y < frame.rows; y++)
        {
            // Make a blue border around the image
            if (x == 0 || x == (frame.cols - 1) || y == 0 || y == (frame.rows - 1))
            {
                size_t index = y*frame.cols*num_channels + x*num_channels;

                frame.data[index + 0] = 255; // B
                frame.data[index + 1] = 127; // G
                frame.data[index + 2] = 0; // R 
            }
        }
    }

    imshow("frame", frame);

    waitKey();

    return 0;
}

Sample image, sparks.png:

image description

edit flag offensive delete link more

Comments

Thanks for the suggestion. It works! So only accessing the first three elements using at is safe?

ac17407 gravatar imageac17407 ( 2019-06-06 05:40:06 -0600 )edit

Yes, only then is it safe. Best of luck to you. And, remember that there are also 1-channel and 4-channel images.

sjhalayka gravatar imagesjhalayka ( 2019-06-06 10:00:45 -0600 )edit
3

answered 2019-06-05 12:01:30 -0600

LBerger gravatar image

My code :

    Mat com = (Mat_<uchar>(4, 3) << 1, 2, 3, 4, 5, 6, 255, 255, 0, 255, 255, 255);
    cout << int(com.at<Vec3b>(0, 0)[2]) << endl;
    cout << int(com.at<Vec3b>(0, 0)[3]) << endl;

really a bad code but it is for demo. com is a CV_8UC1 and not a Vec3b. Now in release result is :

3
4

Vec3b is only char* Now in debug :

3
OpenCV(4.1.0-dev) Error: Assertion failed ((unsigned)i < (unsigned)cn) in cv::Vec<unsigned char,3>::operator [], file G:\Lib\install\opencv\include\opencv2/core/matx.hpp, line 1116
4

opencv throw an exception

I think in release you can use setLog to throw an exception

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2019-06-05 10:41:19 -0600

Seen: 3,487 times

Last updated: Jun 05 '19