3

I wonder if anyone can help me with this. I have an array (single dim) that holds enough uint values to populate a screen 120x160 in size. I want to load the array into a mat and display it as a grayscale image. I am not seeing it can anyone help?? Thanks in advance.

myarray[39360];
//..
//Code populates values between 0 and 255 to the array
// I have printed the array and the values are all 0 to 255
//..
Mat img,img1;

// load the array into a mat
img(120,160,CV_8UC1,myarray);

// convert the mat to a grayscale image, 3 channel instead of the current 1
img.convertTo(img1,CV_8UC3);
namedWindow("test",WINDOW_AUTOSIZE);
imshow("test",img1);
waitKey(0);

// windows pops up but just shows a gray blank page about mid tone :-(
mschuurmans
  • 1,088
  • 1
  • 12
  • 24
Gusisin
  • 41
  • 4
  • `int` is `CV_32SC1` so try `img(120,160,CV_32SC1,myarray);` and `img.convertTo(img1,CV_8U);` so afterwards, img1 will be a CV_8UC1 and can be displayed where 0 = black and 255 = white – Micka Oct 11 '18 at 14:06

2 Answers2

2

Not sure why are you using Mat with 3 channel (CV_8UC3 means 8 bytes per pixel, unsigned, 3 channels) if you want a grayscale image, here is a complete example of what are you trying to do:

#include "opencv2/highgui.hpp"
#include <vector>
#include <iostream>
#include <ctype.h>
#include <cstdlib>

int main()
{
    //  create a uint8_t array, can be unsigned char too
    uint8_t myArray[120*160];

    //  fill values
    srand(time(0));
    for (int i = 0; i < 120*160; ++i)
    {
        myArray[i] = (rand() % 255) + 1;
    }

    //  create grayscale image
    cv::Mat imgGray(120, 160, CV_8UC1, myArray);

    cv::namedWindow("test", cv::WINDOW_AUTOSIZE);
    cv::imshow("test", imgGray);
    cv::waitKey(0);

    return 0;
}

Example output image: enter image description here

unlut
  • 3,525
  • 2
  • 14
  • 23
  • I tried this example I get exactly the same (sad face) – Gusisin Oct 11 '18 at 13:51
  • I tried it and got the same. I agree about the 3 channels but I was responding to another answer on a similar topic that said that imshow does not work with single channel which seemed odd at the time. – Gusisin Oct 11 '18 at 13:58
  • I added an example image. – unlut Oct 11 '18 at 13:59
  • Yes what I expected but mine is just solid one color. (reminds me of poltergeist :-) – Gusisin Oct 11 '18 at 14:01
  • I did do a test where I created an image from a Scalar(x). I chaged the value of x and the image was always the same mid tone gray. I would have expected the tone to change as I changed x? – Gusisin Oct 11 '18 at 14:02
  • What type you get when you use answer from https://stackoverflow.com/questions/10167534/how-to-find-out-what-type-of-a-mat-object-is-with-mattype-in-opencv on your Mat object?, I get Matrix: 8UC1 160x120 – unlut Oct 11 '18 at 14:08
  • I get the same type 0 – Gusisin Oct 11 '18 at 14:16
  • maybe try saving your image ``cv::imwrite("testimg.jpg", imgGray)`` and open your image from an external software. We can see whether the source of problem is opencv Mat object or opencv GUI. – unlut Oct 11 '18 at 14:23
  • Great idea I will try that – Gusisin Oct 11 '18 at 14:45
  • Aha!!! I got an image, very interesting. Not sure why save works and show does not. – Gusisin Oct 11 '18 at 14:49
  • I am searching for similar problems, but they mostly caused due to lack of waitKey but you use it properly. Do you have python installation of opencv? I would like to test you a similar code if you have it. – unlut Oct 11 '18 at 14:58
  • Great idea I will save the array to a file read it into python and see how it looks – Gusisin Oct 11 '18 at 15:11
  • I even tried imshow without a named window in case that was an issue – Gusisin Oct 11 '18 at 15:12
  • What is interesting I saved the image (which shows great when I display it from the os) load it as a mat image and then display it and gray screen again. I think I will do an od of the Mat with 255 in all pixels and see what the mat is made of. – Gusisin Oct 11 '18 at 16:05
  • What platform you are using and how did you install opencv? Does waitKey function work for your window?(What I mean is can you close your window by pressing a button while your window has keyboard focus?) – unlut Oct 11 '18 at 17:04
0
  • What type is myarray? I'm assuming unsigned char[].
  • If you display img, does it show correctly? By that, you can check if anything went wrong before the conversion.
  • The conversion to BGR (which is what you're doing, your converting grayscale to color with all colors the same) doesn't work that way. Here are two choices you have:

    cv::cvtColor(img,img1,cv::COLOR_GRAY2BGR);

    which does the same thing (possibly, in older versions, something like CV_GRAY2BGR), or create an array containing three times img and use cv::merge.

    • Finally, consider NOT converting to BGR at all. If you want a grayscale image, why isn't the 1-channel image sufficient? If you'd save it using cv::imwrite, it would even use less space...
Demosthenes
  • 1,515
  • 10
  • 22
  • Correct unsigned char, well actually uint8_t which is the same. I only did that conversion as someone else in a different topic suggested that imshow was not displaying because it was a single channel image, didn't make sense then still doesn't. I have the lena single channel image from the examples I think I will read that into an array and try to display that. using the above method. I print t he array and sure enough they are all values between 0 and 255. I am so confused what to do next. As for includes I am using the normal suspects and could this be an issue? – Gusisin Oct 11 '18 at 13:56