OpenCV学习——图像二值化处理及二维傅里叶变换

article/2025/10/3 2:15:02

小古在本学期选修了《计算机视觉原理与应用》,最近有一份作业 —— 利用matlab或者OpenCV对图像进行一些处理,由于完全没有接触过matlab和OpenCV,但是学习了一些python语言,所以便利用opencv-python来完成作业。

1 图像二值化处理

1.1 图像二值化算法

        图像二值化就是将灰度化图像像素值设置为0和255,使得图像中的每个像素只能是黑或者是白,没有中间的过渡,是图像分割的一种简单方法。图像二值化通过设定一个阈值,对图像中像素值小于阈值的设置为0,超过像素值的设置为255,从而将整个图像处理为黑白二值效果。图像二值化处理是为了更好地做图像处理判别。图像二值化算法分为全局固定阈值和局部动态阈值即自适应阈值。

        全局阈值二值化对整个图像采用单一的阈值,将图像中每个像素灰度值与阈值进行比较,再依据比较结果将其分为背景或目标对象。典型的全局阈值方法包括迭代算法、OTSU方法、灰度期望值算法等,全局阈值法算法简单, 对于目标和背景明显分离、直方图分布呈双峰的图像效果良好,但其对输入图像有噪声或不均匀光照等情况抵抗能力差,应用受到极大限制。

        局部阈值二值化是按照一定规则将数字图像分块划为N个子图像,并为每个子图像确定相应的阈值(T值不同),即对指定区域构造灰度直方图。根据像素的邻域块的像素值分布来确定该像素位置上的二值化阈值。这样做的好处在于每个像素位置处的二值化阈值不是固定不变的,而是由其周围邻域像素的分布来决定的。亮度较高的图像区域的二值化阈值通常会较高,而亮度较低的图像区域的二值化阈值则会相适应地变小。不同亮度、对比度、纹理的局部图像区域将会拥有相对应的局部二值化阈值。非均匀光照条件或噪声存在等情况虽然影响整体图像的灰度分布却不影响局部的图像性质, 使得局部阈值法较全局阈值法有更广泛的应用。常用的局部阈值法有Bernsen算法、Niblack算法等。常用的局部自适应阈值有:1)局部邻域块的均值;2)局部邻域块的高斯加权和。

        这里使用了全局阈值与局部阈值算法。采用全局阈值算法时,利用了OTSU方法处理,OTSU即大津法又名最大类间方法,此方法通过统计整个图像的直方图特性来实现全局阈值的自动选取。使用方法cv2.threshold(src, thresh, maxval, type),有两个返回值,阈值和阈值处理后的图像。

其中 src:表示的是图片源。

        thresh:表示的是阈值(分割值)。

        maxval:表示的是最大值。

        type:表示的是这里划分的时候使用的是什么类型的算法,包含以下几种

各个阈值类型图示如下:

 

        采用局部阈值算法时,通过计算某个邻域(局部)的均值、中值、高斯加权平均(高斯滤波)来确定阈值,此处采用高斯法。使用方法adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None)

其中 src:表示输入图像(8位单通道图像)。

        maxValue:表示使用 THRESH_BINARY 和 THRESH_BINARY_INV 的最大值.

        adaptiveMethod:表示自适应阈值算法,平均 (ADAPTIVE_THRESH_MEAN_C)或高斯(ADAPTIVE_THRESH_GAUSSIAN_C)。

        thresholdType:表示阈值类型,必须为THRESH_BINARY或THRESH_BINARY_INV的阈值类型。

        blockSize:表示块大小(奇数且大于1,比如3,5,7........ )。

        C:常数,表示从平均值或加权平均值中减去的数。 通常情况下,这是正值,但也可能为零或负值。

        dst:输出图像,可以忽略。

1.2 在Pycharm IDE 利用opencv-python进行图像二值化实现

import cv2def binarization_whole(img):""" 图像全局阈值二值化处理 """# 将图像转为灰度图gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)cv2.imwrite('img/gray.png', gray)# 最大类间方差法(大津算法),thresh会被忽略,参数0可改为任意数字但不起作用,自动计算一个阈值ret, dst = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)print("threshold value %s" % ret)  # 打印选取的阈值# # 创建窗口# cv2.namedWindow("binarization_whole", 0)cv2.imshow("binarization_whole", dst)  # imshow()函数有两个参数:显示图像的帧名称、要显示的图像本身。# 储存图像cv2.imwrite('img/1.png', dst)def binarization_part(img):""" 图像局部阈值二值化处理 """# 将图像转为灰度图gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 图像二值化dst = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 145, 3)cv2.imshow("binarization_part", dst)# 储存图像cv2.imwrite('img/2.png', dst)img = cv2.imread("2.jpg")
binarization_whole(img)
binarization_part(img)cv2.waitKey(0)  # 进程不结束则会一直保持显示状态
cv2.destroyAllWindows()  # 调用 destroyWindows()函数可以释放由 OpenCV创建的所有窗口。

