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 高斯优化说明

具体细节处理请看原文中描述。在这里我只贴出使用高斯一维函数处理的滤镜,和使用滤镜对照片上每一个像素进行处理的代码,代码如下:

 1 //高斯模糊算法 一维(O(2*x*y*2r))形式的高斯函数 比二维(O(x*y*(2r)^2))效率高 对应Blur1D滤镜算法
 2     void Gauss(filter_t& kernel, long radius)
 3     {
 4         kernel.set(radius, Diamet(radius));
 5
 6         static const double SQRT2PI = sqrt(2.0 * PI);
 7
 8         double sigma = (double)radius / 3.0;
 9         double sigma2 = 2.0 * sigma * sigma;
10         double sigmap = sigma * SQRT2PI;
11
12         for (long n = 0, i = -kernel.radius(); i <= kernel.radius(); ++i, ++n)
13             kernel[n] = exp(-(double)(i * i) / sigma2) / sigmap;
14     }

下面的代码是对应高斯一维处理函数的图片像素点处理方法:

 1 void Blur1D(bitmap_t& bitmap, filter_t& kernel)
 2     {
 3         Normalization(kernel);
 4
 5         buffer_t buff(bitmap);
 6
 7         for (long inx = 0, y = 0; y < bitmap.h(); ++y)
 8         {
 9             for (long x = 0; x < bitmap.w(); ++x, ++inx)
10             {
11                 for (long n = 0, i = -kernel.radius(); i <= kernel.radius(); ++i, ++n)
12                 {
13                     long i_k = Edge(i, x, bitmap.w());
14                     long inx_k = inx + i_k;
15                     buff[inx].r += bitmap[inx_k].r * kernel[n];
16                     buff[inx].g += bitmap[inx_k].g * kernel[n];
17                     buff[inx].b += bitmap[inx_k].b * kernel[n];
18                 }
19             }
20         }
21
22         for (long inx = 0, x = 0; x < bitmap.w(); ++x)
23         {
24             for (long y = 0; y < bitmap.h(); ++y)
25             {
26                 inx = y * bitmap.w() + x;
27                 double r = 0.0, g = 0.0, b = 0.0;
28                 for (long n = 0, i = -kernel.radius(); i <= kernel.radius(); ++i, ++n)
29                 {
30                     long i_k = Edge(i, y, bitmap.h());
31                     long inx_k = inx + i_k * bitmap.w();
32                     r += buff[inx_k].r * kernel[n];
33                     g += buff[inx_k].g * kernel[n];
34                     b += buff[inx_k].b * kernel[n];
35                 }
36                 bitmap[inx].r = Clamp<bitmap_t::channel_t>(r);
37                 bitmap[inx].g = Clamp<bitmap_t::channel_t>(g);
38                 bitmap[inx].b = Clamp<bitmap_t::channel_t>(b);
39             }
40         }
41     }

理解了上边的代码后,只需要下面几行代码,就可以生成模糊后的图片,其中resultImage是输出型参数,模糊后的图片存放在其中。

1 filter::bitmap_t bmp;
2     bmp.set((filter::bitmap_t::pixel_t*)resultImage.bits(),
3         resultImage.width(), resultImage.height());
4
5     filter::Filter(pair[4], bmp, radius);

初次之外demo中还提到了一个检测算法时间复杂度的方法,通过调用该方法可以检测每个图片处理过程的时间长短。

1 #define CHECK_TIME(text, ...) 2 { 3     clock_t t1 = std::clock(); 4     { __VA_ARGS__; } 5     clock_t t2 = std::clock(); 6     qDebug() << #__VA_ARGS__ << text << "->" << (long)((double)(t2 - t1) / (double)(CLOCKS_PER_SEC) * 1000.0); 7 }

二、图片圆角处理

上边讲述了图片的模糊处理,其实说白了也就是对图像的每一个像素进行指定的滤镜操作,最终形成 一张新的图片。接下来我们要讲述的是根据一张矩形图来生成一张圆角矩形图,方式有2种我将分别介绍,个人根据自己的情况使用。

