2012-08-09 196 views
4

我已經在互聯網上搜索過,但找不到將QImage(或QPixmap)轉換爲OpenCV Mat的方法。我將如何做到這一點?如何將QImage轉換爲opencv Mat

任何幫助表示讚賞。

+0

這裏是一個[可能重複(http://stackoverflow.com/questions/11170485/qimage-to-cvmat-convertion-strange -behaviour) – SuperSaiyan 2012-08-09 15:21:04

+0

@Thrustmaster - 不是一個愚蠢的事情,只是步驟問題走向另一個方向 – 2012-08-09 15:32:44

回答

5

如果QImage的仍然存在,你只需要在其上進行快速操作,那麼您可以同時構建一個品種::使用QImage的內存

cv::Mat mat(image.rows(),image.cols(),CV_8UC3,image.scanline()); 這是假設的QImage是3channels,即RGB888墊

如果QImage的是要離開,那麼你需要複製數據,請參見Qimage to cv::Mat convertion strange behaviour

如果QImage的是Format_ARGB32_Premultiplied(在參訪格式),那麼你需要將每個像素轉換爲OpenCV中的BGR佈局。 cv :: cvtcolor()函數可以將ARGB轉換爲最新版本的RGB。
或者你可以使用QImage::convertToformat()來複制數據

+1

我是否必須使用scanLine遍歷圖像中的每個指針? – user1576633 2012-08-09 21:29:27

+0

@ user1576633不,QImage連續存儲scanLine(),沒有arg,指向圖像數據的開始 – 2012-08-09 21:38:59

+0

爲什麼不簡單地將這個墊子克隆到另一個,如果QImage消失? – 2013-08-16 10:57:24

0

我將圖像保存到磁盤,然後從CV重新打開它之前轉換爲RGB;)

@ ^我嘗試了以前的解決方案。它似乎沒有與我合作。雖然我得到了一些圖像,但它看起來像是一些條形碼信息的圖像。我想有一些參數不匹配。

6

你發出這個問題一年後有已經在互聯網上偉大的答案:

但我看到它的方式,如果你的工作與Qt和OpenCV在同一時間然後鍵入QImage可能是僅用於顯示,這種情況下,您可能想要使用QPixmap,因爲它的優化顯示。所以這是我做的:

  1. 加載圖像cv::Mat,如果你想顯示的圖像,使用的第二篇文章中介紹了非複製方法轉換爲QPixmap
  2. 做你的圖像處理cv::Mat
  3. 在工作流程的任何時候,您都可以調用諸如Mat2QPixmap()之類的東西來獲得實時結果。
  4. 永遠不要將QPixmap轉換爲cv::Mat,考慮到每種類型的目的,沒有任何意義。
0

我在OpenCV的3.1+風格代碼嘗試:

void qimage_to_mat(const QImage& image, cv::OutputArray out) { 

    switch(image.format()) { 
     case QImage::Format_Invalid: 
     { 
      Mat empty; 
      empty.copyTo(out); 
      break; 
     } 
     case QImage::Format_RGB32: 
     { 
      Mat view(image.height(),image.width(),CV_8UC4,(void *)image.constBits(),image.bytesPerLine()); 
      view.copyTo(out); 
      break; 
     } 
     case QImage::Format_RGB888: 
     { 
      Mat view(image.height(),image.width(),CV_8UC3,(void *)image.constBits(),image.bytesPerLine()); 
      cvtColor(view, out, COLOR_RGB2BGR); 
      break; 
     } 
     default: 
     { 
      QImage conv = image.convertToFormat(QImage::Format_ARGB32); 
      Mat view(conv.height(),conv.width(),CV_8UC4,(void *)conv.constBits(),conv.bytesPerLine()); 
      view.copyTo(out); 
      break; 
     } 
    } 
} 

void mat_to_qimage(cv::InputArray image, QImage& out) 
{ 
    switch(image.type()) 
    { 
     case CV_8UC4: 
     { 
      Mat view(image.getMat()); 
      QImage view2(view.data, view.cols, view.rows, view.step[0], QImage::Format_ARGB32); 
      out = view2.copy(); 
      break; 
     } 
     case CV_8UC3: 
     { 
      Mat mat; 
      cvtColor(image, mat, COLOR_BGR2BGRA); //COLOR_BGR2RGB doesn't behave so use RGBA 
      QImage view(mat.data, mat.cols, mat.rows, mat.step[0], QImage::Format_ARGB32); 
      out = view.copy(); 
      break; 
     } 
     case CV_8UC1: 
     { 
      Mat mat; 
      cvtColor(image, mat, COLOR_GRAY2BGRA); 
      QImage view(mat.data, mat.cols, mat.rows, mat.step[0], QImage::Format_ARGB32); 
      out = view.copy(); 
      break; 
     } 
     default: 
     { 
      throw invalid_argument("Image format not supported"); 
      break; 
     } 
    } 
}