一、opencv简介
opencv是一个跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上,实现了图像处理和计算机视觉方面的很多通用算法。
二、cv常用函数
1.imread
Mat imread( const String& filename, int flags = IMREAD_COLOR );是从指定文件载入一幅图像
filename:要读入图片的完整路径
flags:读入图片的标志
IMREAD_UNCHANGED = -1,表示读取原图,包括alpha通道, 不进行任何改变
IMREAD_GRAYSCALE = 0,表示以灰度图方式读取原图
IMREAD_COLOR = 1,表示以RGB方式读取原图,忽略alpha通道,默认参数
这里需要注意:读取图片时默认是忽略透明度,打开一个背景颜色为透明的图片时会是黑色。如果想要透明度,使用IMREAD_UNCHANGED = -1参数。
2.imwrite
bool imwrite( const String& filename, InputArray img,const std::vector<int>& params = std::vector<int>());是保存一幅图像到指定的文件中。
filename:所需保存图像的文件目录和文件名。这里的文件名需要带有图像格式后缀的,目前OpenCV该函数只支持JPEG,PNG,PPM,PGM,PBM,TIFF等。并不是所有Mat类型都支持。
img:图像数据来源,其类型为Mat。
3.imdecode
Mat imdecode( InputArray buf, int flags );是从指定的内存缓存中读一幅图像
buf:它是以字节为单位接收到的图像数据
flags:它指定读取图像的方式。默认值为IMREAD_COLOR 同(1)中类型
4.imencode
bool imencode( const String& ext, InputArray img,CV_OUT std::vector<uchar>& buf,const std::vector<int>& params = std::vector<int>());是将一幅图像写进内存缓存中。
ext:定义输出文件格式的扩展名
img:需要被编码的图像
buf:输出的缓存区,类型是vector
parms:被编码的格式和压缩率,类型是vector
prams目前支持以下参数:
JPEG,它的压缩率范围(cv_imwrite_jpeg_quality)从0到100(越大越好)。默认值是95。100为没有压缩。
对于WEBP来说,它的压缩范围(cv_imwrite_webp_quality)从1到100(越大越好)。默认情况下(不含任何参数)和质量在100以上,则使用无损压缩。
png,可以压缩级别(cv_imwrite_png_compression)从0到9。更高的值意味着更小的尺寸和更长的压缩时间。默认值是3。
PPM、PGM、或PBM,它可以是一个二进制格式的标志(cv_imwrite_pxm_binary),0或1。默认值是1。
5.cvtColor
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0 );
src:输入图像即要进行颜色空间变换的原图像,可以是Mat类
dst:输出图像即进行颜色空间变换后存储图像,也可以Mat类
code:转换的代码或标识,表示图像转码方式 ,比如:CV_BGR2RGB
dstCn:目标图像通道数,如果取值为0,则由src和code决定
三、Mat常用构造函数
1.Mat::Mat()
无参数构造方法
2.Mat::Mat(int rows, int cols, int type)
创建行数为 rows,列数为 col,类型为 type 的图像
3.Mat::Mat(Size size, int type)
创建大小为 size,类型为 type 的图像
Size(cols,rows)在Size()的构造函数中行数和列数在是反过来的
4.Mat::Mat(int rows, int cols, int type, const Scalar& s)
创建行数为 rows,列数为 col,类型为 type 的图像,并将所有元素初始化为值 s
5.Mat::Mat(Size size, int type, const Scalar& s)
创建大小为 size,类型为 type 的图像,并将所有元素初始化为值 s
6.Mat::Mat(const Mat& m)
将m赋值给新创建的对象,此处不会对图像数据进行复制,m和新对象共用图像数据,属于浅拷贝
四、类似“CV_8UC3”的含义
1.8U还包括{8U,16S,16U,32S,32U,32F}多种类别。
U:无符号整形
S:有符号整形
F:单精度浮点型
8U:8位无符号整形 (0~255)
8S:8位符号整形 (-128~127)
16U:16位无符号整形 (0~65535)
16S:16位有符号整形 (-32768~32767)
32S:32位有符号整形 (-2147483648~2147483647)
32F:32位浮点数 (-FLT_MAX ………FLT_MAX,INF,NAN)
64F:64 位浮点数 (-DBL_MAX ……….DBL_MAX,INF,NAN)
例如:CV_32FC2:32位浮点型双通道矩阵
2.C3 还包括{C1,C3,C4}
C:通道,多通道排列顺序为BGR
C1:单通道,灰度图
C3:三通道,BGR图像
C4:四通道,BGRA图像
如果需要更多的通道数,需要用宏 CV_8UC(n)。例如:CV_8UC(6)文章来源:https://www.toymoban.com/news/detail-766786.html
五、cv::Mat与QImage的互相转换
1.QImage转cv::Mat
cv::Mat QImageTocvMat(const QImage &image)
{
cv::Mat mat;
switch(image.format())
{
case QImage::Format_Grayscale8: //灰度图,每个像素点1个字节(8位)
case QImage::Format_Indexed8: //Mat构造:行数,列数,存储结构,数据,step每行多少字节
mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
break;
case QImage::Format_ARGB32:
case QImage::Format_RGB32:
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());
cv::cvtColor(mat, mat, cv::COLOR_RGB2BGR); //opencv需要转为BGR的字节顺序
break;
}
return mat;
}
2.cv::Mat转QImage
QImage cvMatToQImage(const cv::Mat& mat)
{
switch (mat.type()) {
case CV_8UC1:{
QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
image.setColorCount(256);
for(int i = 0; i < 256; i++){
image.setColor(i, qRgb(i, i, i));
}
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;
}
return image;
}
break;
case CV_8UC3:{
const uchar *pSrc = (const uchar*)mat.data;
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
return image.rgbSwapped();
}
break;
case CV_8UC4:{
const uchar *pSrc = (const uchar*)mat.data;
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
return image.copy();
}
break;
default:
break;
}
return QImage();
}
六、例子
QImage cvMatToQImage(const cv::Mat& mat)
{
switch (mat.type()) {
case CV_8UC1:{
qDebug()<<"CV_8UC1";
QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
image.setColorCount(256);
for(int i = 0; i < 256; i++){
image.setColor(i, qRgb(i, i, i));
}
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;
}
return image;
}
break;
case CV_8UC3:{
qDebug()<<"CV_8UC3";
const uchar *pSrc = (const uchar*)mat.data;
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
return image.rgbSwapped();
}
break;
case CV_8UC4:{
qDebug()<<"CV_8UC4";
const uchar *pSrc = (const uchar*)mat.data;
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
return image.copy();
}
break;
default:
break;
}
return QImage();
}
void MainWindow::on_pushButton_clicked()
{
QString img_name = QFileDialog::getOpenFileName( this, tr("Open Image"), ".", tr("Image Files(*.png *.jpg *.jpeg *.bmp)"));
cv::Mat src = cv::imread(img_name.toStdString(),-1);
QPixmap video = QPixmap::fromImage(cvMatToQImage(src));
ui->label->resize( video.size());
ui->label->setPixmap( video);
}
注意:之前用imread函数读取图片时,没有写后面的枚举值,用的默认值1,默认不读取透明度,结果读出来的背景透明色的图片背景都是黑色的,找了好几天原因。网上的例子都是没有写默认值的,读出来的图片都是没有问题的,一度怀疑自己。结果是这个默认值的问题,写-1的话是读取透明度的,网上例子没有问题是因为读取的图片背景颜色不是透明的,不涉及到透明度问题。文章来源地址https://www.toymoban.com/news/detail-766786.html
到了这里,关于opencv常用函数,QT中Mat与QImage的转换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!