8.6小波变换(Wavelet Transform)边缘检测

实验原理

由于OpenCV本身并不直接支持小波变换(Wavelet Transform),我们需要借助一些技巧来实现它。一种常见的方法是利用离散余弦变换(DCT)或离散傅立叶变换(DFT)来近似实现小波变换的功能。但是,更直接的方法可能是使用离散小波变换(DWT),这通常需要特定的小波基函数。

示例代码1

在这里,我将提供一个简化版本的概念性代码,展示如何使用OpenCV来尝试模拟小波变换以进行边缘检测。请注意,这个示例并不会直接使用OpenCV内置的小波变换功能,而是通过简单的高斯金字塔来模拟小波变换的效果。

首先,确保你的环境中已经安装了OpenCV库。以下是一个基本的例子:

cpp 复制代码
#include "pch.h"
#include <opencv2/opencv.hpp>
#include <iostream>

int main(int argc, char** argv)
{
	// 加载图像
	cv::Mat src = cv::imread("01.jpeg", cv::IMREAD_GRAYSCALE);
	if (src.empty())
	{
		std::cout << "Error: Image not found or unable to open" << std::endl;
		return -1;
	}

	// 创建一个高斯金字塔
	std::vector<cv::Mat> pyramid;
	cv::Mat currentLevel = src.clone();
	for (int level = 0; level < 3; ++level) // 可以根据需要调整层数
	{
		cv::pyrDown(currentLevel, currentLevel);
		pyramid.push_back(currentLevel);
	}

	// 使用高斯金字塔来提取细节层
	cv::Mat reconstructed = pyramid.back();
	for (int level = pyramid.size() - 2; level >= 0; --level)
	{
		cv::pyrUp(pyramid[level + 1], reconstructed, pyramid[level].size());
		cv::Mat detail;
		cv::absdiff(pyramid[level], reconstructed, detail); // 提取细节
		reconstructed = detail;
	}

	// 显示边缘图像
	cv::namedWindow("Original Image", CV_WINDOW_NORMAL);
	cv::imshow("Original Image", src);
	cv::namedWindow("Edge Detection Result", CV_WINDOW_NORMAL);
	cv::imshow("Edge Detection Result", reconstructed);
	cv::waitKey(0);

	return 0;
}

运行结果1

小波变换简介

小波变换是一种时频分析方法,它可以同时提供时间和频率上的分辨率。与傅里叶变换不同,小波变换不仅提供了频率信息,还提供了时间(或空间)上的位置信息。这对于分析非平稳信号特别有用,因为在很多实际应用中,信号的特性随时间变化。

OpenCV中的小波变换

OpenCV提供了一些函数来进行小波变换,主要包括cv::dwt(离散小波变换)cv::idwt(反离散小波变换)。这些函数可以用于多分辨率分析,即在不同的尺度下对图像进行分解和重构。

主要函数

  1. cv::dwt:执行离散小波变换。

  2. cv::idwt:执行反离散小波变换。

在 OpenCV 3.1.0 版本中,cv::dwt 函数并不直接可用,因为该版本及之前的版本中并未包含这个函数。cv::dwt 和 cv::idwt 函数是在 OpenCV 3.2.0 版本之后引入的。

**cv::dwt()**是 OpenCV 库中的一个函数,用于执行离散小波变换(Discrete Wavelet Transform, DWT)。这个变换在图像处理中非常有用,可以用于图像压缩、去噪、特征提取等任务。DWT 可以将信号分解成不同的频率子带,从而提供时间-频率的局部化信息。

函数原型

cpp 复制代码
void dwt(InputArray src, OutputArray dst, 
        int transformType, int level = 1, 
        int wavelet = CV_DWT_HAAR);

参数说明
src: 输入数组(通常是图像),支持多种深度和通道数。
dst: 输出数组,与输入数组具有相同的尺寸和类型。
transformType: 指定变换类型,可以是以下值之一:
CV_DWT_FORWARD: 前向变换。
CV_DWT_INVVERSE: 逆变换。
level: 小波变换的级数,默认为 1。增加级数可以进一步分解低频子带。
wavelet: 使用的小波类型,默认为 CV_DWT_HAAR,目前OpenCV只支持Haar小波。

注意事项
在使用 cv::dwt() 之前,请确保你的图像尺寸是2的幂次方,这样可以避免由于尺寸原因导致的问题。
Haar小波是最简单的一种小波基,它由两个滤波器组成:近似(低通)滤波器和细节(高通)滤波器。
对于多级变换,每增加一级变换,输出图像的尺寸就会减半。

示例代码2

下面是一个简单的示例,演示如何使用 cv::dwt() 进行前向小波变换:

cpp 复制代码
#include <opencv2/opencv.hpp>

