OpenCV3入门(十四)图像特效—挤压、哈哈镜、扭曲
一、图像挤压特效
1、原理
图像压效果本质的图像坐标的非线性变换,将图像向内挤压,挤压的过程产生压缩变形,从而形成的效果。
挤压效果的实现是通过极坐标的形式,设图像中心为O(x,y),某点距离中心O的距离为半径R,非线性方式改变半径R但不改变点的方向,就构成了图像挤压。也可以自定义加压中心点,计算半径方式相同。
图像像素变换倍率使用 y=sqrt(x)。

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

2、实现
void Pinch(Mat& img, Mat& dst, int degree)
{
if (degree < ) degree = ;
if (degree > ) degree = ; if (dst.empty())
dst.create(img.rows, img.cols, img.type());
dst = cv::Scalar::all(); int chns = img.channels();
int height = img.rows;
int width = img.cols; int midX = width / ;
int midY = height / ;
int i, j, k;
int X, Y, offsetX, offsetY;
double radian, radius; //弧和半径 for (i = ; i < height; i++)
{
for (j = ; j < width; j++)
{
offsetX = j - midX;
offsetY = i - midY; radian = atan2((double)offsetY, (double)offsetX); // 半径
radius = sqrtf((float)(offsetX*offsetX + offsetY * offsetY));
radius = sqrtf(radius)*degree; X = (int)(radius*cos(radian)) + midX;
Y = (int)(radius*sin(radian)) + midY; if (X < ) X = ;
if (X >= width) X = width - ;
if (Y < ) Y = ;
if (Y >= height) Y = height - ; for (k = ; k < chns; k++)
{
dst.at<Vec3b>(i, j)[k] = img.at<Vec3b>(Y, X)[k];
}
}
}
} Mat src_img;
Mat dst_img;
int rato = ; void call_back(int, void*)
{
Pinch(src_img, dst_img, rato);
imshow("Pinch图", dst_img);
} int main() { src_img = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\pic18.bmp");
imshow("原图", src_img); Pinch(src_img, dst_img, rato);
imshow("Pinch图", dst_img); namedWindow("Pinch图");
createTrackbar("Pinch倍率", "Pinch图", &rato, , call_back);
call_back(rato, ); waitKey();
}
3、测试效果
测试1:

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

二、哈哈镜特效
1、原理
图像坐标的非线性变换,实现k的根号与k的比值,sqrt(k)/k, 当k为1时总倍率为1,当k小于1时,总倍率为渐变倍率。
2、实现
void Pinch(Mat& img, Mat& dst, int x, int y, int degree)
{
if (dst.empty())
dst.create(img.rows, img.cols, img.type()); dst = cv::Scalar::all();
cout << "x,y " << x << " " << y << endl; int chns = img.channels();
int height = img.rows;
int width = img.cols; midX = x;
midY = y;
int R = ; int i, j, k;
int X, Y, offsetX, offsetY;
double radian, radius; //弧和半径 for (i = ; i < height; i++)
{
for (j = ; j < width; j++)
{
offsetX = j - midX;
offsetY = i - midY;
radian = atan2((double)offsetY, (double)offsetX); // 半径
radius = sqrtf((float)(offsetX*offsetX + offsetY * offsetY));
if (radius <= R && radius > ) {
float k = sqrtf(radius/R) * radius / R * degree;
X = (int)( cos(radian) * k) + midX;
Y = (int)( sin(radian) * k) + midY; if (X < ) X = ;
if (X >= width) X = width - ;
if (Y < ) Y = ;
if (Y >= height) Y = height - ; for (k = ; k < chns; k++)
{
dst.at<Vec3b>(i, j)[k] = img.at<Vec3b>(Y, X)[k];
}
}
else
{
for (k = ; k < chns; k++)
{
dst.at<Vec3b>(i, j)[k] = img.at<Vec3b>(i, j)[k];
}
}
}
} cout << " midX, midY " << midX << " " << midY << endl;
}
3、测试效果
测试1:哈哈镜效果

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

测试3:

三、图像扭曲
对图像的像素坐标进行正弦变换,映射到对应坐标就完成了图像扭曲。关键代码如下:
for (int j = ; j < width; j++)
{
double temp = degree * sin(1.0 * j / width * pi * T ); // [-degree,degree]
temp = degree + temp; // [0, 2*degree]
for (int i = int(temp + 0.5); i < height + temp - * degree; i++)
{
X = (int)((i - temp) * (height) / (height - degree));
if (X >= img.rows)
X = img.rows - ;
if (X < )
X = ; for (int c = ; c < chns; c++)
{
dst.at<Vec3b>(i, j)[c] = img.at<Vec3b>(X, j)[c];
}
}
}
测试1:

测试2:

4、参考文献
1、《学习OpenCV》,清华大学出版社,Gary Bradski, Adrian kaehler著
2、仿射变换
3、PhotoShop算法实现高级篇--挤压特效(三十六)
https://blog.csdn.net/kezunhai/article/details/41873775
技术博客,转载请注明。
OpenCV3入门(十四)图像特效—挤压、哈哈镜、扭曲的更多相关文章
- Spring入门(十四):Spring MVC控制器的2种测试方法
作为一名研发人员,不管你愿不愿意对自己的代码进行测试,都得承认测试对于研发质量保证的重要性,这也就是为什么每个公司的技术部都需要质量控制部的原因,因为越早的发现代码的bug,成本越低,比如说,Dev环 ...
- OpenCV3入门(四)图像的基础操作
1.访问图像像素 1)灰度图像 2)彩色图像 OpenCV中的颜色顺序是BGR而不是RGB. 访问图像的像素在OpenCV中就是访问Mat矩阵,常用的有三种方法. at定位符访问 Mat数据结构,操作 ...
- [WebGL入门]十四,绘制多边形
注意:文章翻译http://wgld.org/.原作者杉本雅広(doxas),文章中假设有我的额外说明,我会加上[lufy:].另外,鄙人webgl研究还不够深入.一些专业词语,假设翻译有误,欢迎大家 ...
- Android入门(十四)内容提供器-实现跨程序共享实例
原文链接:http://www.orlion.ga/661/ 打开SQLite博文中创建的 DatabaseDemo项目,首先将 MyDatabaseHelper中使用 Toast弹出创建数据库成功的 ...
- SpringBoot入门 (十四) Security安全控制
本文记录在SpringBoot使用SpringSecurity进行安全访问控制. 一 什么是Security Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访 ...
- 跟我学Python图像处理丨图像特效处理:毛玻璃、浮雕和油漆特效
摘要:本文讲解常见的图像特效处理,从而让读者实现各种各样的图像特殊效果,并通过Python和OpenCV实现. 本文分享自华为云社区<[Python图像处理] 二十四.图像特效处理之毛玻璃.浮雕 ...
- 网络编程懒人入门(十):一泡尿的时间,快速读懂QUIC协议
1.TCP协议到底怎么了? 现时的互联网应用中,Web平台(准确地说是基于HTTP及其延伸协议的客户端/服务器应用)的数据传输都基于 TCP 协议. 但TCP 协议在创建连接之前需要进行三次握手(如下 ...
- OpenCV3入门(十三)图像运动模糊
1.原理 运动模糊产生: 由于相机传感器或物体相对运动, 按快门瞬间造成图像产生运动模糊. 在用摄像机获取景物图像时,如果在相机曝光期间景物和摄像机之间存在相对运动,例如用照相机拍摄快速运动的物体,或 ...
- 【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
http://blog.csdn.net/poem_qianmo/article/details/26977557 本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog ...
随机推荐
- python数据类型:字符串
字符串是python中最常见的数据类型,使用单引号或双引号创建字符串 python不支持单字符类型,单字符在python中也是字符串 文档原文:http://www.runoob.com/python ...
- 蓝桥杯-PREV31-小朋友排队
解法: 这题有点像冒泡排序,但是做这题并不需要冒泡排序. 假设第i个小朋友比第j个小朋友高,而且i < j 为了把队伍排成从小到大,第i个小朋友一定要去第j个小朋友的右边.又因为只能交换位置相邻 ...
- cs231n spring 2017 lecture16 Adversarial Examples and Adversarial Training
(没太听明白,以后再听) 1. 如何欺骗神经网络? 这部分研究最开始是想探究神经网络到底是如何工作的.结果人们意外的发现,可以只改变原图一点点,人眼根本看不出变化,但是神经网络会给出完全不同的答案.比 ...
- 1022 D进制的A+B (20 分)
题目:1022 D进制的A+B (20 分) 思路: 首先根据A.B的取值范围,可知A+B不过2^31,所以转换成进制数时的最长长度为31. 转换成进制的数存进数组,然后反向输出. 要注意和为0的情况 ...
- nodejs快速测试
对于一些js功能,可以通过nodejs快速搭建测试环境 1.这里我们先通过express脚手架快速搭建一个项目,或者init一个空项目 2.mkdir script 3.这里假设我们的场景是MQTT接 ...
- unittest(22)- p2p项目实战(8)-test_class_auto_incre
# 8.test_class_auto_incre # 使用ddt import requests import unittest from p2p_project_7.tools.http_requ ...
- python标准库-builtin 模块之compile,execfile
eval函数仅仅允许执行简单的表达式.对于更大的代码块时,使用compile和exec函数. 例子:使用 compile函数验证语法 NAME = "script.py" BODY ...
- Numpy入门(二):Numpy数组索引切片和运算
在Numpy中建立了数组或者矩阵后,需要访问数组里的成员,改变元素,并对数组进行切分和计算. 索引和切片 Numpy数组的访问模式和python中的list相似,在多维的数组中使用, 进行区分: 在p ...
- Ubuntu日常使用总结
Contents 使用了将近一年的Ubuntu,感觉不用windows也可以处理日常的事务.并且我相信只要合理利用Ubuntu,一定可以取代你手中的Windows.我不是说Ubuntu有多么好,只是从 ...
- redis实现二级缓存
缓存的作用就是降低数据库的使用率,来减轻数据库的负担.我们平常的操作一般都是查>改,所以数据库的有些查操作是重复的,如果一直使用数据库就会有负担.Mybatis也会做缓存,也会有一级缓存和二级缓 ...