效果图如下:

原图:

二值化处理前的灰度图:

 处理后二值图像

全局阈值二值化处理:

 

 局部阈值二值化处理:

 1.3比较不同阈值下二值化处理后图像的变化

        全局阈值二值化处理时,灰度图、整个图像的直方图特性、设定二值化类型THRESH_BINARY和OSTU’s二值化图(这是一个更加适合于图像灰度直方图具有双峰的情况,他会在双峰之间找到一个值作为阈值)如下:

         

        根据程序运行结果可得到设定二值化类型THRESH_BINARY和OTSU’s二值化法的阈值分别为127和105,由此也产生了不同的效果,很明显,阈值为105时的二值化图更加清楚地展现了房屋的结构和轮廓。阈值为127时,由于阈值高于最佳阈值105而使得图像整体较暗,导致不如阈值为105时的效果图清晰。

        局部阈值二值化处理时,使用方法adaptiveThreshold( )根据各像素点邻域内像素点加权得到各点邻域阈值,然后在各个子图像内进行二值化处理,这样做的好处很明显,与全局阈值处理相比,房屋的房檐和窗户轮廓更加明显清晰。(左图为全局阈值化,右图为局部阈值化)

  为了更加明显,下面展示在不同阈值下的全局阈值二值化处理效果图:

 

   

随着阈值由0开始增加,在阈值为120时图像中橙子轮廓开始凸显,在阈值为180左右时效果最佳,在阈值为220时虽仍有轮廓但已几乎无法辨认出图像中元素,阈值继续增加,阈值为250时已完全无法辨认图像中元素。

测试代码:

import cv2def threshold(thresh):img = cv2.imread("4.jpg")gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)cv2.imwrite('img/gray_orange.png', gray)ret, dst = cv2.threshold(gray, thresh, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)print("threshold value %s" % ret)  # 打印选取的阈值cv2.imshow("threshold", dst)  # imshow()函数有两个参数:显示图像的帧名称、要显示的图像本身。# 储存图像cv2.imwrite('img/orange.png', dst)threshold(50)  # 参数为阈值
cv2.waitKey(0)  # 进程不结束则会一直保持显示状态
cv2.destroyAllWindows()  # 调用 destroyWindows()函数可以释放由 OpenCV创建的所有窗口。

 用OTSU方法验证一下:

    ret, dst = cv2.threshold(gray, thresh, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

 通过运行打印最佳阈值:

效果图:

与阈值为180时的图像相近,所以与上述结论是一致的。

2 二维傅里叶变换

2.1 二维傅里叶变换原理

        傅里叶变换实际上是将信号f(t)与一组不同频率的复正弦做内积,这一组复正弦是变换的基向量,傅里叶系数或傅里叶变换是f(t)在这一组基向量上的投影。傅里叶变换是一种分析信号的方法,它可分析信号的成分,也可用这些成分合成信号,是线性系统分析的一个有力工具,它能够定量地分析诸如数字图像之类的数字化系统,把傅里叶变换的理论与物理解释相结合,将有利于解决大多数图像处理问题,傅里叶变换在图像处理中的应用十分广泛,如图像特征提取、频率域滤波、图像复原、纹理分析等。傅里叶变换主要分为连续傅立叶变换和离散傅立叶变换。

        傅里叶变换的原理是将一个信号分离为无穷多多正弦/复指数信号的加成,即把信号变成正弦信号相加的形式——既然是无穷多个信号相加,那对于非周期信号来说,每个信号的加权应该都是零,但有密度上的差别,因为落到每一个点的概率都是无限小,但这些无限小是有差别的,所以傅里叶变换之后,横坐标即为分离出的正弦信号的频率,纵坐标对应的是加权密度。

        灰度图像是由二维的离散的点构成的,二维离散傅里叶变换常用于图像处理中,对图像进行傅里叶变换后得到其频谱图。频谱图中频率高低表征图像中灰度变化的剧烈程度。图像中边缘和噪声往往是高频信号,而图像背景往往是低频信号。我们在频率域内可以很方便地对图像的高频或低频信息进行操作,完成图像去噪,图像增强,图像边缘提取等操作,因此,对图像进行傅里叶变换的原理如下公式:

 其中u和v是频率变量,X和y是空间或图像变量。 

2.2 图像二维傅里叶变换实现

        利用OpenCV库函数实现傅里叶变换,OpenCV 中进行二维傅里叶变换的函数是

cv2.dft(src, dst=None, flags=None, nonzeroRows=None)

输出的结果是双通道的,第一个通道是结果的实数部分,第二个通道是结果的虚数部分,输入图像src要首先转换成 np.float32 格式。

dst表示输出图像,包括输出大小和尺寸。

nonzeroRows表示当参数不为零时,函数假定只有nonzeroRows输入矩阵的第一行(未设置)或者只有输出矩阵的第一个(设置)包含非零,因此函数可以处理其余的行更有效率,可以节省一些时间。

flags为转换标识,flags= cv2.DFT_COMPLEX_OUTPUT,输出一个复数矩阵,则需要调用cv2.magnitude()函数将傅里叶变换的双通道结果转换为0到255的范围: 

  返回值 = cv2.magnitude(x, y)

x: 浮点型X坐标值,即实部

y: 浮点型Y坐标值,即虚部

经过cv2.magnitude()函数处理后得到的结果为

 

代码:

# OpenCV傅里叶库函数实现图像变换
import cv2
import numpy as np
import matplotlib.pyplot as plt# 读取图像且读为灰度图
img = cv2.imread("4.jpg", 0)
# 使用OpneCV傅里叶变换函数对图像进行傅里叶变换
f_img = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
# 默认结果中心点位置是在左上角,将频谱低频从左上角移动至中心位置
dft_shift = np.fft.fftshift(f_img)
# 将频谱图双通道复数转换为(0,255)区间
dft_img = 20 * np.log(cv2.magnitude(f_img[:, :, 0], f_img[:, :, 1]))
dft_shift_img = 20 * np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))# 图像显示
plt.rcParams['font.sans-serif'] = ['SimHei']  # 显示中文
plt.subplot(131), plt.imshow(img, 'gray'), plt.title('原图像')
plt.axis('off')
plt.subplot(132), plt.imshow(dft_img, 'gray'), plt.title('二维傅里叶频谱图')
plt.axis('off')
plt.subplot(133), plt.imshow(dft_shift_img, 'gray'), plt.title('二维傅里叶中心化频谱图')
plt.axis('off')
plt.show()

 图像处理效果图:

