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

OpenCV 實戰:Haar 小波變換(一維與二維)完整代碼

     編輯:關於C++

一維 Haar 小波原理

對信號 [2,4,6,8,10,12,14,16]:

  1. 求相鄰均值 → [3,7,11,15](低頻/整體信息)。
  2. 求相鄰差值 → [-1,-1,-1,-1](高頻/細節信息)。
  3. 重複對低頻部分分解,得到多級分解。

二維 Haar 小波(圖像)

先對每行做一維變換,再對結果的每列做一維變換。一次分解產生四個子帶:
LL(低頻近似)、LH(水平細節)、HL(垂直細節)、HH(對角細節)。

C++ 完整實現 (OpenCV)

#include 
#include 
using namespace cv;
using namespace std;

int main() {
    Mat img = imread("lenna.bmp", 0); // 灰度讀取
    int levels = 3; // 分解層數
    Mat tmp, wavelet;
    Mat src = img.clone();
    src.convertTo(src, CV_32F);

    for (int lv = 1; lv <= levels; ++lv) {
        int h = src.rows / lv;
        int w = src.cols / lv;
        tmp = Mat::zeros(h, w, CV_32F);
        // 行變換
        for (int i = 0; i < h; ++i) {
            for (int j = 0; j < w/2; ++j) {
                float a = src.at(i, 2*j);
                float b = src.at(i, 2*j+1);
                tmp.at(i, j) = (a + b) * 0.5f;       // 低頻
                tmp.at(i, j + w/2) = (a - b) * 0.5f; // 高頻
            }
        }
        // 列變換
        wavelet = Mat::zeros(h, w, CV_32F);
        for (int i = 0; i < h/2; ++i) {
            for (int j = 0; j < w; ++j) {
                float a = tmp.at(2*i, j);
                float b = tmp.at(2*i+1, j);
                wavelet.at(i, j) = (a + b) * 0.5f;
                wavelet.at(i + h/2, j) = (a - b) * 0.5f;
            }
        }
        src = wavelet; // 下一層處理
    }

    // 顯示結果(增強對比度)
    wavelet.convertTo(wavelet, CV_8U);
    wavelet += 50;
    imshow("Haar Wavelet", wavelet);
    waitKey(0);
    return 0;
}

結果展示

二維 Haar 分解示意

原圖 分解結果 細節子帶 重構示意

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