漩渦濾鏡將圖像以中心為原點,根據極坐標角度進行非線性扭曲,產生旋渦狀視覺效果。

Img_out,尺寸與輸入一致。(x, y),計算其相對中心 (cx, cy) 的極坐標:x0 = x - cx, y0 = cy - yDis = x0² + y0², radius = √Dis, theta = atan2(y0, x0)N=70,修正角度:theta += radius / N(或類似非線性變換)(new_x, new_y):new_x = radius * cos(theta) + cxnew_y = cy - radius * sin(theta)#define pi 3.1415926
int main() {
Mat Img = imread("4.jpg");
Mat Img_out(Img.size(), CV_8UC3);
int width = Img.cols, height = Img.rows;
Point Center(width/2, height/2);
float N = 70.0f;
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
float x0 = x - Center.x;
float y0 = Center.y - y;
float Dis = x0*x0 + y0*y0;
float radius = sqrt(Dis);
float theta = atan2(y0, x0 + 1e-5); // 避免除零
// 核心扭曲公式
theta += radius / N;
float new_x = radius * cos(theta) + Center.x;
float new_y = Center.y - radius * sin(theta);
// 邊界保護
if (new_x < 0) new_x = 0;
if (new_x >= width-1) new_x = width-2;
if (new_y < 0) new_y = 0;
if (new_y >= height-1) new_y = height-2;
// 雙線性插值
int x1 = (int)new_x, y1 = (int)new_y;
float p = new_x - x1, q = new_y - y1;
for (int k = 0; k < 3; ++k) {
Img_out.at<Vec3b>(y, x)[k] =
(1-p)*(1-q)*Img.at<Vec3b>(y1, x1)[k] +
p*(1-q)*Img.at<Vec3b>(y1, x1+1)[k] +
(1-p)*q*Img.at<Vec3b>(y1+1, x1)[k] +
p*q*Img.at<Vec3b>(y1+1, x1+1)[k];
}
}
}
imshow("out", Img_out);
imwrite("Out.jpg", Img_out);
waitKey();
return 0;
}