首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

OpenCV 影像特效:Water Wave Filter(水波紋擾動效果)實現

     編輯:關於C++

效果描述

Water Wave Filter 模擬水面波紋對影像的折射擾動。以同心圓波傳播模型,像素沿徑向位移,位移量隨距離呈正弦波動,形成動態水波視覺效果。

核心演算法

  1. 設定波長 wavelength、振幅 amplitude、相位 phase、中心 (centreX, centreY)、影響半徑 radius。
  2. 對每個輸出像素 (x, y),計算相對中心距離 distance。
  3. 若 distance > radius,保持原位。
  4. 否則計算徑向位移量:
    amount = amplitude * sin(distance / wavelength * 2π - phase) 基礎正弦波。
    amount *= (radius - distance) / radius 邊緣衰減包絡。
    amount *= wavelength / (distance + ε) 能量守恆修正(可選)。
  5. 位移向量:new_x = x + dx * amount,new_y = y + dy * amount(沿徑向位移)。
  6. 雙線性插值採樣。

完整 OpenCV C++ 實現

#include <opencv2/opencv.hpp>
#include <cmath>
#include <algorithm>
using namespace cv;
using namespace std;

void showImage(const Mat& img, const string& name) {
    namedWindow(name, WINDOW_AUTOSIZE);
    imshow(name, img);
}

int main() {
    Mat src = imread("4.jpg");
    if (src.empty()) return -1;
    Mat dst(src.size(), src.type());
    src.copyTo(dst);

    int w = src.cols, h = src.rows;
    float cx = w * 0.25f, cy = h * 0.5f;
    float radius = 0.0f;
    if (radius == 0) radius = min(w, h) * 0.5f;
    float radius2 = radius * radius;

    int wavelength = 20;
    int amplitude = 30;
    float phase = CV_PI / 4;

    for (int y = 0; y < h; ++y) {
        for (int x = 0; x < w; ++x) {
            float dx = x - cx, dy = y - cy;
            float dist2 = dx*dx + dy*dy;
            float nx = x, ny = y;

            if (dist2 < radius2 && dist2 > 0) {
                float distance = sqrt(dist2);
                float amount = amplitude * sin(distance / wavelength * 2*CV_PI - phase);
                amount *= (radius - distance) / radius;      // 邊緣衰減
                amount *= wavelength / (distance + 1e-4f);   // 能量修正
                nx = x + dx * amount;
                ny = y + dy * amount;
            }
            // 邊界裁剪
            nx = max(0.0f, min(nx, w - 2.0f));
            ny = max(0.0f, min(ny, h - 2.0f));
            int x1 = (int)nx, y1 = (int)ny;
            float px = nx - x1, py = ny - y1;

            for (int k = 0; k < 3; ++k) {
                dst.at<Vec3b>(y, x)[k] = saturate_cast<uchar>(
                    (1-px)*(1-py)*src.at<Vec3b>(y1, x1)[k] +
                    px*(1-py)*src.at<Vec3b>(y1, x1+1)[k] +
                    (1-px)*py*src.at<Vec3b>(y1+1, x1)[k] +
                    px*py*src.at<Vec3b>(y1+1, x1+1)[k]
                );
            }
        }
    }
    showImage(dst, "Water Wave");
    waitKey(0);
    return 0;
}

動態動畫擴展

將 phase 隨時間線性遞增(phase += speed * dt),在迴圈中重複渲染即可產生動態水波動畫。配合 VideoWriter 可輸出影片。

參數效果對照

參數增加效果減少效果
wavelength波紋間距變大、波數減少波紋密集、高頻擾動
amplitude位移幅度大、扭曲強烈微弱擾動、近似原圖
phase波紋向外傳播(動畫)波紋向內收斂
radius影響範圍擴大局部水波效果

效果展示

Water Wave Filter 效果圖

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved