文章目录

  • 前言
  • 一、理想低通滤波器(ILPF)
  • 二、代码
  • 三、说明

前言

数字图像处理c++ opencv(VS2019 opencv4.53)持续更新


一、理想低通滤波器(ILPF)


通过设置频率半径,半径内的频率大小不变,半径外的频率置为0,即保留了低频区,滤除了高频区,达到滤波的目的。


二、代码

主代码:

#include<iostream>
#include<opencv2/opencv.hpp>
#include "MY_DFT.h"
#include "Salt.h"using namespace cv;
using namespace std;int main()
{ Mat image, image_gray, image_output, image_transform;   //定义输入图像,灰度图像,输出图像image = imread("lena.png");  //读取图像;if (image.empty()){cout << "读取错误" << endl;return -1;}imshow("image", image);cvtColor(image, image_gray, COLOR_BGR2GRAY); //转换为灰度图imshow("image_gray", image_gray); //显示灰度图Salt(image_gray, 1000);imshow("image_gray", image_gray); //显示噪声图//1、傅里叶变换,image_output为可显示的频谱图,image_transform为傅里叶变换的复数结果My_DFT(image_gray, image_output, image_transform);imshow("image_output", image_output);//2、理想低通滤波Mat planes[] = { Mat_<float>(image_output), Mat::zeros(image_output.size(),CV_32F) };split(image_transform, planes);//分离通道,获取实部虚部Mat image_transform_real = planes[0];Mat image_transform_imag = planes[1];int core_x = image_transform_real.rows / 2;//频谱图中心坐标int core_y = image_transform_real.cols / 2;int r = 80;  //滤波半径for (int i = 0; i < image_transform_real.rows; i++){for (int j = 0; j < image_transform_real.cols; j++){//距离中心的距离大于设置半径r的点所在值设为0if (((i- core_x) * (i - core_x) + (j- core_y) * (j - core_y)) > r * r){image_transform_real.at<float>(i, j) = 0;image_transform_imag.at<float>(i, j) = 0;}}}planes[0] = image_transform_real;planes[1] = image_transform_imag;Mat image_transform_ilpf;//定义理想低通滤波矩阵merge(planes, 2, image_transform_ilpf);//3、傅里叶逆变换Mat iDft[] = { Mat_<float>(image_output), Mat::zeros(image_output.size(),CV_32F) };idft(image_transform_ilpf, image_transform_ilpf);//傅立叶逆变换split(image_transform_ilpf, iDft);//分离通道,主要获取0通道magnitude(iDft[0], iDft[1], iDft[0]); //计算复数的幅值,保存在iDft[0]normalize(iDft[0], iDft[0], 0, 1, NORM_MINMAX);//归一化处理imshow("idft", iDft[0]);//显示逆变换图像waitKey(0);  //暂停,保持图像显示,等待按键结束return 0;
}

噪声代码(.h文件):

#pragma once
#include<iostream>
#include<opencv2/opencv.hpp>
#include <random>using namespace cv;
using namespace std;void Salt(Mat image, int n);

噪声代码(.cpp文件):

#include "Salt.h"void Salt(Mat image, int n)
{default_random_engine generater;uniform_int_distribution<int>randomRow(0, image.rows - 1);uniform_int_distribution<int>randomCol(0, image.cols - 1);int i, j;for (int k = 0; k < n; k++){i = randomCol(generater);j = randomRow(generater);if (image.channels() == 1){image.at<uchar>(j, i) = 255;}else if (image.channels() == 3){image.at<Vec3b>(j, i)[0] = 255;image.at<Vec3b>(j, i)[1] = 255;image.at<Vec3b>(j, i)[2] = 255;}}
}

傅里叶变换代码(.h文件):

#pragma once
#include<iostream>
#include<opencv2/opencv.hpp>
#include<cmath>using namespace cv;
using namespace std;void My_DFT(Mat input_image, Mat& output_image, Mat& transform_array);

傅里叶变换代码(.cpp文件):

