代码

  1. import cv2, math
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. ## 定义图像目录
  5. image_directory = 'D:\\Data_documents\\ImageProcess\\images\\'
  6. # 图像读取
  7. imgname = image_directory + 'lena.jpg'
  8. img = cv2.imread(imgname)
  9. # 图像显示在一个新的名字为'image'的窗口中,如果看不到,在任务栏中把窗口恢复后观察图像,在窗口中按任意键关闭窗口
  10. cv2.imshow('image',img)
  11. cv2.waitKey(0)
  12. cv2.destroyAllWindows()
  13. # 彩色图像转化为灰度图像
  14. image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

1. 图像加噪声

1.1 高斯噪声

  1. # 产生高斯随机噪声,并显示 (mean value to 128 and a standard deviation to 20.)
  2. gaussian_noise = np.zeros((image.shape[0], image.shape[1]),dtype=np.uint8)
  3. cv2.randn(gaussian_noise, 128,10)
  4. cv2.imshow('Gaussian noise',gaussian_noise)
  5. cv2.waitKey(0)
  6. cv2.destroyAllWindows()

1.2 随机噪声

  1. # 产生随机噪声,并显示 ( random values drawn from an uniform distribution, the pixel values were set from 0 to 255)
  2. uniform_noise = np.zeros((image.shape[0], image.shape[1]),dtype=np.uint8)
  3. cv2.randu(uniform_noise,0,255)
  4. cv2.imshow('uniform noise',uniform_noise)
  5. cv2.waitKey(0)
  6. cv2.destroyAllWindows()

1.3 脉冲噪声

  1. # 产生脉冲噪声,并显示 (大于250的设置为255(白色),其余设置为0)
  2. impulse_noise = uniform_noise.copy()
  3. ret,impulse_noise = cv2.threshold(uniform_noise,250,255,cv2.THRESH_BINARY)
  4. cv2.imshow('Impulse noise',impulse_noise)
  5. cv2.waitKey(0)
  6. cv2.destroyAllWindows()

1.4 添加噪声到图像

  1. # 1
  2. gaussian_noise = (gaussian_noise*0.5).astype(np.uint8)
  3. noisy_image1 = cv2.add(image,gaussian_noise)
  4. cv2.imshow('Noisy image - Gaussian noise',noisy_image1)
  5. # 2
  6. uniform_noise = (uniform_noise*0.5).astype(np.uint8)
  7. noisy_image2 = cv2.add(image,uniform_noise)
  8. cv2.imshow('Noisy image - Uniform noise',noisy_image2)
  9. # 3
  10. impulse_noise = (impulse_noise*0.5).astype(np.uint8)
  11. noisy_image3 = cv2.add(image,impulse_noise)
  12. cv2.imshow('Noisy image - Impuls noise',noisy_image3)
  13. cv2.waitKey(0)
  14. cv2.destroyAllWindows()

1.5 中值滤波

  1. blurred1 = cv2.medianBlur(noisy_image1, 3)
  2. cv2.imshow('Median filter - Gaussian noise',blurred1)
  3. blurred2 = cv2.medianBlur(noisy_image2, 3)
  4. cv2.imshow('Median filter - Uniform noise',blurred2)
  5. blurred3 = cv2.medianBlur(noisy_image3, 3)
  6. cv2.imshow('Median filter - Impuls noise',blurred3)
  7. cv2.waitKey(0)
  8. cv2.destroyAllWindows()
  9. # 观察: 中值滤波对于脉冲噪声的滤波效果较好

1.6 观察三种噪声能量分布

  1. #观察三种噪声的能量分布
  2. filters = [gaussian_noise, uniform_noise, impulse_noise, noisy_image1, noisy_image2, noisy_image3]
  3. filter_name = ['gaussian_noise', 'uniform_noise','impulse_noise', 'noisy_image1', 'noisy_image2', 'noisy_image3']
  4. fft_filters = [np.fft.fft2(x) for x in filters]
  5. fft_shift = [np.fft.fftshift(y) for y in fft_filters]
  6. mag_spectrum = [np.log(np.abs(z)+1) for z in fft_shift]
  7. for i in range(6):
  8. plt.subplot(2,3,i+1),plt.imshow(mag_spectrum[i],cmap = 'gray')
  9. plt.title(filter_name[i]), plt.xticks([]), plt.yticks([])
  10. plt.show()

image.png

2. 图像模糊的检测问题