int main()
{
    cv::Mat img = cv::imread("path_to_your_image.jpg", cv::IMREAD_GRAYSCALE);
    if (img.empty())
    {
        std::cout << "Error: Image not found." << std::endl;
        return -1;
    }

    // 创建与原图相同大小的输出矩阵
    cv::Mat coeffs;
    // 执行前向离散小波变换
    cv::dwt(img, coeffs, cv::DWT_FORWARD);

    // 显示变换后的图像
    cv::imshow("Original Image", img);
    cv::imshow("Transformed Image", coeffs);
    cv::waitKey(0);

    return 0;
}

总结
cv::dwt() 提供了一个方便的方式来应用离散小波变换。
通过选择不同的变换类型和级别,可以实现对图像数据的多种分析和处理。
如果你需要进行更复杂的小波分析或使用其他类型的小波基,可能需要查看其他的库或自定义实现

**cv::idwt()**是 OpenCV 库中的一个函数,用于执行逆离散小波变换(Inverse Discrete Wavelet Transform, IDWT)。这个函数可以将通过 cv::dwt() 得到的小波系数重构回原始的图像或信号。

函数原型

cpp 复制代码
void idwt(InputArray src, OutputArray dst, 
            int transformType, int level = 1, 
            int wavelet = CV_DWT_HAAR);

参数说明
src: 输入数组(通常是经过离散小波变换后得到的小波系数),支持多种深度和通道数。
dst: 输出数组,与输入数组具有相同的尺寸和类型。
transformType: 指定变换类型,可以是以下值之一:
CV_DWT_FORWARD: 虽然这不是逆变换,但在某些情况下可能被用作参数传递。
CV_DWT_INVERSE: 逆变换。
level: 小波变换的级数,默认为 1。这个参数应该与 cv::dwt() 中使用的相同。
wavelet: 使用的小波类型,默认为 CV_DWT_HAAR,目前OpenCV只支持Haar小波。

注意事项
在使用 cv::idwt() 之前,确保你的输入系数数组符合之前进行的 cv::dwt() 变换的结构。
对于多级变换,你需要按照相同的级数进行逆变换。
通常,逆变换的结果会尽可能接近原始图像,但由于量化和其他误差,可能会有一些微小的差异。

示例代码3

下面是一个简单的示例,演示如何使用 cv::dwt() 和 cv::idwt() 进行前向小波变换和逆变换:

cpp 复制代码
#include <opencv2/opencv.hpp>

int main()
{
    cv::Mat img = cv::imread("path_to_your_image.jpg", cv::IMREAD_GRAYSCALE);
    if (img.empty())
    {
        std::cout << "Error: Image not found." << std::endl;
        return -1;
    }

    // 创建与原图相同大小的输出矩阵
    cv::Mat coeffs, reconstructed;
    // 执行前向离散小波变换
    cv::dwt(img, coeffs, cv::DWT_FORWARD, 2);  // 假设使用两级变换

    // 执行逆离散小波变换
    cv::idwt(coeffs, reconstructed, cv::DWT_INVERSE, 2);  // 使用相同的级数

    // 显示原始图像和重构图像
    cv::imshow("Original Image", img);
    cv::imshow("Reconstructed Image", reconstructed);
    cv::waitKey(0);

    return 0;
}

总结
cv::idwt() 函数允许你在 OpenCV 中执行逆离散小波变换,
从而能够从小波系数中恢复出原始的图像或信号。
确保你使用正确的变换级别和类型来匹配之前进行的正向变换。
如果你在使用过程中遇到任何问题,确保你的 OpenCV 版本至少是 3.2.0,因为在更早的版本中可能不包含这些函数。
相关推荐
云空9 分钟前
《QT 5.14.1 搭建 opencv 环境全攻略》
开发语言·qt·opencv
编码小哥11 分钟前
opencv中的色彩空间
opencv·计算机视觉
吃个糖糖16 分钟前
34 Opencv 自定义角点检测
人工智能·opencv·计算机视觉
花花少年18 分钟前
【Windows版】opencv 和opencv_contrib配置
opencv·opencv_contrib
YRr YRr18 分钟前
解决Ubuntu 20.04上编译OpenCV 3.2时遇到的stdlib.h缺失错误
linux·opencv·ubuntu
葡萄爱3 小时前
OpenCV图像分割
人工智能·opencv·计算机视觉
编码小哥5 小时前
通过opencv加载、保存视频
人工智能·opencv
发呆小天才O.oᯅ5 小时前
YOLOv8目标检测——详细记录使用OpenCV的DNN模块进行推理部署C++实现
c++·图像处理·人工智能·opencv·yolo·目标检测·dnn
西猫雷婶5 小时前
python学opencv|读取图像(十六)修改HSV图像HSV值
开发语言·python·opencv
pchmi5 小时前
C# OpenCV机器视觉:模板匹配
opencv·c#·机器视觉