|
|
#pragma once
|
|
|
|
|
|
#include <opencv2\opencv.hpp>
|
|
|
#include <QDebug>
|
|
|
#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<uchar>(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<uchar>(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<float>(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;
|
|
|
}
|
|
|
};
|