choucavalier
choucavalier

Reputation: 2770

(opencv) imread with CV_LOAD_IMAGE_GRAYSCALE yields a 4 channels Mat

The following code reads an image from a file into a cv::Mat object.

#include <string>

#include <opencv2/opencv.hpp>

cv::Mat load_image(std::string img_path)
{
  cv::Mat img = cv::imread(img_path, CV_LOAD_IMAGE_GRAYSCALE);
  cv::Scalar intensity = img.at<uchar>(0, 0);
  std::cout << intensity << std::endl;
  return img;
}

I would expect the cv::Mat to have only one channel (namely, the intensity of the image) but it has 4.

$ ./test_load_image
[164, 0, 0, 0]

I also tried converting the image with

cv::Mat gray(img.size(), CV_8UC1);
img.convertTo(gray, CV_8UC1);

but the gray matrix is also a 4 channels one.

I'd like to know if it's possible to have a single channel cv::Mat. Intuitively, that's what I would expect to have when dealing with a grayscale (thus, single channel) image.

Upvotes: 0

Views: 657

Answers (1)

Miki
Miki

Reputation: 41765

The matrix is single channel. You're just reading the values in the wrong way.

Scalar is a struct with 4 values. Constructing a Scalar with a single value will result in a Scalar with the first value set, and the remaining at zero.

In your case, only the first values make sense. The zeros are as default for Scalar.

However, you don't need to use a Scalar:

uchar intensity = img.at<uchar>(0, 0);
std::cout << int(intensity) << std::endl; // Print the value, not the ASCII character

Upvotes: 5

Related Questions