Ask Your Question
0

how do i save QImage in cv::Mat

asked 2013-03-13 03:43:32 -0600

dark gravatar image

can anyone tell me how to save QImage in a cv::Mat variable? QByteArray to cv::Mat would also work.

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
1

answered 2013-03-13 04:30:26 -0600

Guanta gravatar image

Afaik you need to write it yourself, e.g.:

cv::Mat3b QImage2Mat(const QImage &src) {
  unsigned int height = src.height();
  unsigned int width = src.width();

  cv::Mat3b dest(height, width);
  for (unsigned int y = 0; y < height; ++y) {
    cv::Vec3b *destrow = dest[y];
    for (unsigned int x = 0; x < width; ++x) {
      QRgb pxl = src.pixel(x, y);
      destrow[x] = cv::Vec3b(qBlue(pxl), qGreen(pxl), qRed(pxl));
    }
  }
  return dest;
}
edit flag offensive delete link more

Comments

operations for each pixel will be too slow. was hoping for something fast. maybe scanLine() or data() of the QByteArray class

dark gravatar imagedark ( 2013-03-13 05:00:23 -0600 )edit

Hmm from the QByteArray you can get the data via data() or constData(). This you could use to create a matrix-header on top, i.e. : uchar* data = bytearray.data(); cv::Mat3b a(rows, cols, data); Note that you should check first if the layout of the data you get from your byteArray is correct (maybe it is saved as rgb instead of bgr) or otherwise. For QImage it probably won't work since it seems that the data is aligned to 32bit. So is the QByteArray coming from the QImage (then it probably won't work due to the alignment) or did you create it?

Guanta gravatar imageGuanta ( 2013-03-13 05:37:59 -0600 )edit

I'm using QTcpSocket to receive pictures from a tablet. readAll() gives me a ByteArray. Then i use LoadFromData() for a Pixmap, to display the image in a GUI.

Now i want to change it and save to cv::Mat, to be able to use imageprocessing.

Will see if your char pointer idea solves it.

dark gravatar imagedark ( 2013-03-13 07:27:36 -0600 )edit

This is what i'm using now: cv::Mat image = cv::Mat(img.height(), img.width(), CV_8UC4, img.scanLine(0), img.bytesPerLine());

img is a QImage.

dark gravatar imagedark ( 2013-03-13 11:56:12 -0600 )edit

Nice one! Note that the most OpenCV functions expect either single or three channels. So maybe you need to use cv::split(img, vec_of_mats).

Guanta gravatar imageGuanta ( 2013-03-13 12:23:42 -0600 )edit

I know. I need it as CV_8UC3 in BGR format. will try cv::mixChannels later, oi maybe someone has a better idea and i don't need to search google :)

dark gravatar imagedark ( 2013-03-14 02:28:35 -0600 )edit

Question Tools

Stats

Asked: 2013-03-13 03:43:32 -0600

Seen: 2,918 times

Last updated: Mar 13 '13