挤压效果
挤压效果是将图像向内挤压,产生收缩变形。
挤压效果的实现可以看成是数学极坐标的一种体现,将当前像素点、图像正中心点和过中心点的水平线这三要素画出一个极坐标,然后根据用户指定的挤压度,在当前点与中心点所连的直线上映射出一个像素点,最后将这个像素点作为目标点输出。设原图像上的点坐标用(x’,y’)表示,挤压效果图上的点坐标用(x,y)表示,图像正中心点坐标为(midx,midy),ρ和θ表示点(x,y)所在极坐标系对应的极值和极角,degree为挤压度,取值为[1,32],那么挤压效果满足的关系如下式所示:
其中,
//模板
Mat Extrusion(Mat& src,int degree) {
assert(degree>=1&°ree<=32);
Mat output(src.size(), CV_8UC3);
int width = output.cols;
int heigh = output.rows;
Point center(width / 2, heigh / 2);
for (int y = 0; y < heigh; y++)
{
uchar* img_p = output.ptr<uchar>(y);
for (int x = 0; x < width; x++)
{
Point offset(x - center.x, y - center.y);
double theta = atan2((double)offset.y, (double)offset.x);
double rou = sqrt(pow((double)offset.x, 2) + pow((double)offset.y, 2));
//具体计算方式根据不同的效果进行修改既可
int newX = center.x + int(degree * sqrt(rou) * cos(theta));
int newY = center.y + int(degree * sqrt(rou) * sin(theta));
if (newX < 0)
newX = 0;
else if (newX >= width)
newX = width - 1;
if (newY < 0)
newY = 0;
else if (newY >= heigh)
newY = heigh - 1;
img_p[3 * x] = src.at<uchar>(newY, newX * 3);
img_p[3 * x + 1] = src.at<uchar>(newY, newX * 3 + 1);
img_p[3 * x + 2] = src.at<uchar>(newY, newX * 3 + 2);
}
}
return output;
}