1、纯代码处理

纯代码处理,顾名思义也就是不需要外来的资源帮忙,其实原理也就是这样,通过给原来的图片设置掩码图像来生成圆角,也即我们需要自己从内存中绘制一张掩码图像,周围是透明的,里面是一个不透明的圆角矩形。效果如图5所示,实现代码如下:

 1 QPixmap PixmapToRound(const QPixmap & img, int radius)
 2 {
 3     if (img.isNull())
 4     {
 5         return QPixmap();
 6     }
 7
 8     QSize size(img.size());
 9     QBitmap mask(size);
10     QPainter painter(&mask);
11     painter.setRenderHint(QPainter::Antialiasing);
12     painter.setRenderHint(QPainter::SmoothPixmapTransform);
13     painter.fillRect(mask.rect(), Qt::white);
14     painter.setBrush(QColor(0, 0, 0));
15     painter.drawRoundedRect(mask.rect(), radius, radius);
16
17     QPixmap image = img;// .scaled(size);
18     image.setMask(mask);
19     return image;
20 }

图5 圆角预览

2、蒙版实现

所谓蒙版实现其实原理和方式1类似,只是上图上的掩码图片需要设计师类提供,这样的设计就需要设计师设计出多套蒙版,效果和图5一样,diamante如下:

 1 QPixmap PixmapToRound(const QPixmap & img, const QPixmap & mengban, QSize size)
 2 {
 3     if (img.isNull())
 4     {
 5         return QPixmap();
 6     }
 7     QImage resultImage(size, QImage::Format_ARGB32_Premultiplied);
 8     QPixmap mask(mengban.scaled(size)); //蒙层图片
 9
10     QPainter painter(&resultImage);
11     painter.setRenderHints(QPainter::SmoothPixmapTransform);
12     painter.setCompositionMode(QPainter::CompositionMode_Source);
13     painter.fillRect(resultImage.rect(), Qt::transparent);
14     painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
15     painter.drawPixmap(0, 0, mask);
16     painter.setCompositionMode(QPainter::CompositionMode_SourceOut);
17     painter.drawPixmap(0, 0, img.scaled(size));
18     painter.setCompositionMode(QPainter::CompositionMode_DestinationOver);
19     painter.end();
20
21     return QPixmap::fromImage(resultImage);
22 }

demo下载链接:http://download.csdn.net/detail/qq_30392343/9591008

时间: 2024-10-15 00:26:23

qt之图像处理的相关文章

Qt Quick 图像处理实例之美图秀秀(附源码下载)

在<Qt Quick 之 QML 与 C++ 混合编程详解>一文中我们讲解了 QML 与 C++ 混合编程的方方面面的内容,这次我们通过一个图像处理应用,再来看一下 QML 与 C++ 混合编程的威力,同时也为诸君揭开美图秀秀.魔拍之类的相片美化应用的底层原理. 项目的创建过程请参考<Qt Quick 之 Hello World 图文详解>,项目名称为 imageProcessor ,创建完成后需要添加两个文件: imageProcessor.h 和 imageProcessor.

基于Qt的图像处理技术和算法

原文链接: http://developer.nokia.com/community/wiki/Image_editing_techniques_and_algorithms_using_Qt 这篇文章主要阐述了如何使用Qt在像素级别上对图像进行操作,并实现了一些图像效果,这些效果主要有:灰度,模糊,锐化,添加相框,金属质感,改变图像饱和度,亮度还有白平衡. 介绍 文章中,我们将讨论在Qt中修改图像的一些技术和算法,在这之前,你必须知道在Qt中操作图像的一些方法. .在Qt中有两种表示图像的类,

Qt Quick核心编程从入门到精通

