#pragma once #include #include #include "GSurface.h" class ImageUtils { public: //曲面转换成mat 黑白图 static void convertSurfaceToMat(GSurface* pSrcSurf, float zlower, float zupper, cv::Mat& dstMat) { int nx = pSrcSurf->XNum() - 1; int ny = pSrcSurf->YNum() - 1; // Mat构造:行数,列数,存储结构,数据,step每行多少字节 dstMat = cv::Mat::zeros(ny, nx, CV_8UC1); //缺省黑色 float v; zlower -= 1e-4; zupper += 1e-4; for (int j = 0; j < ny; j++) { for (int i = 0; i < nx; i++) { v = pSrcSurf->Z(i, j); if (v > zlower && v < zupper) { dstMat.at(j, i) = 255; // 对指定的像素赋值为白色 } } } } //mat 转换为 surface static bool convertMatToSurface(cv::Mat& mat, float x0, float y0, float deltX, float deltY, GSurface* pDstSurf) { int nx = mat.cols; int ny = mat.rows; if (nx < 2 || ny < 2) return false; pDstSurf->Create(nx, ny, x0, y0, deltX, deltY); switch (mat.type()) { case CV_8UC1: for (int j = 0; j < ny; j++) { uchar* p = mat.ptr(j); for (int i = 0; i < nx; i++) { pDstSurf->setZ(i, j, (unsigned int)p[i]); } } break; case CV_32FC1: //float for (int j = 0; j < ny; j++) { float* p = mat.ptr(j); for (int i = 0; i < nx; i++) { pDstSurf->setZ(i, j, (float)p[i]); } } break; default: return false; break; } pDstSurf->CalcRange(); return true; } //Mat 转换为QImage static bool ConvertMatToQImage(cv::Mat& mat, QImage& image, QImage::Format fmt = QImage::Format_ARGB32_Premultiplied) { if (mat.empty()) { qDebug() << "load image fail!"; return false; } switch (mat.type()) { case CV_8UC1: { image = QImage(mat.cols, mat.rows, QImage::Format_Indexed8); //set the color table image.setColorCount(256); for (int i = 0; i < 256; i++) image.setColor(i, qRgb(i, i, i)); //copy input mat uchar* pSrc = mat.data; for (int row = 0; row < mat.rows; row++) { uchar* pDest = image.scanLine(row); memcpy(pDest, pSrc, mat.cols); pSrc += mat.step; } break; } case CV_8UC3: image = QImage((const unsigned char*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888); image = image.rgbSwapped(); // BRG转为RGB // Qt5.14增加了Format_BGR888 // image = QImage((const unsigned char*)mat.data, mat.cols, mat.rows, mat.cols * 3, QImage::Format_BGR888); break; case CV_8UC4: image = QImage((const unsigned char*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32); break; case CV_16UC4: image = QImage((const unsigned char*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGBA8888);// Format_RGBA64); image = image.rgbSwapped(); // BRG转为RGB break; } if (!image.isNull()) image = image.convertToFormat(fmt); return true; } //QImage转换为Mat static bool ConvertQImageToMat(const QImage& image, cv::Mat& mat) { switch (image.format()) { case QImage::Format_Grayscale8: // 灰度图,每个像素点1个字节(8位) // Mat构造:行数,列数,存储结构,数据,step每行多少字节 mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine()); break; case QImage::Format_ARGB32: // uint32存储0xAARRGGBB,pc一般小端存储低位在前,所以字节顺序就成了BGRA case QImage::Format_RGB32: // Alpha为FF case QImage::Format_ARGB32_Premultiplied: mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine()); break; case QImage::Format_RGB888: // RR,GG,BB字节顺序存储 mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine()); // opencv需要转为BGR的字节顺序 cv::cvtColor(mat, mat, cv::COLOR_RGB2BGR); break; case QImage::Format_Indexed8: mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.bits(), image.bytesPerLine()); break; //case QImage::Format_RGBA64: // uint64存储,顺序和Format_ARGB32相反,RGBA // mat = cv::Mat(image.height(), image.width(), CV_16UC4, (void*)image.constBits(), image.bytesPerLine()); // // opencv需要转为BGRA的字节顺序 // cv::cvtColor(mat, mat, cv::COLOR_RGBA2BGRA); // break; } return true; } };