问题
利用所学知识,实现如下图像的变换
分析
图片所示为空域增强实例——骨骼扫描图像,用于检测骨骼感染等疾病
问题的目的是突出骨骼的边缘和细节变化部分,但是图片的灰度动态范围较窄,并且有很高的噪声,难于使用单一方法进行增强。若使用直方图均衡化,由于图片本身灰度动态范围较窄,再均衡化则灰度更少,效果不好;左图并非低对比度图像,具有高低亮度的信息,单纯使用对数变换或伽马变换也不合适,目的并非压制高亮度。只有强化边缘和细节之后,才能调整亮度,所以要组合多种变换。
具体操作过程如下:
文字解释为:原图像A 经过拉普拉斯变换(二阶微分)得到图像B;图像A、B相加得到锐化后的图像C;
图像A经过sobel梯度处理(一阶微分)得到图像D;图像D经过平滑处理(3x3 或 5x5的滤波器)得到图像E;
图像C和图像E进行乘法变换得到图像F;图A和图F进行求和得到图像G;图像G进行幂律变换,最终的到结果。
分别使用Laplace和Sobel的原因是:在强化的同时,要抑制噪声Laplace对平滑部分噪声突显要强于梯度算子。梯度算子对边缘(灰度斜坡和台阶)平均响应高于laplace算子,对噪声等腰小于laplace算子。根据这个性质,用梯度算子抑制laplace噪声(保留灰度变换激烈部分的细节,抑制灰度变换平缓区域的噪声)
代码
代码语言:javascript复制from sklearn import preprocessing
import cv2
import matplotlib.pyplot as plt
import numpy as np
from skimage import data, filters, io
# 函数
def im2double(image):
info = np.iinfo(image.dtype) # 获取输入图像的数据类型
return image.astype(np.float) / info.max # 将所有值除以数据类型中最大可能的值
def rgb2gray(rgb):
return np.dot(rgb[..., :3], [0.299, 0.587, 0.114])
image = cv2.imread('image01.png') # 这里是原图的路径名
image = im2double(image)
image = rgb2gray(image)
cv2.imshow("Origin", image)
cv2.waitKey(0)
kernel = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]])
laplace = cv2.filter2D(image.astype('float32'), -1,
kernel, borderType=cv2.BORDER_CONSTANT)
cv2.imshow('laplacian', laplace)
cv2.waitKey(0)
# 加法操作
add_img = image laplace
cv2.imshow("add_img", add_img)
cv2.waitKey(0)
# 单方向x求梯度 sobel
sobel_img = filters.sobel(image)
# sobel_img = cv2.Sobel(image, cv2.CV_64F, 0, 1) 出现的结果不一样
cv2.imshow("sobel_img", sobel_img)
cv2.waitKey(0)
# 使用5*5均值滤波器平滑后的Sobel图像
average_img = cv2.blur(sobel_img, (3, 3)) #可以更改核的大小
cv2.imshow("average_img", average_img)
cv2.waitKey(0)
# 乘法运算 sobel平滑 和 拉普拉斯锐化
mask_img = add_img * average_img
cv2.imshow("mask_img", mask_img)
cv2.waitKey(0)
# 加法运算 原图 和 锐化加强mask_img
sharp_img = image mask_img
cv2.imshow("sharp_img", sharp_img)
cv2.waitKey(0)
# 进行灰度幂律变换
power_img = sharp_img ** 0.5
cv2.imshow("power_img", power_img)
cv2.waitKey(0)
结果
注意:不同的第三方库 如 cv2 和 plt,它们的show函数显示的处理后的图像是不一样的,但效果相同。