PhotoShop算法实现高级篇--挤压特效(三十六)
在Apple本本自带的摄像头里有挤压的功能,带小侄子玩的时候乐得嘴都合不拢。其实挤压效果的时候先是将图像向内挤压,挤压的过程产生压缩变形,从而形成的效果。挤压效果的实现是通过数学极坐标的形式,将当前像素、图像中心店和过中心点的水平线这三要素画出的一个极坐标,然后根据指定的挤压度,在当前点与中心点所连的直线上映射出一个像素点,此像素点即为目标像素点。
先上一张图,美女(效果似曾相似不?):
算法实现比较简单,如下:
// degree:挤压幅度(1-32)
void PhotoShop::Pinch(Mat& img, Mat& dst, int degree)
{
if (degree<1 ) degree = 1;
if ( degree> 32) degree = 32;
if ( dst.empty())
dst.create(img.rows, img.cols, img.type());
dst = cv::Scalar::all(0);
int chns = img.channels();
int height = img.rows;
int width = img.cols;
int midX = width/2;
int midY =height/2;
int i, j, k;
int X, Y, offsetX, offsetY;
double radian, radius; //弧和半径
for ( i=0; i<height; i++)
{
for ( j=0; 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<0 ) X = 0;
if ( X>= width) X = width - 1;
if ( Y<0 ) Y = 0;
if ( Y>=height) Y = height -1;
for ( k=0; k<chns; k++)
{
setPixel(dst, i,j, k, getPixel(img, Y, X, k));
}
}
}
}
再来一张凤姐的老公:
再来个丑的(看你还跟鬼子混不):
哈哈,喜庆哈,丑你没商量。
凶器没了~?~