通过这次作业,小古也对OpenCV有了浓厚的兴趣,以后会继续学习利用OpenCV进行图像处理的技能。

图片来源:
避暑山庄 · 如意州岛 —— 一片云 - 承德 - PhotoFans摄影网

橙子 —— 百度图片


http://chatgpt.dhexx.cn/article/8VvQd9K9.shtml

相关文章

二维傅里叶变换是怎么进行的?

1.首先回顾一下一维FT 通俗来讲,一维傅里叶变换是将一个一维的信号分解成若干个三角波。 对于一个三角波而言,需要三个参数来确定它:频率,幅度 A ,相位。因此在频域中,一维坐标代表频率,而每个坐标对应的…

二维傅里叶变换需知

from: https://blog.csdn.net/wenhao_ir/article/details/51037744 代码如下,这个代码是实现灰度图像作二维傅里叶变换后的非线性变换哈~ clear all; Iimread(coins.png); Ffft2((im2double(I))); Ffftshift(F); Fabs(F); Tlog(F1); subplot(1,2,1); imshow(F,[]…

傅里叶级数、一维傅里叶变换到二维傅里叶变换数理推导

傅里叶级数、一维傅里叶变换到二维傅里叶变换数理推导 参考资料: 如何理解傅里叶级数公式 二重傅里叶级数 从傅里叶级数到傅里叶变换 高维傅里叶变换的推导 连续傅里叶变换和离散傅里叶变换 二维离散傅里叶变换 IDL实现傅里叶变换 想要用傅里叶变换的思维处理一个…

二维傅里叶变换简化方式

