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

OpenCV 影像特效:Kaleidoscope Filter(萬花筒效果)實現

     編輯:關於C++

效果描述

Kaleidoscope Filter 將影像以極座標對稱重複,產生萬花筒般的多重鏡像圖案。核心為極座標轉換配合角度週期性映射。

核心演算法

  1. 設定中心 (centreX, centreY)、半徑 radius、邊數 sides(對稱份數)、旋轉角度 angle。
  2. 對每個輸出像素 (x, y),計算相對中心極座標 (r, θ):r = sqrt(dx²+dy²),θ = atan2(dy, dx)。
  3. 角度週期化映射:temp_theta = fmod(θ, π/sides) * 2(或類似三角波函數),使角度在 [0, 2π/sides) 週期反射。
  4. 計算新極座標 radius_c = radius / cos(temp_theta)(修正徑向距離保持邊界連續)。
  5. 轉回直角座標:new_x = cx + radius_c * cos(θ),new_y = cy + radius_c * sin(θ)。
  6. 雙線性插值採樣。

三角波函數實現角度反射

float Triangle(float x) {
    float temp_r = fmod(x, CV_PI * 0.5f);
    if (temp_r < 0) temp_r += CV_PI * 0.5f;
    if (temp_r > CV_PI * 0.25f) temp_r = CV_PI * 0.5f - temp_r;
    return temp_r;
}

將角度映射為鋸齒波,實現鏡像對稱。

完整 OpenCV C++ 實現

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

float Triangle(float x) {
    float temp_r = fmod(x, CV_PI * 0.5f);
    if (temp_r < 0) temp_r += CV_PI * 0.5f;
    if (temp_r > CV_PI * 0.25f) temp_r = CV_PI * 0.5f - temp_r;
    return temp_r;
}

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());

    int w = src.cols, h = src.rows;
    float cx = w * 0.5f, cy = h * 0.5f;
    float radius = 150.0f;
    float sides = 10.0f;
    float angle = 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 theta = atan2(dy, dx);
            float r = sqrt(dx*dx + dy*dy);

            float temp_theta = Triangle(theta * sides * 0.5f);
            float radius_c = radius / cos(temp_theta);
            float nx = cx + radius_c * cos(theta);
            float ny = cy + radius_c * sin(theta);

            // 邊界處理:超出範圍用邊界值或跳過
            if (nx < 0) nx = 0;
            else if (nx >= w-1) nx = w-2;
            if (ny < 0) ny = 0;
            else if (ny >= h-1) ny = h-2;

            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, "Kaleidoscope");
    waitKey(0);
    return 0;
}

效果展示

Kaleidoscope Filter 效果圖

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