#include "MY_DFT.h"//傅里叶变换得到频谱图和复数域结果
void My_DFT(Mat input_image, Mat& output_image, Mat& transform_image)
{//1.扩展图像矩阵,为2,3,5的倍数时运算速度快int m = getOptimalDFTSize(input_image.rows);int n = getOptimalDFTSize(input_image.cols);copyMakeBorder(input_image, input_image, 0, m - input_image.rows, 0, n - input_image.cols, BORDER_CONSTANT, Scalar::all(0));//2.创建一个双通道矩阵planes,用来储存复数的实部与虚部Mat planes[] = { Mat_<float>(input_image), Mat::zeros(input_image.size(), CV_32F) };//3.从多个单通道数组中创建一个多通道数组:transform_image。函数Merge将几个数组合并为一个多通道阵列,即输出数组的每个元素将是输入数组元素的级联merge(planes, 2, transform_image);//4.进行傅立叶变换dft(transform_image, transform_image);//5.计算复数的幅值,保存在output_image(频谱图)split(transform_image, planes); // 将双通道分为两个单通道,一个表示实部,一个表示虚部Mat transform_image_real = planes[0];Mat transform_image_imag = planes[1];magnitude(planes[0], planes[1], output_image); //计算复数的幅值,保存在output_image(频谱图)//6.前面得到的频谱图数级过大,不好显示,因此转换output_image += Scalar(1);   // 取对数前将所有的像素都加1,防止log0log(output_image, output_image);   // 取对数normalize(output_image, output_image, 0, 1, NORM_MINMAX); //归一化//7.剪切和重分布幅度图像限output_image = output_image(Rect(0, 0, output_image.cols & -2, output_image.rows & -2));// 重新排列傅里叶图像中的象限,使原点位于图像中心int cx = output_image.cols / 2;int cy = output_image.rows / 2;Mat q0(output_image, Rect(0, 0, cx, cy));   // 左上区域Mat q1(output_image, Rect(cx, 0, cx, cy));  // 右上区域Mat q2(output_image, Rect(0, cy, cx, cy));  // 左下区域Mat q3(output_image, Rect(cx, cy, cx, cy)); // 右下区域//交换象限中心化Mat tmp;q0.copyTo(tmp); q3.copyTo(q0); tmp.copyTo(q3);//左上与右下进行交换q1.copyTo(tmp); q2.copyTo(q1); tmp.copyTo(q2);//右上与左下进行交换Mat q00(transform_image_real, Rect(0, 0, cx, cy));   // 左上区域Mat q01(transform_image_real, Rect(cx, 0, cx, cy));  // 右上区域Mat q02(transform_image_real, Rect(0, cy, cx, cy));  // 左下区域Mat q03(transform_image_real, Rect(cx, cy, cx, cy)); // 右下区域q00.copyTo(tmp); q03.copyTo(q00); tmp.copyTo(q03);//左上与右下进行交换q01.copyTo(tmp); q02.copyTo(q01); tmp.copyTo(q02);//右上与左下进行交换Mat q10(transform_image_imag, Rect(0, 0, cx, cy));   // 左上区域Mat q11(transform_image_imag, Rect(cx, 0, cx, cy));  // 右上区域Mat q12(transform_image_imag, Rect(0, cy, cx, cy));  // 左下区域Mat q13(transform_image_imag, Rect(cx, cy, cx, cy)); // 右下区域q10.copyTo(tmp); q13.copyTo(q10); tmp.copyTo(q13);//左上与右下进行交换q11.copyTo(tmp); q12.copyTo(q11); tmp.copyTo(q12);//右上与左下进行交换planes[0] = transform_image_real;planes[1] = transform_image_imag;merge(planes, 2, transform_image);//将傅里叶变换结果中心化
}

结果:


三、说明

理想低通滤波会导致振铃效应,因此现实很少使用理想低通滤波器,多使用高斯低通滤波或巴特沃斯低通滤波。