在处理二维矩阵时,常想着如何把时域转换到频域来处理,因此翻来了以往数分里面的常用的傅里叶(Fourier Transform); (Notes:一下公式中 M,N分别为二维矩阵的列数和行数,f(x,y) 代表改二维矩阵,F(u,v)为转换后的矩阵&…

C++中fftw库二维傅里叶变换笔记

目录 1.相关基础知识参考链接 2.二维傅里叶变换作用简介 3.FFTW二维傅里叶变换输出分析 (1)原始输出数据​ (2)频谱中心化后的输出数据 4.频谱图绘制 5.二维傅里叶变换逆变换 6.从输出结果中分离各平面波并画出波形平面图…

二维傅里叶变换的理解和使用

目录 似模似样的前言一维傅里叶二维傅里叶 似模似样的前言 最近的瑕疵检测项目需要在有纹理的产品上做很细致的检测。由于当前做项目使用的还是halcon居多,目前知道的方法还是傅里叶变换比较靠谱。 但仅靠halcon自带的样例并不能很好的理解和使用傅里叶&#xff0…

二维傅里叶变换频谱图的直观理解

众所周知:频谱中心代表低频,四周代表高频。 问:那(u,v)一点代表什么? 答: 1.当为水平方向的正弦图片时,二维傅里叶变换后,其只有u方向的频谱值; 2…

Matlab:二维傅里叶变换

Matlab:二维傅里叶变换 二维傅里叶变换二维衍射模式fft2 函数将二维数据变换为频率空间。例如,您可以变换二维光学掩膜以揭示其衍射模式。 二维傅里叶变换 以下公式定义 mn 矩阵 X 的离散傅里叶变换 Y。 i 是虚数单位,p 和 j 是值范围从 0 到 m–1 的索引,q 和 k 是值范围…

matlab二维傅里叶变换ffshift,形象理解二维傅里叶变换

点击上方“机器学习与生成对抗网络”,关注"星标" 获取有趣、好玩的前沿干货! 来自 | 知乎 阿姆斯特朗 链接 | https://zhuanlan.zhihu.com/p/110026009 文仅交流,侵删 1.回顾一下一维FT 公式: 通俗来讲,一维傅里叶变换是将一个一维的信号分解成若干个复指数波 …

傅里叶变换(二维离散傅里叶变换)

离散二维傅里叶变换 一常用性质: 可分离性、周期性和共轭对称性、平移性、旋转性质、卷积与相关定理; (1)可分离性: 二维离散傅里叶变换DFT可分离性的基本思想是DFT可分离为两次一维DFT。因此可以用通过计算两次一维…

二维傅里叶变换

fft2 函数将二维数据变换为频率空间。例如,可以变换二维光学掩膜以揭示其衍射模式。 二维傅里叶变换 以下公式定义 mn 矩阵 X 的离散傅里叶变换 Y。 和 是以下方程所定义的复单位根。 i 是虚数单位,p 和 j 是值范围从 0 到 m–1 的索引,q …

【深度好文】二维图像傅里叶变换 YYDS

1. 傅里叶变换原理 在数学中进行傅里叶变换为连续模拟信号,通常来说: 二维连续函数f(x,y)的傅里叶正变换为: 相应的傅里叶逆变换公式为: 但是在计算机领域,计算机一般处理的是数字信号,只能进行有限次计…

微信公众号开发模式没有域名怎么办?申请免费域名

微信公众号开发采用前后端分离模式,那么前端使用微信开发工具开发时,需要域名才能访问,那么域名从何而来呢? 1、申请域名 a)、NetApp申请免费域名 : https://natapp.cn/login b)、域名申请好以后,下载客户端&#xf…

freenom 申请免费域名

为了降低建站成本,可在freenom上申请免费域名,可以免费使用一年。 一. 注册域名 登录freenom.com,输入域名,检测通过后,输入邮箱,登录邮箱完成激活。 二. 配置DNS 上面申请的域名未绑定外网ip&#xff0c…

如何注册一个免费的网站空间和域名

https://www.jianshu.com/p/016c83f70d43 前几天想搞个网站玩玩,于是就上网搜哪里可以注册免费的网站空间和域名,折腾了好几天都没注册成,国内好像已经没有免费的了。只好用英文去搜国外的网站,才找到了一个能注册成功的&#xff…

Freenom免费域名申请

Freenom免费域名申请 准备条件操作流程注意选择域名确定并提交订单方法一(谷歌,FaceBook)方法二(开发者邮箱注册) 注册谷歌,Facebook 注册 防订单失败操作 准备条件 必须拥有一个 谷歌账号 或 Facebook 账号 亦或者 拥有一个 未注册Freenom的邮箱 登录 …

【免费域名】教你免费申请顶级域名

一、输入网址 :https://my.freenom.com/ 二、点击Service->Register a New Domain,注意这里有网络延时至少30秒 三、输入自己想要的域名,点击Check Avaliability,比如我的是abc5500,延时10秒 四、Get it now! ->…

免费域名证书最新申请方式大全

目前市场环境下,可获得域名SSL证书的方式有很多,一般有付费和免费划分。对于想免费使用域名SSL证书的朋友,这里收集整理了几个常用的SSL证书申请方式。 对于SSL证书的用处,简单的来说,就是加密数据传输,使…

免费域名申请及免费DNS解析

一:免费域名申请 1:freenom免费域名申请(有效期12个月) 我是通过科学上网才申请成功。普通方式申请容易出现各种问题不成功。因为freenom网站要连接国外各种服务器检测域名的可用性。 如下图申请成功的域名: 域名再DNS…

freenom域名申请教程

freenom域名申请教程 1. 注册&申请域名 打开freenom官网,注册一个账户【注意:如果没有明显的注册按钮,可以通过如下方式同时申请域名和注册账户】 打开域名申请【不用注册】 选择好了域名之后,点击Checkout;选择…