filtering and hybrid images

filtering and hybrid images

import cv2
import numpy as np

imga = cv2.imread('../../data/fish.bmp')
imgb = cv2.imread('../../data/submarine.bmp')

d0=40

def single_channel(img):
    rows, cols = img.shape[:2]
 
    # 计算最优尺寸
    nrows = cv2.getOptimalDFTSize(rows)
    ncols = cv2.getOptimalDFTSize(cols)
    # 根据新尺寸,建立新变换图像
    nimg = np.zeros((nrows, ncols))
    nimg[:rows,:cols] = img
    # 得到的fft_mat有2个通道,实部和虚部
    fft_mat = cv2.dft(np.float32(nimg), flags = cv2.DFT_COMPLEX_OUTPUT)
    # 反换位,低频部分移到中间,高频部分移到四周
    fft_mat = np.fft.fftshift(fft_mat)

    return fft_mat
 
def fft_distances(m, n):
    u = np.array([i - m/2 for i in range(m)], dtype=np.float32)
    v = np.array([i - n/2 for i in range(n)], dtype=np.float32)
    ret = np.ones((m, n))
    for i in range(m):
        for j in range(n):
            ret[i][j] = np.sqrt(u[i]*u[i] + v[j]*v[j])
    u = np.array([i if i<=m/2 else m-i for i in range(m)], dtype=np.float32)
    v = np.array([i if i<=m/2 else m-i for i in range(m)], dtype=np.float32)
    return ret
 
def change_filter(flag):
    # 理想低通滤波器
    if flag == 1:
        # 初始化滤波器,因为fft_mat有2个通道,filter_mat也需要2个通道
        filter_mat = np.zeros((nrows, ncols ,2), np.float32)
        # 将filter_mat中以(ncols/2, nrows/2)为圆心、d0为半径的圆内的值设置为1
        cv2.circle(filter_mat, (np.int(ncols/2), np.int(nrows/2)) , d0, (1,1,1), -1)
    # 布特沃斯低通滤波
    elif flag == 2:
        n = 2 # 2阶
        filter_mat = None
        duv = fft_distances(*fft_mat.shape[:2])
        filter_mat = 1 / (1+ np.power(duv/d0, 2*n))
        filter_mat = cv2.merge((filter_mat, filter_mat)) # fliter_mat 需要2个通道
    # 高斯低通滤波(σ为d0)
    else:
        filter_mat = None
        duv = fft_distances(*fft_mat.shape[:2])
        filter_mat = np.exp(-(duv*duv) / (2*d0*d0))
        filter_mat = cv2.merge((filter_mat, filter_mat)) # fliter_mat 需要2个通道
    return filter_mat
 
def ifft(fft_mat):
    # 反换位,低频部分移到四周,高频部分移到中间
    f_ishift_mat = np.fft.ifftshift(fft_mat)
    # 傅里叶反变换
    img_back = cv2.idft(f_ishift_mat)
    # 将复数转换为幅度, sqrt(re^2 + im^2)
    img_back = cv2.magnitude(*cv2.split(img_back))
    # 标准化到0~255之间
    cv2.normalize(img_back, img_back, 0, 255, cv2.NORM_MINMAX)
    return np.uint8(np.around(img_back))[:rows,:cols]


def blur(img):
    #低频
    b,g,r = cv2.split(img)
    fft_mat_b = single_channel(b)
    fft_mat_g = single_channel(g)
    fft_mat_r = single_channel(r)
    img1 = ifft(change_filter(3) * fft_mat_b) # 高斯低通
    img2 = ifft(change_filter(3) * fft_mat_g) # 高斯低通
    img3 = ifft(change_filter(3) * fft_mat_r) # 高斯低通

    img = cv2.merge([img3,img2,img1])

    return img

def sharp(img, num):  # num是用来选择哪种滤波器的
    # 高频
    b,g,r = cv2.split(img)
    fft_mat_b = single_channel(b)
    fft_mat_g = single_channel(g)
    fft_mat_r = single_channel(r)
    img1 = ifft((1 - change_filter(num)) * fft_mat_b) # 高斯低通
    img2 = ifft((1 - change_filter(num)) * fft_mat_g) # 高斯低通
    img3 = ifft((1 - change_filter(num)) * fft_mat_r) # 高斯低通

    img = cv2.merge([img3,img2,img1])

    return img



def hybrid(img1,img2):
    img_blur = blur(img1)
    img_sharp = sharp(img2,2)

    result = img_blur+img_sharp
    
    plt.figure(figsize=(10,8))
    plt.subplot(131)
    plt.imshow(img_blur)
    plt.title('blur')
    plt.yticks([])
    plt.axis('off')

    plt.subplot(132)
    plt.imshow(img_sharp)
    plt.title('sharp')
    plt.yticks([])
    plt.axis('off')

    plt.subplot(133)
    plt.imshow(result)
    plt.title('hybrid')
    plt.yticks([])
    plt.axis('off')
    plt.savefig("myresult.jpg")
    return result

result = hybrid(imga,imgb)

Hybrid效果如下图所示,貌似 高通滤波器的效果不是很好。。。
filtering and hybrid images_第1张图片

img1 = sharp(imgb,1)
img2 = sharp(imgb,2)
img3 = sharp(imgb,3)
plt.figure(figsize=(12,10))
plt.subplot(131)
plt.imshow(img1)
plt.axis("off")
plt.subplot(132)
plt.imshow(img2)
plt.axis("off")
plt.subplot(133)
plt.imshow(img3)
plt.axis("off")

filtering and hybrid images_第2张图片
参考博客

你可能感兴趣的:(计算机视觉,python,opencv,numpy)