问题
I got confused with the openCV documentation mentioned here.
As per the documentation, if i create an image with "uchar", the pixels of that image can store unsigned integer values but if i create an image using the following code:
Mat image;
image = imread("someImage.jpg" , 0); // Read an image in "UCHAR" form
or by doing
image.create(10, 10, CV_8UC1);
for(int i=0; i<image.rows; i++)
{
for(int j=o; j<image.cols; j++)
{
image.at<uchar>(i,j) = (uchar)255;
}
}
and then if i try to print the values using
cout<<" "<<image.at<uchar>(i,j);
then i get some wierd results at terminal but if i use the following statement then i can get the values inbetween 0-255.
cout<<" "<<(int)image.at<uchar>(i,j); // with TYPECAST
Question: Why do i need to do typecast to get print the values in range 0-255 if the image itself can store "unsigned integer" values.
回答1:
If you try to find definition of uchar
(which is pressing F12 if you are using Visual Studio), then you'll end up in OpenCV's core/types_c.h:
#ifndef HAVE_IPL
typedef unsigned char uchar;
typedef unsigned short ushort;
#endif
which standard and reasonable way of defining unsigned integral 8bit type (i.e. "8-bit unsigned integer") since standard ensures that char
always requires exactly 1 byte of memory. This means that:
cout << " " << image.at<uchar>(i,j);
uses the overloaded operator<<
that takes unsigned char
(char
), which prints passed value in form of character, not number.
Explicit cast, however, causes another version of <<
to be used:
cout << " " << (int) image.at<uchar>(i,j);
and therefore it prints numbers. This issue is not related to the fact that you are using OpenCV at all.
Simple example:
char c = 56; // equivalent to c = '8'
unsigned char uc = 56;
int i = 56;
std::cout << c << " " << uc << " " << i;
outputs: 8 8 56
And if the fact that it is a template confuses you, then this behavior is also equivalent to:
template<class T>
T getValueAs(int i) { return static_cast<T>(i); }
typedef unsigned char uchar;
int main() {
int i = 56;
std::cout << getValueAs<uchar>(i) << " " << (int)getValueAs<uchar>(i);
}
回答2:
Simply, because although uchar
is an integer type, the stream operation <<
prints the character it represents, not a sequence of digits. Passing the type int
you get a different overload of that same stream operation, which does print a sequence of digits.
来源:https://stackoverflow.com/questions/22115302/opencv-documentation-says-that-uchar-is-unsigned-integer-datatype-how