1
votes

I am new to C++ and OpenCV, my current project require some convert from Matrix to grayscale image. Here i used the function cvtColor, but for some reason it keep crashing cause the error : "OpenCV error: Assertion failed(scn==3 | scn==4) in cv::cvtColor".
Here my source code:

for (int i = 0; i < 2048; i++)
{
    for (int j = 0; j < 2048; j++)
    {
        t[i][j] = abs((L3[i][j] - L_blurred_3[i][j]) / (sqrt(L2_blurred[i][j] - L_blurred_4[i][j])));
    }
}
Mat tt(2048, 2048, CV_64F, Scalar(0));

for (int i = 0; i < 2048; i++)
{
    for (int j = 0; j < 2048; j++)
    {
        tt.at<double>(i, j) = t[i][j];
    }
}
tt.convertTo(tt, CV_32F);
Mat tgray(2048, 2048, CV_32F, Scalar(0));
cvtColor(tt, tgray, COLOR_BGR2GRAY);

i did make some search on site and google and i have tried many different ways but the result still the same, i know that the problem is my matrix "tt" is a one channel image, so i have 2 main questions:

  1. How to fix this assertion error? Do i need to convert tt to 3 or 4 channels? and how?
  2. Is there any other function that do the same work for 1 channel image?
3
cvtColor(tt, tgray, COLOR_BGR2GRAY); requires a 3 channel input , your tt has only one. why do you want to convert a one-channel Mat into a one-channel Mat ?berak
you probably don't even need the cvtColor() operationberak
but why in matlab the Mat tt and this one : tgray=mat2gray(tt) deosn't give the same output ? i mean,both function is to convert matrix into grayscale image,right ? So if tt is already a grayscale one so what is the function mat2gray(tt) for ?HienPham
opencv != matlab. blind 1:1 code conversion is rarely a good idea here.berak
i know,i'm just wondering,and thank you :DHienPham

3 Answers

2
votes

As dFionov wrote, all images are matrices. If you want to visualize some float values as grayscale image you need to rescale all values to [0..1] range. For example you may use minMaxLoc and convertTo functions as follows:

double minV, maxV;
minMaxLoc(tt, &minV, &maxV);
double alpha = 1. / (maxV - minV);
double beta = -minV * alpha;

Mat gray;
tt.convertTo(gray, CV_32FC1, alpha, beta);
imshow("data", gray);
waitKey();

Ranges for another types are:

  • [0..255] for unsigned char
  • [0..65535] for unsigned short
  • [0..1] for float and double
2
votes

according to http://de.mathworks.com/help/images/ref/mat2gray.html matlab mat2gray scales the values in the matrix to fit the range [0..1] (black = 0, white = 1).

so you could just use

cv::normalize(tt, tgray, 0, 1, cv::NORM_MINMAX);

or in general:

cv::normalize(sourceMat, destinationMat, 0, 1, cv::NORM_MINMAX);
1
votes

All images is matrices. You can see what you get in cv::Mat with imshow("Image", tt).
And in line:

cvtColor(tt, tgray, COLOR_BGR2GRAY);

You trying to convert matrix with 3 or 4 plains to matrix with 1 plain. Conversion type controls by COLOR_BGR2GRAY constant. Information about cvtColor() function you can find in OpenCV documentation

In this case you don't need to convert your tt matrix - it is already grayscale image.