opencv QImage与Mat 互转 及简单的图像处理
Posted BigProgrambug
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了opencv QImage与Mat 互转 及简单的图像处理相关的知识,希望对你有一定的参考价值。
opencv(mat与qimage 的互转)及简单的图像处理
一、opencv库文件
编译好的opencv 库。
二、使用方式(Qt)
把上面下载的opencv.zip 解压出来的include和lib 文件夹放到工程文件夹里面,并在pro 文件中添加以下代码,即可使用
INCLUDEPATH +=$$PWD\\include
INCLUDEPATH +=$$PWD\\include\\opencv
INCLUDEPATH +=$$PWD\\include\\opencv2
LIBS +=$$PWD\\lib/libopencv_*.a
三、QImage 转 Mat (不太全,多多指教)
通过判断QImage 的类型 在调用Mat 的构造函数进行转换,代码都有进行注释
代码如下(示例):
cv::Mat ImageHandle::QImage2Mat(QImage image)
{
cv::Mat mat; //创建一个mat对象来接收
switch (image.format()) //QImage 的一个库函数 可以返回图片的类型
{
case QImage::Format_ARGB32_Premultiplied: //RGB32 为四通道的所以在调用mat构造函数需要转换成四通道的mat类型(CV_8UC4)
mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());
break;
case QImage::Format_RGB888: //RGB888 即RGB24 三通道八位的图片 所以转成三通道的mat(CV_8UC4)
mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());
//因为Qimage 是RGB 通道 而 Mat 为 BGR 通道 所以需要使用cvtcolor进行转换,不然图片通道会颠倒
cv::cvtColor(mat, mat,cv::COLOR_RGB2BGR);
break;
case QImage::Format_Indexed8: //Indexed8 为单通道的图片 所以在转换成mat 也是单通道(CV_8UC1)
mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
break;
}
return mat;
}
四、Mat转 QImage
跟上面一样也是通过判断mat的通道 调用QImage的构造函数来进行转换
QImage ImageHandle::Mat2QImage(cv::Mat mat)
{
if(mat.type() == CV_8UC1)
{
QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
//转换为qimage 单通道颜色值
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;
}
else if(mat.type() == CV_8UC3)
{
QImage image((const uchar*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
return image.rgbSwapped();
}
else if(mat.type() == CV_8UC4)
{
const uchar *pSrc = (const uchar*)mat.data;
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
return image;
}
else
{
return QImage();
}
}
五、一些简单的图像处理操作
1、图片的滤色
通过mat的宽高来访问图片的所有像素点 并删除对应的颜色
QImage ImageHandle::ImageColorDelete(QImage &image, int flag)
{
cv::Mat mat = this->QImage2Mat(image);
cv::Mat dst = cv::Mat::zeros(mat.size(),mat.type());
int chl = mat.channels();
//遍历像素点 滤除每个像素点所对应的颜色值,从而达到滤色的效果
for(int row=0;row<mat.rows;row++)
{
for(int col=0;col<mat.cols;col++)
{
if(chl == 3)
{
switch (flag)
{
case BLUE:
dst.at<cv::Vec3b>(row,col)[0] = 0;
dst.at<cv::Vec3b>(row,col)[1] = mat.at<cv::Vec3b>(row,col)[1];
dst.at<cv::Vec3b>(row,col)[2] = mat.at<cv::Vec3b>(row,col)[2];
break;
case GREEN:
dst.at<cv::Vec3b>(row,col)[0] = mat.at<cv::Vec3b>(row,col)[0];
dst.at<cv::Vec3b>(row,col)[1] = 0;
dst.at<cv::Vec3b>(row,col)[2] = mat.at<cv::Vec3b>(row,col)[2];
break;
case RED:
dst.at<cv::Vec3b>(row,col)[0] = mat.at<cv::Vec3b>(row,col)[0];
dst.at<cv::Vec3b>(row,col)[1] = mat.at<cv::Vec3b>(row,col)[1];
dst.at<cv::Vec3b>(row,col)[2] = 0;
break;
}
}
}
}
return this->Mat2QImage(dst);
}
2、图片的反色
操作每个像素点,每个像素点的像素进行取反得到反色效果
QImage ImageHandle::ImageContraryColor(QImage &image)
{
cv::Mat mat = this->QImage2Mat(image);
cv::Mat dst = cv::Mat::zeros(mat.size(),mat.type());
int chl = mat.channels();
//操作每个像素点,每个像素点的像素进行取反得到反色效果
for(int row=0;row<mat.rows;row++)
{
for(int col=0;col<mat.cols;col++)
{
if(chl == 3)
{
dst.at<cv::Vec3b>(row,col)[0] = 255 - mat.at<cv::Vec3b>(row,col)[0];
dst.at<cv::Vec3b>(row,col)[1] = 255 - mat.at<cv::Vec3b>(row,col)[1];
dst.at<cv::Vec3b>(row,col)[2] = 255 - mat.at<cv::Vec3b>(row,col)[2];
}
}
}
return this->Mat2QImage(dst);
}
3、图像的提色
遍历像素点 提取所对应的颜色
cv::Mat mat = this->QImage2Mat(image);
cv::Mat dst = cv::Mat::zeros(mat.size(),mat.type());
int chl = mat.channels();
//遍历像素点 提取所对应的颜色
for(int row=0;row<mat.rows;row++)
{
for(int col=0;col<mat.cols;col++)
{
if(chl == 3)
{
switch (flag)
{
case BLUE:
dst.at<cv::Vec3b>(row,col)[0] = mat.at<cv::Vec3b>(row,col)[0];
dst.at<cv::Vec3b>(row,col)[1] = 0;
dst.at<cv::Vec3b>(row,col)[2] = 0;
break;
case GREEN:
dst.at<cv::Vec3b>(row,col)[0] = 0;
dst.at<cv::Vec3b>(row,col)[1] = mat.at<cv::Vec3b>(row,col)[1];
dst.at<cv::Vec3b>(row,col)[2] = 0;
break;
case RED:
dst.at<cv::Vec3b>(row,col)[0] =0;
dst.at<cv::Vec3b>(row,col)[1] = 0;
dst.at<cv::Vec3b>(row,col)[2] = mat.at<cv::Vec3b>(row,col)[2];
break;
}
}
}
}
return this->Mat2QImage(dst);
刚开始主要还是记录一下自己实现的功能,后面还会进行更新opencv 的图像处理部分
以上是关于opencv QImage与Mat 互转 及简单的图像处理的主要内容,如果未能解决你的问题,请参考以下文章