반응형
250x250
Notice
Recent Posts
Recent Comments
Link
«   2026/01   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

폴크(FOLC)

치수 계산하기 - robust edge detection 4 본문

카테고리 없음

치수 계산하기 - robust edge detection 4

folcjin 2025. 6. 21. 19:55
728x90
반응형

Total Variation (TV)과 Sparsity 기반의 영상 복원 혹은 영상 복구 알고리즘은 잡음 제거, 압축 센싱 복원, 이미지 인페인팅 등 다양한 영상 처리 분야에서 널리 활용됩니다.

Total Variation (TV) Regularization

TV 정규화는 영상의 급격한 변화(예: 에지)는 유지하면서, 잡음과 같은 고주파 성분을 억제하는 정규화 방법입니다. 주로 isotropic TV 또는 anisotropic TV로 나뉩니다

이는 영상의 gradient의 L1 norm을 최소화하여 결과적으로 평탄한 영역은 부드럽게 만들고, edge는 보존합니다.

 

Sparsity Constraint

Sparsity는 이미지가 특정 basis(예: Wavelet, DCT 등)에서 희소 표현이 가능하다는 가정을 활용합니다. 일반적으로 다음과 같은 형태로 표현됩니다:

 

결합된 모델: TV + Sparsity

이미지 복구 문제를 TV 및 Sparsity로 정식화하면 다음과 같은 최적화 문제가 됩니다:

 

예제

#include <opencv2/opencv.hpp>
#include <iostream>
#include <cmath>

using namespace cv;
using namespace std;

// Parameters
const double lambda_tv = 0.1;
const double lambda_sp = 0.05;
const int maxIter = 100;
const double tau = 0.125;

// Total Variation Gradient Descent Step
void computeTVGradient(const Mat& u, Mat& grad) {
    grad = Mat::zeros(u.size(), CV_64F);
    for (int y = 0; y < u.rows - 1; ++y) {
        for (int x = 0; x < u.cols - 1; ++x) {
            double dx = u.at<double>(y, x+1) - u.at<double>(y, x);
            double dy = u.at<double>(y+1, x) - u.at<double>(y, x);
            double norm = sqrt(dx*dx + dy*dy + 1e-8);
            grad.at<double>(y, x) -= lambda_tv * (dx / norm + dy / norm);
        }
    }
}

// Soft thresholding for sparsity
void softThreshold(Mat& coeffs, double thresh) {
    for (int y = 0; y < coeffs.rows; ++y) {
        for (int x = 0; x < coeffs.cols; ++x) {
            double& val = coeffs.at<double>(y, x);
            val = std::copysign(std::max(std::abs(val) - thresh, 0.0), val);
        }
    }
}

// Main Optimization Loop
Mat tvSparsityDenoise(const Mat& noisy) {
    Mat u = noisy.clone();
    Mat grad, dctCoeffs;

    for (int i = 0; i < maxIter; ++i) {
        // TV gradient
        computeTVGradient(u, grad);

        // Gradient descent step
        u -= tau * grad;

        // Sparsity in DCT domain
        dct(u, dctCoeffs);
        softThreshold(dctCoeffs, lambda_sp);
        idct(dctCoeffs, u);
    }
    return u;
}

int main() {
    Mat input = imread("noisy_image.png", IMREAD_GRAYSCALE);
    if (input.empty()) {
        cout << "Image not found!" << endl;
        return -1;
    }

    input.convertTo(input, CV_64F, 1.0 / 255.0);
    Mat denoised = tvSparsityDenoise(input);
    denoised.convertTo(denoised, CV_8U, 255.0);

    imshow("Original", input);
    imshow("Denoised", denoised);
    waitKey(0);
    return 0;
}

728x90
반응형
사업자 정보 표시
사업자 등록번호 : -- | TEL : --