毕业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

如果您觉得文章不错,不妨给个打赏,写作不易,感谢各位的支持。您的支持是我最大的动力,谢谢!!! 

 

很重要--转载声明

  1. 本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords
  2. 如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。

qt之图像处理的更多相关文章

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

    在<Qt Quick 之 QML 与 C++ 混合编程具体解释>一文中我们解说了 QML 与 C++ 混合编程的方方面面的内容,这次我们通过一个图像处理应用.再来看一下 QML 与 C++ ...

  2. QT 数字图像处理 笔记一

    1.被有符号整数和无符号整数十足的坑了一上午.我在实现图像旋转的时候先把坐标轴中心平移到图像中心:painter.translate(up_x+temp_w,up_y+temp_h);注意这里面各个数 ...

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

    https://blog.csdn.net/silangquan/article/details/41008183

  4. Qt:&OpenCV—Q图像处理基本操作(Code)

    原文链接:http://www.cnblogs.com/emouse/archive/2013/03/31/2991333.html 作者写作一系列:http://www.cnblogs.com/em ...

  5. Qt Quick实现的涂鸦程序

    之前一直以为 Qt Quick 里 Canvas 才干够自绘.后来发觉不是,原来还有好几种方式都能够画图! 能够使用原始的 OpenGL(Qt Quick 使用 OpenGL 渲染).能够构造QSGN ...

  6. Qt Quick实现的疯狂算数游戏

    使用 Qt Quick 写了个小游戏:疯狂算数.支持 Windows 和 Android 两个平台. 游戏简单,但牵涉到下面你的 Qt Quick 主题: 自己实现一个按钮 自适应分辨率 国际化 QM ...

  7. Qt编程之QImage类小结

    最近用Qt做图像处理,以下references是需要用到的 references: http://blog.csdn.net/lyc_daniel/article/details/9193881 ht ...

  8. Qt Quick 布局演示

    于 Qt Widgets 于,我们经常使用许多布局管理器来管理界面 widgets . 于 Qt Quick 实际上,有两个相关的管理和布局库,所谓集 Item Positioner ,所谓集 Ite ...

  9. QT中VideoProbe的简介和实现

    一.遇到问题        在Android机上使用QT进行图像处理程序设计的时候,遇到的一个比较明显的问题就是图片采集的问题----摄像头获得是实时的视频,如果我们想从中动态地截获图片,并且转换成M ...

随机推荐

  1. 在命令行输入python出现“Warning:This Python interpreter is in a conda environment, but the environment has not been activated. Libraries may fail to load. To activate this environment please see https://conda.

    [现象] 在命令行输入python出现“Warning:This Python interpreter is in a conda environment, but the environment h ...

  2. HTML学习笔记【思维导图版】

  3. babel分析

    现在都用 ES6 新语法以及 ES7 新特性来写应用了,但是浏览器和相关的环境还不能友好的支持,需要用到 Babel 转码器来转换成 ES5 的代码 相信大家都看到过如下的名词: babel-pres ...

  4. 一、OpenStack环境准备及共享组件安装

    一.OpenStack部署环境准备: 1.关闭防火墙所有虚拟机都要操作 # setenforce 0 # systemctl stop firewalld 2.域名解析所有虚拟机都要操作 # cat ...

  5. mongo删除指定字段,可多个字段同时删除

    参考代码: db.getCollection('Person').update({"email":{$exists:true}},{$unset:{"email" ...

  6. TortoiseSVN--clearup清理失败解决办法

    工作中经常遇到update.commit 失败导致冲突问题,需要用clear up来清除问题,个别异常情况导致clear up失败,进入死循环!可以使用sqlite3.exe清理一下wc.db文件的队 ...

  7. java简单框架设计

    设计框架包可以作为一个工具给大家用,需要有完全不同设计思路给出来,不同于我们去做一个web服务.网站. 或者一个业务微服务,需要从原来使用视角转换成一个构建者视角. 框架或者工具,更多是框架来管理或者 ...

  8. 主流图库对比以及JanusGraph入门

    1.Overall Comparison Name Neo4j JanusGraph Giraph Jena 1.Compute Framework Yes Yes Yes 2.External Co ...

  9. Android SDK提供的常用控件Widget “常用控件”“Android原生”

    Android提供一个标准的视图工具箱来帮助创建简单的UI界面.通过使用这些控件(必要时,可以对这些控件进行修改). 创建一个简单的.xml文件,从预览窗口可以看到Android SDK提供的原生控件 ...

  10. python用类实现xrange

    class xrange(object): def __init__(self, start, end=0, step=1): self.start = start self.end = end se ...