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,因为在更早的版本中可能不包含这些函数。
相关推荐
jndingxin12 分钟前
OpenCV结构分析与形状描述符(18)比较两个轮廓相似度的函数matchShapes()的使用
人工智能·opencv·计算机视觉
杨~friendship6 小时前
Ubuntu上使用qt和opencv显示图像
linux·开发语言·c++·qt·opencv·ubuntu
jndingxin7 小时前
OpenCV结构分析与形状描述符(19)查找二维点集的最小面积外接旋转矩形函数minAreaRect()的使用
人工智能·opencv·计算机视觉
jndingxin21 小时前
OpenCV运动分析和目标跟踪(1)累积操作函数accumulate()的使用
人工智能·opencv·目标跟踪
一只小小程序猿1 天前
Python计算机视觉编程 第三章 图像到图像的映射
python·opencv·计算机视觉
白茶等风121381 天前
OpenCV_图像旋转超详细讲解
人工智能·opencv·计算机视觉
MYVision_ MY视界2 天前
OpenCV 4.10 windows 上编译并上传conan
人工智能·opencv·计算机视觉
嵌入(师)2 天前
opencv anaconda yolov5安装流程
人工智能·opencv·yolo
mirror_zAI2 天前
[OpenCV] 数字图像处理 C++ 学习——15像素重映射(cv::remap) 附完整代码
c++·图像处理·opencv·计算机视觉
菜就多练_08282 天前
《深度学习》OpenCV 高阶 图像金字塔 用法解析及案例实现
人工智能·深度学习·opencv