Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV cv::Mat 'ones' for multi-channel matrix?

When working with 1-channel (e.g. CV_8UC1) Mat objects in OpenCV, this creates a Mat of all ones: cv::Mat img = cv::Mat::ones(x,y,CV_8UC1).

However, when I use 3-channel images (e.g. CV_8UC3), things get a little more complicated. Doing cv::Mat img = cv::Mat::ones(x,y,CV_8UC3) puts ones into channel 0, but channels 1 and 2 contain zeros. So, how do I use cv::Mat::ones() for multi-channel images?

Here's some code that might help you to see what I mean:

void testOnes() {
 int x=2; int y=2; //arbitrary

 // 1 channel
 cv::Mat img_C1 = cv::Mat::ones(x,y,CV_8UC1);
 uchar px1 = img_C1.at<uchar>(0,0); //not sure of correct data type for px in 1-channel img
 printf("px of 1-channel img: %d \n", (int)px1); //prints 1

 // 3 channels
 cv::Mat img_C3 = cv::Mat::ones(x,y,CV_8UC3); //note 8UC3 instead of 8UC1
 cv::Vec3b px3 = img_C3.at<cv::Vec3b>(0,0);
 printf("px of 3-channel img: %d %d %d \n", (int)px3[0], (int)px3[1], (int)px3[2]); //prints 1 0 0
}

So, I would have expected to see this printout: px of 3-channel img: 1 1 1, but instead I see this: px of 3-channel img: 1 0 0.

P.S. I did a lot of searching before posting this. I wasn't able to resolve this by searching SO for "[opencv] Mat::ones" or "[opencv] +mat +ones".

like image 337
solvingPuzzles Avatar asked Sep 09 '12 22:09

solvingPuzzles


People also ask

What is a CV :: mat?

In OpenCV the main matrix class is called Mat and is contained in the OpenCV-namespace cv. This matrix is not templated but nevertheless can contain different data types. These are indicated by a certain type-number. Additionally, OpenCV provides a templated class called Mat_, which is derived from Mat.

How do I know what type of CV mat I have?

We can check the Data Type of a cv::Mat using “type()” method. This is a method you can use for checking the type of an cv::Mat.

What is the use of mat in OpenCV?

The Mat class of OpenCV library is used to store the values of an image. It represents an n-dimensional array and is used to store image data of grayscale or color images, voxel volumes, vector fields, point clouds, tensors, histograms, etc.

What is cv_64f?

Here's example for CV_64FC1 : CV_ - this is just a prefix. 64 - number of bits per base matrix element (e.g. pixel value in grayscale image or single color element in BGR image) F - type of the base element.


2 Answers

I don't use OpenCV, but I believe I know what's going on here. You define a data-type, but you are requesting the value '1' for that. The Mat class appears not to pay attention to the fact that you have a multi-channel datatype, so it simply casts '1' as a 3-byte unsigned char.

So instead of using the ones function, just use the scalar constructor:

cv::Mat img_C3( x, y, CV_8UC3, CV_RGB(1,1,1) );
like image 62
paddy Avatar answered Sep 17 '22 08:09

paddy


You can also initialize like this:

Mat img;

/// Lots of stuff here ...

// Need to initialize again for some reason:
img = Mat::Mat(Size(width, height), CV_8UC3, CV_RGB(255,255,255));
like image 34
Amyr Avatar answered Sep 17 '22 08:09

Amyr