1.背景
在VS2022中,结合QT开发框架,使用OpenCV开源图像处理库,实现在QT界面中完成简易的图像处理,这里展示采用了灰度化处理,其它图像处理操作依据具体场景编写即可。
2.图像格式问题
在QT中,采用的是QImage,QPixmap,而在OpenCV中采用的是Mat,两者不能混淆,在QT中进行图像的展示不能直接使用Mat格式图片,所以会存在图像格式转换问题。关于图像格式互相转换的代码为:
cv::Mat imgToMat(QImage& image)
{
cv::Mat mat;
switch (image.format()) {
case QImage::Format_RGB32:
mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());
break;
case QImage::Format_RGB888:
mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());
cv::cvtColor(mat, mat, cv::COLOR_RGB2BGR);
break;
case QImage::Format_Indexed8:
mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
break;
default:
throw std::runtime_error("Unsupported QImage format");
}
return mat;
}
QImage matToImg(cv::Mat& mat)
{
switch (mat.type()) {
case CV_8UC4: {
QImage image(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB32);
return image;
}
case CV_8UC3: {
QImage image(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
return image.rgbSwapped();
}
case CV_8UC1: {
QImage image(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_Indexed8);
return image;
}
default:
throw std::runtime_error("Unsupported cv::Mat format");
}
}
QPixmap matToPix(cv::Mat& mat)
{
QImage image = matToImg(mat);
QPixmap pixmap = QPixmap::fromImage(image);
return pixmap;
}
cv::Mat pixToMat(QPixmap& p)
{
QImage image = p.toImage();
cv::Mat mat = imgToMat(image);
return mat;
}
需要注意的是,在进行imgToMat过程当中的mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());其中的constBits()有时候并不会起作用,改为bits()即可。了解了一下发现两者都是指向图像像素数据的指针,一个是常量的,只可读,另一个非常量,是可修改的。但是本身都是复制操作,不知道为什么会产生这个bug。
3.ui布局及代码
在图片布局当中,采用的是四个Label,两个存放文字的Label,两个存放图片的Label,Label通过设置pixmap可以摆放图片。
相关图像处理代码如下(代码中的originImage代表存放原图的Label名字,TransAfterImage代表存放处理后的Label名字):
QImage image("F://imgs//CSDN_Credic1017.jpg");
QPixmap pixmap = QPixmap::fromImage(image);
ui.originImage->setPixmap(pixmap);
// 图片适应窗口大小
ui.originImage->setScaledContents(true);
cv::Mat img = pixToMat(pixmap);
cv::Mat gray;
cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);
QPixmap grayPixmap = matToPix(gray);
ui.TransAfterImage->setPixmap(grayPixmap);
ui.TransAfterImage->setScaledContents(true);
在进行操作后,最终效果图如下:
4.总结
本次博客展示了如何在QT上如何进行简单的图像处理操作,虽然简单,但是涉及了图像格式问题,图像显示方式选取比较常用的点。下一步将对图像处理进行更深层次的应用,结合可视化框架QT。
往期好文推荐:
VS2022搭建QT及OpenCV环境
C++ QT使用stackwidget实现页面切换(含源码)
我是乐于分享C++、QT、图像处理与深度学习的Credic,是一个在职的C++图像处理软件工程师。如果文章对你有帮助麻烦点个点赞关注收藏哦,你的点赞关注是我最大的动力,持续分享干货中···