qt之图像处理
毕业2年了,一直使用的qt做桌面程序,很少接触图像算法类的东西,最近由于项目的原因,不得不了解下图像处理,不过也是一些简单的图像处理,仅此作为记录,并希望能帮助初学qt图像处理的朋友。
首先我推荐一篇文章,高斯模糊算法的实现和优化这篇文章也是我理解图片模糊的开始,我个人觉得讲的相当清楚明了。因此如果对原理或者名词不理解的同学可以进去一看究竟。下面我说下我自己在项目运用过程中的一心心得,就包括对图片处理的一些操作,做一记录。
如果对Qt的图像储存相关类不了解,可以看QPixmap/QImage/QPicture中的讲解,比较准确的描述了qt设计这几个类的目的,其中QImage类可以对图像进行镜像转换、QPixmap可以进行矢量拉伸等。不过这些都是qt自带的一些操作,但是还有一些特殊处理需要我们自己实现,接下来我就说下图片模糊处理和图片圆角处理
一、图片模糊处理
图片模糊处理说白了就是需要寻找一套模糊算法来生成模糊滤镜,然后对图像上的每一个像素进行处理,问题的关键在于模糊算法的实现,本篇开始推荐的文章中高斯模糊其实就是使用高斯函数生成模糊滤镜的过程,并对图片进行处理。既然知道了原理,那么其实图片模糊也就可以用很多方式来做了,毕竟替换高斯函数的方法有很多。文章最后有我自己整理的一个小demo,可以供大家参考。
下面我先贴上几种模糊函数下的实现效果,为什么要实现这样的效果呢,呵呵。。因为mac上的qq在换头像时背景色会自动切换,背景色应该就是通过模糊算法自动生成。
图1 高斯函数模糊
图2 直线函数模糊
图3 算术平均值模糊
这3种模糊都是使用了Blur1D方法进行滤镜处理,通过测试Blur1D方法比Blur2D方法快接近10倍。这个方法的优化,在本文推荐的第一篇文章中就有详细说明,如图4所示
图4 高斯优化说明
具体细节处理请看原文中描述。在这里我只贴出使用高斯一维函数处理的滤镜,和使用滤镜对照片上每一个像素进行处理的代码,代码如下:
//高斯模糊算法 一维(O(2*x*y*2r))形式的高斯函数 比二维(O(x*y*(2r)^2))效率高 对应Blur1D滤镜算法
void Gauss(filter_t& kernel, long radius)
{
kernel.set(radius, Diamet(radius)); static const double SQRT2PI = sqrt(2.0 * PI); double sigma = (double)radius / 3.0;
double sigma2 = 2.0 * sigma * sigma;
double sigmap = sigma * SQRT2PI; for (long n = , i = -kernel.radius(); i <= kernel.radius(); ++i, ++n)
kernel[n] = exp(-(double)(i * i) / sigma2) / sigmap;
}
下面的代码是对应高斯一维处理函数的图片像素点处理方法:
void Blur1D(bitmap_t& bitmap, filter_t& kernel)
{
Normalization(kernel); buffer_t buff(bitmap); for (long inx = , y = ; y < bitmap.h(); ++y)
{
for (long x = ; x < bitmap.w(); ++x, ++inx)
{
for (long n = , i = -kernel.radius(); i <= kernel.radius(); ++i, ++n)
{
long i_k = Edge(i, x, bitmap.w());
long inx_k = inx + i_k;
buff[inx].r += bitmap[inx_k].r * kernel[n];
buff[inx].g += bitmap[inx_k].g * kernel[n];
buff[inx].b += bitmap[inx_k].b * kernel[n];
}
}
} for (long inx = , x = ; x < bitmap.w(); ++x)
{
for (long y = ; y < bitmap.h(); ++y)
{
inx = y * bitmap.w() + x;
double r = 0.0, g = 0.0, b = 0.0;
for (long n = , i = -kernel.radius(); i <= kernel.radius(); ++i, ++n)
{
long i_k = Edge(i, y, bitmap.h());
long inx_k = inx + i_k * bitmap.w();
r += buff[inx_k].r * kernel[n];
g += buff[inx_k].g * kernel[n];
b += buff[inx_k].b * kernel[n];
}
bitmap[inx].r = Clamp<bitmap_t::channel_t>(r);
bitmap[inx].g = Clamp<bitmap_t::channel_t>(g);
bitmap[inx].b = Clamp<bitmap_t::channel_t>(b);
}
}
}
理解了上边的代码后,只需要下面几行代码,就可以生成模糊后的图片,其中resultImage是输出型参数,模糊后的图片存放在其中。
filter::bitmap_t bmp;
bmp.set((filter::bitmap_t::pixel_t*)resultImage.bits(),
resultImage.width(), resultImage.height()); filter::Filter(pair[], bmp, radius);
初次之外demo中还提到了一个检测算法时间复杂度的方法,通过调用该方法可以检测每个图片处理过程的时间长短。
#define CHECK_TIME(text, ...) \
{ \
clock_t t1 = std::clock(); \
{ __VA_ARGS__; } \
clock_t t2 = std::clock(); \
qDebug() << #__VA_ARGS__ << text << "->" << (long)((double)(t2 - t1) / (double)(CLOCKS_PER_SEC) * 1000.0); \
}
二、图片圆角处理
上边讲述了图片的模糊处理,其实说白了也就是对图像的每一个像素进行指定的滤镜操作,最终形成 一张新的图片。接下来我们要讲述的是根据一张矩形图来生成一张圆角矩形图,方式有2种我将分别介绍,个人根据自己的情况使用。
1、纯代码处理
纯代码处理,顾名思义也就是不需要外来的资源帮忙,其实原理也就是这样,通过给原来的图片设置掩码图像来生成圆角,也即我们需要自己从内存中绘制一张掩码图像,周围是透明的,里面是一个不透明的圆角矩形。效果如图5所示,实现代码如下:
QPixmap PixmapToRound(const QPixmap & img, int radius)
{
if (img.isNull())
{
return QPixmap();
} QSize size(img.size());
QBitmap mask(size);
QPainter painter(&mask);
painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHint(QPainter::SmoothPixmapTransform);
painter.fillRect(mask.rect(), Qt::white);
painter.setBrush(QColor(, , ));
painter.drawRoundedRect(mask.rect(), radius, radius); QPixmap image = img;// .scaled(size);
image.setMask(mask);
return image;
}
图5 圆角预览
2、蒙版实现
所谓蒙版实现其实原理和方式1类似,只是上图上的掩码图片需要设计师类提供,这样的设计就需要设计师设计出多套蒙版,效果和图5一样,diamante如下:
QPixmap PixmapToRound(const QPixmap & img, const QPixmap & mengban, QSize size)
{
if (img.isNull())
{
return QPixmap();
}
QImage resultImage(size, QImage::Format_ARGB32_Premultiplied);
QPixmap mask(mengban.scaled(size)); //蒙层图片 QPainter painter(&resultImage);
painter.setRenderHints(QPainter::SmoothPixmapTransform);
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.fillRect(resultImage.rect(), Qt::transparent);
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
painter.drawPixmap(, , mask);
painter.setCompositionMode(QPainter::CompositionMode_SourceOut);
painter.drawPixmap(, , img.scaled(size));
painter.setCompositionMode(QPainter::CompositionMode_DestinationOver);
painter.end(); return QPixmap::fromImage(resultImage);
}
demo下载链接:http://download.csdn.net/detail/qq_30392343/9591008
很重要--转载声明
- 本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords
- 如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。
qt之图像处理的更多相关文章
- Qt Quick 图像处理实例之美图秀秀(附源代码下载)
在<Qt Quick 之 QML 与 C++ 混合编程具体解释>一文中我们解说了 QML 与 C++ 混合编程的方方面面的内容,这次我们通过一个图像处理应用.再来看一下 QML 与 C++ ...
- QT 数字图像处理 笔记一
1.被有符号整数和无符号整数十足的坑了一上午.我在实现图像旋转的时候先把坐标轴中心平移到图像中心:painter.translate(up_x+temp_w,up_y+temp_h);注意这里面各个数 ...
- 基于Qt的图像处理技术和算法
https://blog.csdn.net/silangquan/article/details/41008183
- Qt:&OpenCV—Q图像处理基本操作(Code)
原文链接:http://www.cnblogs.com/emouse/archive/2013/03/31/2991333.html 作者写作一系列:http://www.cnblogs.com/em ...
- Qt Quick实现的涂鸦程序
之前一直以为 Qt Quick 里 Canvas 才干够自绘.后来发觉不是,原来还有好几种方式都能够画图! 能够使用原始的 OpenGL(Qt Quick 使用 OpenGL 渲染).能够构造QSGN ...
- Qt Quick实现的疯狂算数游戏
使用 Qt Quick 写了个小游戏:疯狂算数.支持 Windows 和 Android 两个平台. 游戏简单,但牵涉到下面你的 Qt Quick 主题: 自己实现一个按钮 自适应分辨率 国际化 QM ...
- Qt编程之QImage类小结
最近用Qt做图像处理,以下references是需要用到的 references: http://blog.csdn.net/lyc_daniel/article/details/9193881 ht ...
- Qt Quick 布局演示
于 Qt Widgets 于,我们经常使用许多布局管理器来管理界面 widgets . 于 Qt Quick 实际上,有两个相关的管理和布局库,所谓集 Item Positioner ,所谓集 Ite ...
- QT中VideoProbe的简介和实现
一.遇到问题 在Android机上使用QT进行图像处理程序设计的时候,遇到的一个比较明显的问题就是图片采集的问题----摄像头获得是实时的视频,如果我们想从中动态地截获图片,并且转换成M ...
随机推荐
- Cow Contest POJ - 3660 (floyd 传递闭包)
N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a programming contest. As we ...
- avue的小白之路
经过几天的看实例,我稍稍了解到了avue,写这个博客主要是最近学习avue的一个总结.. avue是基于vue与element ui的一个框架,强烈建议等了解这其中道理在学习avue会事半功倍:这是我 ...
- Python+Tkinter 实现计算器功能
#=================================================================================== import tkinter ...
- mysql5.7.X版本only_full_group_by问题解决
一.出错原因 最近因为开发数据库与部署数据库版本不同,带来了几个问题,其中only_full_group_by问题是之前没有遇到的. 具体报错如下 [Err] 1055 - Expression #1 ...
- PHP调用微信wx_JSSDK录音并播放,
<?php require_once "jssdk.php"; $jssdk = new JSSDK("wx7a862ec806328ca2", &quo ...
- h5软键盘挡住输入框问题解决(android)
问题 移动端浏览器中的表单在部分android机型上测试,点击靠下的输入框时会遇到弹出的软键盘挡住输入框问题 ios可自身弹起(ios自身的调整偶尔也会出问题,例如第三方键盘会遮挡,原因是第三方输入法 ...
- IOS开发中将定时器添加到runLoop中
runLoop主要就是为线程而生的.他能够让线程在有任务的时候保持工作状态,没有任务的时候让线程处于休眠待备状态. 主线程的runloop默认是开启的.主线程上创建的定时器已经默认添加到runLoop ...
- 五、JAVA反射、线程
第五节:Java反射.线程 线程 1.进程:进程是程序的基本执行实体,进程是线程的容器. 线程:被称为轻量进程,是程序执行流的最小单元.线程是进程中的一个实 ...
- Java当中的IO二
1.大文件的读写方法 由于文件很大,我们不能一下子把文件内的所有内容都读取出来,所以只能一段一段的读取 注意:在关闭read()和write()的时候可能会产生IOException,需要对其进行处理 ...
- vue项目中的相关插件
所有安装都是cd到该项目目录中安装 -S代表将插件添加到项目中的package.json文件 1.iview 是一套基于 Vue.js 的开源 UI 组件库,主要服务于 PC 界面的中后台产品 cnp ...