噪聲處理
噪聲的存在嚴重影響了遙感圖像的質量,因此在圖像增強處理和分類處理之前,必須予以糾正.圖像中各種妨礙人們對其信息接受的因素即可稱爲圖像噪聲 。噪聲在理論上可以定義爲“不可預測,只能用統計方法來認識的隨機誤差”。
- 高斯噪聲:高斯噪聲符合高斯分佈
- 椒鹽噪聲:椒鹽噪聲又稱脈衝噪聲,它隨機改變一些像素值,是由圖像傳感器,傳輸信道,解碼處理等產生的黑白相間的亮暗點噪聲。
去噪處理
消除噪聲成分成爲平滑或濾波,他有兩個重要的要求,第一是不能破壞圖片輪廓邊緣的重要信息,第二是圖片要清晰,視覺效果好.噪聲處理有均值濾波/高斯濾波/中值濾波/雙線性濾波
邊緣檢測
邊緣檢測算法有差分檢測/Reboerts算子/Sobel算子/Prewitt算子/Kirsch算子/Laplace算子
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
import PIL.Image as Image
import skimage
from skimage import filters
#實現均值濾波的代碼
def imgConvolve(image, kernel):
'''
卷積操作
'''
img_h = int(image.shape[0])
img_w = int(image.shape[1])
kernel_h = int(kernel.shape[0])
kernel_w = int(kernel.shape[1])
#padding 圖片的大小不變
padding_h = int((kernel_h - 1) / 2)
padding_w = int((kernel_w - 1) / 2)
convolve_h = int(img_h + 2*padding_h)
convolve_w = int(img_w + 2*padding_w)
#分配空間
img_padding = np.zeros((convolve_h, convolve_w))
#將像素值填充進去
img_padding[padding_h:padding_h+img_h, padding_w:padding_w+img_w] = image[:, :]
image_convolve = np.zeros(image.shape)
#進行卷積
for i in range(padding_h,padding_h+img_h):
for j in range(padding_w,padding_w+img_w):
image_convolve[i-padding_h][j-padding_w] = int(np.sum(img_padding[i-padding_h:i + padding_h+1, j-padding_w:j+padding_w+1]*kernel))
return image_convolve
def avgFilter(image, kernel):
'''
均值濾波
'''
img = imgConvolve(image, kernel)
return img * (1.0 / kernel.size)
#讀取圖片,灰度處理
data = cv.imread("filter_test.jpg")
data = cv.cvtColor(data, cv.COLOR_BGR2GRAY)
#保存灰度圖片
cv.imwrite("real_img.jpg", data, [int(cv.IMWRITE_JPEG_QUALITY), 70])
cv.waitKey(0)
cv.destroyWindows()
kernel_1 = np.ones([3,3])
kernel_2 = np.ones([5,5])
#均值濾波模糊處理
avg_data_1 = avgFilter(data, kernel_1)
avg_data_2 = avgFilter(data, kernel_2)
#保存圖片
cv.imwrite('avg_filter_1.jpg',avg_data_1,[int(cv.IMWRITE_JPEG_QUALITY),70]) #jpeg格式,質量爲70
cv.imwrite('avg_filter_2.jpg',avg_data_2,[int(cv.IMWRITE_JPEG_QUALITY),70]) #jpeg格式,質量爲70
#把保存圖片
img1 = cv.imread("avg_filter_1.jpg")
img2 = cv.imread("avg_filter_2.jpg")
imgs = np.hstack([img1, img2])
cv.imwrite("diff_filter.jpg", imgs, [int(cv.IMWRITE_JPEG_QUALITY), 70])
#生成含有噪聲圖片
rel_img = cv.imread("mouse.jpg") #(412, 550, 3)
#加入高斯噪聲
noise_img = skimage.util.random_noise(rel_img, mode='gaussian', seed=None, clip=True)
#salt椒鹽濾波
noise_img = skimage.util.random_noise(rel_img, mode='salt', seed=None, clip=True)
plt.figure(figsize=(10, 10))
plt.imshow(noise_img)
plt.xticks([])
plt.yticks([])
plt.savefig("gau_noise_img.jpg")
plt.show()
#opencv實現降噪
img_path = "gau_noise_img.jpg"
img = cv.imread(img_path)
#均值濾波
img1 = cv.blur(img, (5,5))
#高斯濾波
img2 = cv.GaussianBlur(img, (5,5), 0) #0指sigma
#中指濾波
img3 = cv.medianBlur(img, 5)
#雙值濾波
img4 = cv.bilateralFilter(img, 9, 75, 75)
titles = ['real', 'mean', 'gaussian', 'median', 'bilateral']
imgs = [img, img1, img2, img3, img4]
plt.figure(figsize=(20, 10))
for i in range(5):
plt.xticks([])
plt.yticks([])
plt.subplot(2, 3, i+1) #下標是從1開始的
plt.imshow(imgs[i])
plt.title(titles[i])
#先save在show,因爲如果show後會產生一張新的空白圖片,再保存下載的圖片就是空白的
#畫質70
plt.xticks([])
plt.yticks([])
plt.savefig("real_filter.jpg", quality=100)
plt.show()
#邊緣檢測
real_img = cv.imread("mouse.jpg")
real_img = cv.cvtColor(real_img, cv.COLOR_BGR2GRAY)
gau_filter_img = cv.imread("gau_noise_img.jpg")
gau_filter_img = cv.cvtColor(gau_filter_img, cv.COLOR_BGR2GRAY)
salt_filter_img = cv.imread("salt_noise_img.jpg")
salt_filter_img = cv.cvtColor(salt_filter_img, cv.COLOR_BGR2GRAY)
#-1表示和原圖像相同的深度, 兩個1分別是兩個方向的邊緣檢測
real_sobel_img = cv.Sobel(salt_filter_img, -1, 1, 1, ksize=3)
real_prewitt_img = filters.prewitt(salt_filter_img)
titles = ["real", "sobel", "prewitt"]
imgs = [salt_filter_img, real_sobel_img, real_prewitt_img]
plt.figure(figsize=(20, 10))
for i in range(3):
plt.xticks([])
plt.yticks([])
plt.subplot(1,3,i+1)
plt.imshow(imgs[i], cmap="gray") #顯示灰度圖即可
plt.title(titles[i])
plt.xticks([])
plt.yticks([])
plt.savefig("salt_edge_img.jpg")
plt.show()