QT+opencv学习笔记(1)——图像点运算

开发环境为:win10+QT5.8+opencv3.2

一、读取图像

         QT中显示图片的时候可以用QLabel也可以用GraphicsView,本文使用的是QLabel。但是需要注意的是在opencv中图像是以BGR的顺序存储的,所以在读取并显示彩色图片之前需要将其转换为正常的RGB顺序,然后再转换为QImage格式,再用画刷绘制出来。但要注意的是图片不会自动调整大小。

QPainter painter(this);
QImage image;
image.load(fileName);
painter.drawImage(0, 0, image, 0, 0, 320, 480);//坐标(0,0),图片大小为(320,480)
        而使用Pixmap图片能够自适应QLabel大小,比较方便,所以选择这种方式

        主要代码如下:

    fileName = QFileDialog::getOpenFileName(this,"Open Image",".","Image File(*.png *.jpg *.jpeg *.bmp)");
    grayImg = imread(fileName.toLatin1().data(),IMREAD_GRAYSCALE);
    //cvtColor(image,image,CV_BGR2RGB);
    QImage img = QImage((const unsigned char*)(grayImg.data),grayImg.cols,grayImg.rows,QImage::Format_RGB888);
    QPixmap *pixmap = new QPixmap(fileName);
    pixmap->scaled(ui->oriImgLabel->size(), Qt::KeepAspectRatio);
    ui->oriImgLabel->setScaledContents(true);
    ui->oriImgLabel->setPixmap(*pixmap);

        读取结果如下图:

二、图像反色

         图像反色是指颠倒原来颜色值的大小,最简单的做法是如果颜色的量化等级是256,则可以直接用256分别减去原图的R,G,B值得到新的R,G,B值,本文使用的是灰度图,只有一个通道,更为简单。

        主要代码如下:

    //遍历所有像素,并设置像素值
    MatIterator_<uchar> grayit, grayend;
    for( grayit = antiImg.begin<uchar>(), grayend =
    antiImg.end<uchar>(); grayit != grayend; ++grayit)
        *grayit = 255-*grayit;

        图像反色处理结果如下:

                                                                     

三、灰度拉伸

         一幅图片,成像时光照不足或光照过强,会造成图片偏暗或偏亮,对比度较低。这时候需要增加图像的灰度级来丰富图像的信息,一般采用灰度拉伸来实现。

        主要代码如下:

    Mat resultImage = srcImage.clone();
    int nRows = resultImage.rows;
    int nCols = resultImage.cols;
    //判断图像的连续性
    if (resultImage.isContinuous())
    {
        nCols = nCols*nRows;
        nRows = 1;
    }
    //图像指针操作
    uchar *pDataMat;
    int pixMax = 0, pixMin = 255;
    //计算图像的最大最小值
    for (int j = 0; j < nRows; j++)
    {
        pDataMat = resultImage.ptr<uchar>(j);//ptr<>()得到的是一行指针
        for (int i = 0; i < nCols; i++)
        {
            if (pDataMat[i] > pixMax)
                pixMax = pDataMat[i];
            if (pDataMat[i] < pixMin)
                pixMin = pDataMat[i];
        }
    }
    //灰度拉伸映射
    for (int j = 0; j < nRows; j++)
    {
        pDataMat = resultImage.ptr<uchar>(j);
        for (int i = 0; i < nCols; i++)
        {
            pDataMat[i] = (pDataMat[i] - pixMin) * 255 / (pixMax - pixMin);
        }
    }
    return resultImage;

        需要注意的是在初始化Mat图像所使用的方式,

Mat resultImage(srcImage);
Mat resultImage = srcImage;

       上面两种初始化方式为浅复制,指针指向同一块内存区域,srcImage相当于resultImage的引用,对srcImage的操作会影响resultImage。

Mat resultImage = srcImage.clone();
srcImage.copyTo(resultImage);

        上面两种初始化方式为深复制,指针指向不同的内存区域,对srcImage的操作不会影响resultImage。

        浅复制与深复制的具体区别可参考对深拷贝与浅拷贝的再次理解

        灰度拉伸处理结果如下:


四、灰度均衡

         一幅图片如果曝光不均匀,会造成大片的黑暗区域或高亮区域,可以采用灰度均衡的方法来处理。灰度均衡是把图像中像素的值在灰度级上重新分配的过程,使输入图像转换为在每一灰度级上都有相同的像素点数的输出图像。opencv有库函数来实现灰度均衡。

        主要代码如下:

equalizeHist(grayImg, balaImg);

        灰度均衡处理结果如下:


        整体工程代码见QT+opencv图像点运算,包括图像反色,灰度拉伸,灰度均衡

参考:

(1)OpenCV学习笔记(一)对比度拉伸


猜你喜欢

转载自blog.csdn.net/minghui_/article/details/80396789