毕业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. C语言--第四次作业--数组

    1.本章学习总结 1.1 思维导图 1.2本章学习体会及代码量学习体会 1.2.1学习体会 不知不觉都快学习C语言结束了,自从开始了数组的学习就感觉难度瞬间几何级上升鸭(让人头大,感觉到了各种绝望), ...

  2. 【C语言编程练习】新娘与新郎

    1. 题目要求 新郎A,B,C与新娘 X,Y,Z.有人不知道她们谁和谁结婚了,询问了6位新人中的三位,A说他将和X结婚,X说她的未婚夫是C,C说她会和Z结婚,一听就知道是全是假话,请编程找出谁和谁结婚 ...

  3. hdu1814 Peaceful Commission

    hdu1814 Peaceful Commission 题意:2-sat裸题,打印字典序最小的 我写了三个 染色做法,正解 scc做法,不管字典序 scc做法,错误的字典序贪心 #include &l ...

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

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

  5. vue插件官方文档,做个记录

    vue的插件,组件都可以按照这种方式添加 官方文档 https://cn.vuejs.org/v2/guide/plugins.html 做个记录用

  6. Android滑动列表(拖拽,左滑删除,右滑完成)功能实现(1)

    场景: 近期做的TODO APP需要在主页添加一个功能,就是可以左滑删除,右滑完成.看了一下当前其他人做的例如仿探探式的效果,核心功能基本一样,但是和我预想的还是有少量区别,于是干脆自己重头学一遍如何 ...

  7. Markdown常用快捷键

    Markdown使用的符号:井号,星号,大于号,中括号,竖线,横杠,波浪线,反引号 # ,*, > ,[],|,-,~,` 井号 + 空格:根据空格的个数显示各标题的大小 标题一 标题二 标题三 ...

  8. RDD算子

    RDD算子 #常用Transformation(即转换,延迟加载) #通过并行化scala集合创建RDD val rdd1 = sc.parallelize(Array(1,2,3,4,5,6,7,8 ...

  9. CommonsChunkPlugin

    CommonsChunk 插件的作用就是提取代码中的公共代码,然后将公共模块打包到一个独立的文件中,以便在其它的入口和模块中使用,原理就是把多个入口共同的依赖都给定义成一个新入口 多种打包情况: 单一 ...

  10. Centos7 编译安装 Nginx PHP Mariadb Memcached 扩展 ZendOpcache扩展 (实测 笔记 Centos 7.3 + Openssl 1.1.0e + Mariadb 10.1.22 + Nginx 1.12.0 + PHP 7.1.4 + Laravel 5.4 )

    环境: 系统硬件:vmware vsphere (CPU:2*4核,内存2G,双网卡) 系统版本:CentOS-7-x86_64-Minimal-1611.iso 安装步骤: 1.准备 1.0 查看硬 ...