Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to access nth channel of a Mat in opencv?

I know how to access three channels cv::Mat using Vec3b. But now I have an n channel cv::Mat and n is not constant (to use cv::Vec<uchar, n>). How I can access cv::Mat channels now?

like image 680
ahamid555 Avatar asked Jul 27 '17 11:07

ahamid555


2 Answers

Let's say n = 10 and we want to access 4th channel of pixel (i, j). Here's a simple example:

typedef cv::Vec<uchar, 10> Vec10b;

// ....

// Create the mat
cv::Mat_<Vec10b> some_mat;

// Access 4th channel
uchar value = some_mat.at<Vec10b>(i,j)(4); 

// or 
uchar value = some_mat.at<Vec10b>(i,j)[4];

Hope this helps you. Notice that you can omit the typedef line, I just think it's easier this way.

like image 86
DimChtz Avatar answered Oct 13 '22 20:10

DimChtz


To be able to handle arbitrary number of channels, you can use cv::Mat::ptr and some pointer arithmetics.

For example, a simple approach that supports only CV_8U data type would be as follows:

#include <opencv2/opencv.hpp>
#include <cstdint>
#include <iostream>

inline uint8_t get_value(cv::Mat const& img, int32_t row, int32_t col, int32_t channel)
{
    CV_DbgAssert(channel < img.channels());
    uint8_t const* pixel_ptr(img.ptr(row, col));
    uint8_t const* value_ptr(pixel_ptr + channel);
    return *value_ptr;
}

void test(uint32_t channel_count)
{
    cv::Mat img(128, 128, CV_8UC(channel_count));
    cv::randu(img, 0, 256);

    for (int32_t i(0); i < img.channels(); ++i) {
        std::cout << i << ":" << get_value(img, 32, 32, i) << "\n";
    }
}

int main()
{
    for (uint32_t i(1); i < 10; ++i) {
        test(i);
    }

    return 0;
}
like image 28
Dan Mašek Avatar answered Oct 13 '22 20:10

Dan Mašek