本文是个推荐文章,推荐foruok博主的Qt quick 核心编程的系列经典编程! foruok 博主 的Qt Quick系列文章: Qt Quick 简介 QML 语言基础 Qt Quick 之 Hello World 图文详解 Qt Quick 简单教程 Qt Quick 事件处理之信号与槽 Qt Quick事件处理之鼠标.键盘.定时器 Qt Quick 事件处理之捏拉缩放与旋转 Qt Quick 组件与对象动态创建详解 Qt Quick 布局介绍 Qt Quick 之 QML 与 C++

Qt Quick里的图形效果——渐变(Gradient)

Qt Quick提供了三种渐变图形效果: ConicalGradient,锥形渐变 LinearGradient,线性渐变 RadialGradient,径向渐变 效果 下图是我设计的示例效果: 图 1 渐变图形效果 如图所示,第一行为线性渐变,第二行为锥形渐变,第三行为径向渐变. 渐变元素与其他图形效果元素不同之处在于:渐变元素既可以用来改变一个已有的元素(如Image),也有可以独立使用.如你在示例效果图中看到的那样,每一行前两个是独立使用渐变元素的效果,后两个是讲渐变效果应用到其它元素上的

Qt Quick实现的疯狂算数游戏

使用 Qt Quick 写了个小游戏:疯狂算数.支持 Windows 和 Android 两个平台. 就差您这一票了亲:博客之星评选,点击投我一票,谢谢.投过了也可以点哦,每天都可以投投一票. 游戏简单,但牵涉到下面你的 Qt Quick 主题: 自己实现一个按钮 自适应分辨率 国际化 QML与C++混合编程 APK图标设置 APK名称汉化 动画 其实所有这些内容,在我的书<Qt Quick核心编程>里都讲到了,感兴趣的朋友可以看我的书. 大概来看一下吧,先看效果. Android 手机运行效

Qt Quick里的粒子系统

就差您这一票了亲:博客之星评选,点击投我一票,谢谢.投过了也可以点哦,每天都可以投投一票. Qt Quick提供了一个粒子系统,提供了四种主要的 QML 类型: ParticleSystem ,粒子系统,它维护一个粒子系统相关的 Emitters . Painters . Affectors ,Emitters . Painters . Affectors 要想一起玩儿,就得指定同一个 ParticleSystem. ParticleSystem Painters , 它负责渲染一个粒子.Par

Qt Quick里的图形效果——颜色(Color)

Qt Quick提供了通过改变一个 Item 的颜色来产生各种各样效果的元素.有下面几种: BrightnessContrast,调整亮度和对比度 ColorOverlay,在源 Item 上覆盖一层颜色 Colorize,设置源 Item 的 HSL 颜色空间 Desaturate,降低颜色的饱和度 GammaAdjust,使用 gamma 曲线来改变源 Item 的照度 HueSaturation,在 HSL 颜色空间改变源 Item 的颜色 LevelAdjust,在 RGBA 颜色空间调

Qt Quick里的AnimatedSprite的用法

之前用 AnimatedImage 时一直对 AnimatedSprite 很奇怪,想试一下怎么用,一下子没试出来,放下了,后来一直没时间. OK ,今天想起来,又搞了一下. AnimatedSprite 说明 AnimatedSprite 元素用来播放精灵动画. 一些常见的属性解释: source 属性是 url 类型的,接受一个包含多帧的图片. frameWidth 和 frameHeight 指定帧大小. frameX 和 frameY 指定第一帧的左上角. frameCount 指定这个

Qt Quick之ListView下拉刷新数据

Qt Quick里的ListView,本身是Flickable的派生类,当你用鼠标拖曳或者手指触摸(触摸屏)时,会产生flickStarted和flickEnded两个信号,利用这两个信号,就可以实现下拉刷新数据,当然上拉刷新也是可以的. 创建一个Qt Quick App项目,添加dynamicModel.h和dynamicModel.cpp两个文件,用于实现DynamicListModel.项目创建过程参考<Qt Quick 之 Hello World 图文详解>. 我们实现的下拉刷新效果有