c++ opencv数字图像处理:频率域滤波--低通滤波--理想低通滤波相关推荐

  1. 数字图像处理-频率域滤波原理

    from:https://blog.csdn.net/forrest02/article/details/55510711?locationNum=15&fps=1 写在前面的话 作者是一名在 ...

  2. 数字图像处理-频率域滤波

    一.实验原理 频率域滤波是对图像进行傅里叶变换,将图像由图像空间转换到频域空间,然后在频率域中对图像的频谱作分析处理,以改变图像的频率特征,原理是用傅里叶变换表示的函数特征完全可以通过傅里叶反变换来重 ...

  3. 数字图像处理 频率域平滑 MATLAB实验

    一.原理_频率域平滑 理想低通滤波器的传递函数为: n 阶巴特沃斯低通滤波器的传递函数为: n 阶指数低通滤波器的传递函数为: 二.步骤 (1)读入原图像test.tif并显示: (2)对原图像添加高 ...

  4. 数字图像处理 频率域锐化 MATLAB实验

    一.原理_频率域锐化 理想高通滤波器的传递函数为: n 阶巴特沃斯高通滤波器的传递函数为: n 阶指数高通滤波器的传递函数为: 二.步骤 (1)读入原图像test.tif并显示: (2)采用理想高通滤 ...

  5. 图像算法四:【图像增强--频率域】傅里叶变换、快速傅里叶变换、频域滤波、频域低通滤波、频域高通滤波

    频率域滤波与空间域滤波殊途同归,空间域图像增强与频率域图像增强是两种截然不同的技术,实际上在相当程度上说它们是在不同的领域做相同的事情,只是有些滤波更适合在空间域完成,而有些则更适合在频率域中完成. ...

  6. 数字图像处理-空间域处理-灰度变换-基本灰度变换函数(反转变换、对数变换、伽马变换和分段线性变换)

    数字图像处理-空间域处理-灰度变换-基本灰度变换函数(反转变换.对数变换.伽马变换和分段线性变换) 空间域处理是直接对像素进行操作的方法,这是相对于频率域处理而言的.空间域处理主要分为两大类:灰度变换 ...

  7. OpenCV数字图像处理基于C++:灰度变换

    OpenCV数字图像处理基于C++:灰度变换 1.1 灰度变换概念 在图像预处理中,图像的灰度变换是图像增强的重要手段,灰度变换可以使图像对比度扩展,图像清晰,特征明显,灰度变换主要利用点运算来修正像 ...

  8. OpenCV数字图像处理学习平台

    原始图像1-1 处理中的图像1-2 处理结果1-3(检测到所有圆) OpenCV数字图像处理学习平台,是一款可视化.交互式方式学习OpenCV的工具软件,由资深计算机视觉专家精心打造,花费近两年整理成 ...

  9. 《opencv 数字图像处理 图像基础》

    <opencv 数字图像处理 图像基础> 矩阵 通道分离和合并 彩色图像转灰度图像 灰度图转二值化图像 图像运算 矩阵 定义一个显示图像的函数,对于灰度图,里面添加了vmin=0,vmax ...

最新文章

  1. 【mysql错误】用as别名 做where条件,报未知的列 1054 - Unknown column 'name111' in 'field list'...
  2. pandas中set_option的常用设置:显示所有行、显示所有列、控制浮点型精度、每个数据元素的显示字符数、对齐形式等
  3. 报名 | 极简大数据决策,培养数据化思维讲座
  4. 支持全球探测点的新一代网站监控
  5. php图片写入带问号_php实现图片上传时添加文字和图片水印技巧
  6. 3. Qt Creator
  7. Effective Java之在细节消息中包含能捕获失败的消息(六十三)
  8. sendRedirec forward
  9. Python实现蒙特卡罗方法仿真模拟求解圆周率Pi值
  10. Sublime PyV8
  11. 七参数空间直角坐标系坐标转换
  12. C语言四种swap函数
  13. 智能电视或将掀起IT产业新一轮狂潮
  14. 计算机连接网线后无法上网,网线插电脑能上网插路由器不能上网了怎么办?
  15. 计算机二级web知识点,计算机二级WEB考试主要考哪些内容?
  16. STM32无线通信——nRF24L01通信模块
  17. MySql数据库解锁ACT_DE_DATABASECHANGELOGLOCK
  18. 软件架构师:走钢索的人
  19. 域用户桌面图标无法删除的解决办法
  20. C++ [](){}

热门文章

  1. oracle sqlplus显示格式,Oraclesqlplus设置显示格式命令详解
  2. html中加长下滑线,css怎么设置下划线的长度?
  3. 如何获取mysql数据库中字段的注释和类型长度
  4. vue学习记录-05 事件监听
  5. MySQL 多表操作
  6. 多目录Makefile编写
  7. 运行ORB-SLAM2
  8. Python串口编程(转载)
  9. 如何提交一个PR?【OpenHarmony成长计划】【OpenHarmony开源社区】
  10. JavaScriptCore-b