opencv QImage与Mat 互转 及简单的图像处理

Posted BigProgrambug

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了opencv QImage与Mat 互转 及简单的图像处理相关的知识,希望对你有一定的参考价值。


一、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 互转 及简单的图像处理的主要内容,如果未能解决你的问题,请参考以下文章

bitmap与mat互转方便opencv操作

bitmap与mat互转方便opencv操作

bitmap与mat互转方便opencv操作

如何将 RGB32 格式的 QImage 转换为 OpenCV::mat?

Opencv和Qt QImage格式转Mat

QImage 与 cv::Mat 之间的相互转换