一、图像挤压特效

1、原理

图像压效果本质的图像坐标的非线性变换,将图像向内挤压,挤压的过程产生压缩变形,从而形成的效果。

挤压效果的实现是通过极坐标的形式,设图像中心为O(x,y),某点距离中心O的距离为半径R,非线性方式改变半径R但不改变点的方向,就构成了图像挤压。也可以自定义加压中心点,计算半径方式相同。

图像像素变换倍率使用 y=sqrt(x)。

图像上点P与图像中心O的距离为R,图像挤压就是P点坐标映射到OP直线上的点R2位置,其中| OR2 |=sqrt(OP)*ratio。

2、实现

  1. void Pinch(Mat& img, Mat& dst, int degree)
  2. {
  3. if (degree < ) degree = ;
  4. if (degree > ) degree = ;
  5.  
  6. if (dst.empty())
  7. dst.create(img.rows, img.cols, img.type());
  8. dst = cv::Scalar::all();
  9.  
  10. int chns = img.channels();
  11. int height = img.rows;
  12. int width = img.cols;
  13.  
  14. int midX = width / ;
  15. int midY = height / ;
  16. int i, j, k;
  17. int X, Y, offsetX, offsetY;
  18. double radian, radius; //弧和半径
  19.  
  20. for (i = ; i < height; i++)
  21. {
  22. for (j = ; j < width; j++)
  23. {
  24. offsetX = j - midX;
  25. offsetY = i - midY;
  26.  
  27. radian = atan2((double)offsetY, (double)offsetX);
  28.  
  29. // 半径
  30. radius = sqrtf((float)(offsetX*offsetX + offsetY * offsetY));
  31. radius = sqrtf(radius)*degree;
  32.  
  33. X = (int)(radius*cos(radian)) + midX;
  34. Y = (int)(radius*sin(radian)) + midY;
  35.  
  36. if (X < ) X = ;
  37. if (X >= width) X = width - ;
  38. if (Y < ) Y = ;
  39. if (Y >= height) Y = height - ;
  40.  
  41. for (k = ; k < chns; k++)
  42. {
  43. dst.at<Vec3b>(i, j)[k] = img.at<Vec3b>(Y, X)[k];
  44. }
  45. }
  46. }
  47. }
  48.  
  49. Mat src_img;
  50. Mat dst_img;
  51. int rato = ;
  52.  
  53. void call_back(int, void*)
  54. {
  55. Pinch(src_img, dst_img, rato);
  56. imshow("Pinch图", dst_img);
  57. }
  58.  
  59. int main() {
  60.  
  61. src_img = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\pic18.bmp");
  62. imshow("原图", src_img);
  63.  
  64. Pinch(src_img, dst_img, rato);
  65. imshow("Pinch图", dst_img);
  66.  
  67. namedWindow("Pinch图");
  68. createTrackbar("Pinch倍率", "Pinch图", &rato, , call_back);
  69. call_back(rato, );
  70.  
  71. waitKey();
  72. }

3、测试效果

测试1:

测试2:不同倍率下棋盘格的挤压效果。

二、哈哈镜特效

1、原理

图像坐标的非线性变换,实现k的根号与k的比值,sqrt(k)/k, 当k为1时总倍率为1,当k小于1时,总倍率为渐变倍率。

2、实现

  1. void Pinch(Mat& img, Mat& dst, int x, int y, int degree)
  2. {
  3. if (dst.empty())
  4. dst.create(img.rows, img.cols, img.type());
  5.  
  6. dst = cv::Scalar::all();
  7. cout << "x,y " << x << " " << y << endl;
  8.  
  9. int chns = img.channels();
  10. int height = img.rows;
  11. int width = img.cols;
  12.  
  13. midX = x;
  14. midY = y;
  15. int R = ;
  16.  
  17. int i, j, k;
  18. int X, Y, offsetX, offsetY;
  19. double radian, radius; //弧和半径
  20.  
  21. for (i = ; i < height; i++)
  22. {
  23. for (j = ; j < width; j++)
  24. {
  25. offsetX = j - midX;
  26. offsetY = i - midY;
  27. radian = atan2((double)offsetY, (double)offsetX);
  28.  
  29. // 半径
  30. radius = sqrtf((float)(offsetX*offsetX + offsetY * offsetY));
  31. if (radius <= R && radius > ) {
  32. float k = sqrtf(radius/R) * radius / R * degree;
  33. X = (int)( cos(radian) * k) + midX;
  34. Y = (int)( sin(radian) * k) + midY;
  35.  
  36. if (X < ) X = ;
  37. if (X >= width) X = width - ;
  38. if (Y < ) Y = ;
  39. if (Y >= height) Y = height - ;
  40.  
  41. for (k = ; k < chns; k++)
  42. {
  43. dst.at<Vec3b>(i, j)[k] = img.at<Vec3b>(Y, X)[k];
  44. }
  45. }
  46. else
  47. {
  48. for (k = ; k < chns; k++)
  49. {
  50. dst.at<Vec3b>(i, j)[k] = img.at<Vec3b>(i, j)[k];
  51. }
  52. }
  53. }
  54. }
  55.  
  56. cout << " midX, midY " << midX << " " << midY << endl;
  57. }

3、测试效果

测试1:哈哈镜效果

测试2:大倍率呈现潜望镜效果。

测试3:

三、图像扭曲