2.1 图像模糊检测方法

  1. # 下面的函数计算并返回图像的FFT变换的高频部分的均值
  2. def detect_blur_fft(image, size=60, vis=False):
  3. # grab the dimensions of the image and use the dimensions to
  4. # derive the center (x, y)-coordinates
  5. (h, w) = image.shape
  6. (cX, cY) = (int(w / 2.0), int(h / 2.0))
  7. # FFT
  8. fft = np.fft.fft2(image)
  9. fftShift = np.fft.fftshift(fft)
  10. magnitude = 20 * np.log(np.abs(fftShift))
  11. if vis:
  12. # display the original input image
  13. (fig, ax) = plt.subplots(1, 2, )
  14. ax[0].imshow(image, cmap="gray")
  15. ax[0].set_title("Input")
  16. ax[0].set_xticks([])
  17. ax[0].set_yticks([])
  18. # display the magnitude image
  19. ax[1].imshow(magnitude, cmap="gray")
  20. ax[1].set_title("Magnitude Spectrum")
  21. ax[1].set_xticks([])
  22. ax[1].set_yticks([])
  23. # show our plots
  24. plt.show()
  25. # FFT 取高频,并求反变换
  26. fftShift[cY - size:cY + size, cX - size:cX + size] = 0
  27. fftShift = np.fft.ifftshift(fftShift)
  28. recon = np.fft.ifft2(fftShift)
  29. magnitude = 20 * np.log(np.abs(recon))
  30. # 返回均值
  31. mean = np.mean(magnitude)
  32. return mean
  1. # 利用该函数对不同的图像进行检测,显示FFT结果,并返回结果
  2. detect_blur_fft(image, size=60,vis=True)
  3. # 利用该函数对不同的图像进行检测,不显示FFT结果,返回结果
  4. detect_blur_fft(image, size=60,vis=False)
  1. # orgimg: 输入的图像
  2. # thres: 阈值
  3. def display_blur_fft(orgimg, thres):
  4. gray = cv2.resize(orgimg, (500, int(orgimg.shape[1]/orgimg.shape[0]*500)) )
  5. # 判断是否彩色图像,是则转换成灰度图像
  6. if (len(gray.shape)>2):
  7. gray = cv2.cvtColor(gray, cv2.COLOR_BGR2GRAY)
  8. mean_value = detect_blur_fft(gray)
  9. # 大于阈值则设置为 Blurry
  10. blurry = (mean_value < thres)
  11. # 在图像上显示
  12. # 构造一个三通道BGR的彩色图像
  13. image = np.dstack([gray] * 3)
  14. # 设置显示mean值的颜色(BGR)和格式
  15. color = (0, 0, 255) if blurry else (0, 255, 0)
  16. text = "Blurry ({:.4f})" if blurry else "Not Blurry ({:.4f})"
  17. text = text.format(mean_value)
  18. # 设置显示mean值的位置和字体、宽度
  19. cv2.putText(image, text, (10, 25), cv2.FONT_HERSHEY_SIMPLEX, 0.7, color, 2)
  20. # print("[INFO] {}".format(text))
  21. # 显示图像
  22. cv2.imshow("Output", image)
  1. # 阈值设为 15
  2. display_blur_fft(image, 15)
  3. cv2.waitKey(0)
  4. cv2.destroyAllWindows()
  5. # 阈值设为 20
  6. img_Guassian = cv2.GaussianBlur(image,(5,5),0)
  7. display_blur_fft(img_Guassian, 20)
  8. cv2.waitKey(0)
  9. cv2.destroyAllWindows()

2.2 视频实时显示图像,判断是否模糊

  1. # 开启计算机的摄像头,降噪后显示实时图像和是否模糊,按q退出
  2. cap = cv2.VideoCapture(0)
  3. cv2.imshow("Output", image)
  4. while True:
  5. # Capture frame-by-frame
  6. ret, frame = cap.read()
  7. if ret==True:
  8. frameimg = cv2.medianBlur(frame, 3)
  9. # 显示是否模糊
  10. display_blur_fft(frameimg, 15.5)
  11. # 判断键盘输入q后,退出
  12. key = cv2.waitKey(1) & 0xFF
  13. if key == ord("q"):
  14. break;
  15. # When everything done, release the capture
  16. cap.release()
  17. cv2.destroyAllWindows()

知识点

5.1 图像退化模型

5.2 噪声模型及参数估计

5.3 图像复原方法

5.4 图像几何校正

课件

机器视觉-第5章-图像复原.pdf