Opencv-Python学习(五)

一、傅里叶变换

        傅里叶变换的详细过程及推导可以看一个大佬写的,我这里就不介绍了,链接:傅里叶分析之掐死教程(完整版)更新于2014.06.06 - 知乎

         我这里就介绍一下傅里叶变换的一些概念和opencv中如何实现傅里叶变换:

        低频:变化缓慢的灰度分量,非边界

        高频:变化剧烈的灰度分量,如边界

        低通滤波器:只保留低频,效果:会使图片模糊

        高通滤波器:只保留高频,效果:会增强图片细节

(1)傅里叶变换

          在opencv中提供了傅里叶变换函数,cv2.dft()和逆变换函数cv2.idft(),在官方文档中要求输入的图片为np.float32格式

        图像经过傅里叶变换后频率为0会在左上角,通常会经过变换,将频率为0变换到中心位置,可以使用shift变换来实现

        使用函数cv2.dft()进行傅里叶变换返回的是双通道(实部,虚部),需要转换为图片格式(0,255)才能显示

代码实现:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt


cat = cv.imread('../de/cat.jpg', 0)
cat_32 = np.float32(cat)

cat_dft = cv.dft(cat_32, flags=cv.DFT_COMPLEX_OUTPUT)  # 进行傅里叶变换,DFT_COMPLEX_OUTPUT傅里叶变换方法
cat_shift = np.fft.fftshift(cat_dft)   # 进行shift变换
# 映射到灰度图中
cat_gray = 20*np.log(cv.magnitude(cat_shift[:, :, 0], cat_shift[:, :, 1]))  # cv2.magnitude()转换后数值小,需要映射到(0, 255)所以需要转换
plt.subplot(221), plt.imshow(cat, 'gray'), plt.title('cat'), plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(cat_gray, 'gray'), plt.title('cat_dft'), plt.xticks([]), plt.yticks([])
plt.show()

效果:

         原图和经过傅里叶变换后的对比,经傅里叶变换后,中间最亮的区域就是频率为0,越往外频率就越大。

(2)低通滤波器

        低通滤波器:只保留低频,效果:会使图片模糊。

        原理:经过傅里叶变换和shift变换,将低频集中在了中间位置,只需要制作一个和输入图片大小一致的mask,此mask的格式只需要将中间一部分置为1,周围为0,然后将mask与经过傅里叶变换和shift变换的结果相乘,就得到了只剩低频的结果。

代码实现:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt


cat = cv.imread('../de/cat.jpg', 0)
cat_32 = np.float32(cat)

cat_dft = cv.dft(cat_32, flags=cv.DFT_COMPLEX_OUTPUT)  # 进行傅里叶变换,DFT_COMPLEX_OUTPUT傅里叶变换方法
cat_shift = np.fft.fftshift(cat_dft)   # 进行shift变换
w, h = cat.shape
x = int(w/2)
y = int(h/2)
print(x, y)
mask = np.zeros((w, h, 2), np.uint8)    # 构造mask
mask[(x-50):(x+50), (y-50):(y+50)] = 1
fcat_shift = cat_shift * mask
fcat = np.fft.ifftshift(fcat_shift)     # 逆shift
cat_back = cv.idft(fcat)           # 逆傅里叶
cat_back = cv.magnitude(cat_back[:, :, 0], cat_back[:, :, 1])   # 映射到(0,255)
plt.subplot(221), plt.imshow(cat, 'gray'), plt.title('cat'), plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(cat_back, 'gray'), plt.title('cat_back'), plt.xticks([]), plt.yticks([])
plt.show()

效果图:

 (3)高通滤波器

        高通滤波器:只保留高频,效果:会增强图片细节

        原理:和低通滤波器的原理几乎一致,只是构造mask时,将是1的变成0,0的变成1,这样就把低频的去掉,只保留高频。

代码实现:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt


cat = cv.imread('../de/cat.jpg', 0)
cat_32 = np.float32(cat)

cat_dft = cv.dft(cat_32, flags=cv.DFT_COMPLEX_OUTPUT)  # 进行傅里叶变换,DFT_COMPLEX_OUTPUT傅里叶变换方法
cat_shift = np.fft.fftshift(cat_dft)   # 进行shift变换
w, h = cat.shape
x = int(w/2)
y = int(h/2)
print(x, y)
mask = np.ones((w, h, 2), np.uint8)
mask[(x-50):(x+50), (y-50):(y+50)] = 0
fcat_shift = cat_shift * mask
fcat = np.fft.ifftshift(fcat_shift)
cat_back = cv.idft(fcat)
cat_back = cv.magnitude(cat_back[:, :, 0], cat_back[:, :, 1])
plt.subplot(221), plt.imshow(cat, 'gray'), plt.title('cat'), plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(cat_back, 'gray'), plt.title('cat_back'), plt.xticks([]), plt.yticks([])
plt.show()

效果图:

 二、Harris角点检测

        Harris角点检测其具体原理可以看知乎上一位大佬写的,链接:图像处理基础(七)Harris 角点检测 - 知乎,这上面有具体的原理和数学公式推导过程,我这里只介绍实现代码。

        在opencv中Harris角点检测为:cv2.cornerHarris(img, blockSize, ksize, k)

        img:数据类型为float32的的输入图像

        blockSize:角点检测中指定区域的大小

        ksize:Sober求导中使用窗口的大小

        k:取值参数,[0.04, 0.06]

实现代码:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

img = cv.imread('../de/c.jpg')
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
print(img_gray)
img_gray = np.float32(img_gray)
des = cv.cornerHarris(img_gray, 2, 3, 0.04)

img[des > 0.1*des.max()] = [255, 0, 0]  # 某一个自相似变化程度大于0.1倍的最大值我就可以认为这个就是一个角点
plt.imshow(img), plt.xticks([]), plt.yticks([])
plt.show()

效果图:

 对于黑白图像效果还是比较不错的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值