对图像的像素坐标进行正弦变换,映射到对应坐标就完成了图像扭曲。关键代码如下:

  1. for (int j = ; j < width; j++)
  2. {
  3. double temp = degree * sin(1.0 * j / width * pi * T ); // [-degree,degree]
  4. temp = degree + temp; // [0, 2*degree]
  5. for (int i = int(temp + 0.5); i < height + temp - * degree; i++)
  6. {
  7. X = (int)((i - temp) * (height) / (height - degree));
  8. if (X >= img.rows)
  9. X = img.rows - ;
  10. if (X < )
  11. X = ;
  12.  
  13. for (int c = ; c < chns; c++)
  14. {
  15. dst.at<Vec3b>(i, j)[c] = img.at<Vec3b>(X, j)[c];
  16. }
  17. }
  18. }

测试1:

测试2:

4、参考文献

1、《学习OpenCV》,清华大学出版社,Gary Bradski, Adrian kaehler著

2、仿射变换

http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/imgtrans/warp_affine/warp_affine.html

3、PhotoShop算法实现高级篇--挤压特效(三十六)

https://blog.csdn.net/kezunhai/article/details/41873775

技术博客,转载请注明。

https://www.cnblogs.com/pingwen/p/12503047.html

OpenCV3入门(十四)图像特效—挤压、哈哈镜、扭曲的更多相关文章

  1. Spring入门(十四):Spring MVC控制器的2种测试方法

    作为一名研发人员,不管你愿不愿意对自己的代码进行测试,都得承认测试对于研发质量保证的重要性,这也就是为什么每个公司的技术部都需要质量控制部的原因,因为越早的发现代码的bug,成本越低,比如说,Dev环 ...

  2. OpenCV3入门(四)图像的基础操作

    1.访问图像像素 1)灰度图像 2)彩色图像 OpenCV中的颜色顺序是BGR而不是RGB. 访问图像的像素在OpenCV中就是访问Mat矩阵,常用的有三种方法. at定位符访问 Mat数据结构,操作 ...

  3. [WebGL入门]十四,绘制多边形

    注意:文章翻译http://wgld.org/.原作者杉本雅広(doxas),文章中假设有我的额外说明,我会加上[lufy:].另外,鄙人webgl研究还不够深入.一些专业词语,假设翻译有误,欢迎大家 ...

  4. Android入门(十四)内容提供器-实现跨程序共享实例

    原文链接:http://www.orlion.ga/661/ 打开SQLite博文中创建的 DatabaseDemo项目,首先将 MyDatabaseHelper中使用 Toast弹出创建数据库成功的 ...

  5. SpringBoot入门 (十四) Security安全控制

    本文记录在SpringBoot使用SpringSecurity进行安全访问控制. 一 什么是Security Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访 ...

  6. 跟我学Python图像处理丨图像特效处理:毛玻璃、浮雕和油漆特效

    摘要:本文讲解常见的图像特效处理,从而让读者实现各种各样的图像特殊效果,并通过Python和OpenCV实现. 本文分享自华为云社区<[Python图像处理] 二十四.图像特效处理之毛玻璃.浮雕 ...

  7. 网络编程懒人入门(十):一泡尿的时间,快速读懂QUIC协议

    1.TCP协议到底怎么了? 现时的互联网应用中,Web平台(准确地说是基于HTTP及其延伸协议的客户端/服务器应用)的数据传输都基于 TCP 协议. 但TCP 协议在创建连接之前需要进行三次握手(如下 ...

  8. OpenCV3入门(十三)图像运动模糊

    1.原理 运动模糊产生: 由于相机传感器或物体相对运动, 按快门瞬间造成图像产生运动模糊. 在用摄像机获取景物图像时,如果在相机曝光期间景物和摄像机之间存在相对运动,例如用照相机拍摄快速运动的物体,或 ...

  9. 【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑

    http://blog.csdn.net/poem_qianmo/article/details/26977557 本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog ...

随机推荐

  1. OpenCV 使用FLANN进行特征点匹配

    #include <stdio.h> #include <iostream> #include "opencv2/core/core.hpp" #inclu ...

  2. 高可用(keepalived+lvs)

    博主本人平和谦逊,热爱学习,读者阅读过程中发现错误的地方,请帮忙指出,感激不尽 架构图: 本次实验严格按照下图完成 1.系统环境设置 1.1SELinux设置 vim /etc/selinux/con ...

  3. HihoCode-1323-回文字符串

    参考博客: https://blog.csdn.net/mitsuha_/article/details/76690634 https://blog.csdn.net/u014142379/artic ...

  4. Angular开发者指南(五)服务

    服务 AngularJS服务是使用依赖注入(DI)连接在一起的可替代对象. 可以使用服务在整个应用程式中整理和分享程式码. AngularJS服务有: 延迟初始化 - AngularJS只在应用程序组 ...

  5. 框架之MyBatis

    什么是框架,简单的来说框架就是一个程序的半成品,而我们就是的工作就是根据我们的工作需要将其完善.MyBatis框架的作用就是将我们使用JDBC操作数据库的过程移交给MyBatis,让它来帮我们完成这些 ...

  6. (转)python中join()方法

    原文:http://blog.csdn.net/weixin_40475396/article/details/78227747 函数:string.join() Python中有join()和os. ...

  7. 使用java列举所有给定数组中和为定值的组合

    import java.util.Arrays; public class SolveProb { ]; ;// 记录当前 public SolveProb() { } public static v ...

  8. 吴裕雄--天生自然 R语言开发学习:方差分析(续一)

    #-------------------------------------------------------------------# # R in Action (2nd ed): Chapte ...

  9. JavaScript中的document.fullscreenEnabled

    本文主要讲述了: 什么是document.fullscreenEnabled 作用 兼容性 正文 什么是document.fullscreenEnabled document.fullscreenEn ...

  10. [大餐]开发摘记1--我的Fragment通信的框架

    [大餐]开发摘记1--我的Fragment通信的框架 | 卖牙膏的芖口钉 盒子 盒子 博客 分类 标签 友链 大专栏  [大餐]开发摘记1--我的Fragment通信的框架ass="ROUN ...