开发环境为: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图像点运算,包括图像反色,灰度拉伸,灰度均衡
参考: