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

本文介绍了如何在Qt环境中整合OpenCV库,包括库文件的配置和在.pro文件中的引用。详细展示了QImage与OpenCV的Mat类型之间的转换方法,并提供了图片滤色、反色和提色的简单图像处理操作示例代码。
摘要由CSDN通过智能技术生成


一、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 的图像处理部分

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BigProgrambug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值