图像恢复:去除噪声并平滑轮廓,受损图像复原技术问询
Hey there! I see you’ve tried morphological closing and fixed thresholding to restore your noisy image, but aren’t satisfied with the output. Let’s walk through some targeted improvements and alternative methods that should give you cleaner results, especially since it looks like you’re dealing with pepper noise (given your initial closing operation choice).
1. Median Filtering + Adaptive Thresholding (Best for Salt & Pepper Noise)
Median filtering is the go-to for salt/pepper noise because it replaces each pixel with the median value of its neighborhood—this eliminates sharp, isolated noise points without blurring edges as much as morphological operations can. Pairing it with adaptive thresholding fixes the issue of fixed thresholds failing on unevenly lit images.
import cv2 import numpy as np # Load grayscale image img = cv2.imread(r'D:\Image\tainted.png', 0) # Apply median filter (adjust kernel size based on noise severity: 3x3 for light noise, 5x5 for heavy) median_cleaned = cv2.medianBlur(img, 5) # Use adaptive Gaussian thresholding to handle local brightness variations binary_img = cv2.adaptiveThreshold( median_cleaned, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, # Invert if your foreground is dark on light background 11, # Block size (must be odd) 2 # Constant subtracted from threshold )
2. Optimized Morphological Operations + Otsu’s Thresholding
If you want to stick with morphological methods, tweak your approach to avoid over-blurring details. Swap your large 5x5 kernel for a smaller one first, then use Otsu’s automatic thresholding instead of a fixed 127 value—it calculates the optimal threshold based on your image’s histogram.
img = cv2.imread(r'D:\Image\tainted.png', 0) # Smaller closing kernel to preserve fine details while filling pepper noise small_kernel = np.ones((3,3), np.uint8) closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, small_kernel) # Light Gaussian blur to smooth residual noise smoothed = cv2.GaussianBlur(closing, (3,3), 0) # Otsu's thresholding automatically finds the best binary cutoff ret, binary_img = cv2.threshold(smoothed, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
3. Non-Local Means Denoising (For Mixed Noise Scenarios)
If your image has a mix of pepper noise and Gaussian noise, non-local means denoising works better than standard filters. It averages similar pixel blocks across the image, preserving edges while reducing noise.
img = cv2.imread(r'D:\Image\tainted.png', 0) # Fast non-local means denoising (adjust h for strength: higher = more denoising, but more blurring) denoised = cv2.fastNlMeansDenoising( img, None, h=10, templateWindowSize=7, searchWindowSize=21 ) # Apply Otsu's thresholding for clean binarization ret, binary_img = cv2.threshold(denoised, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
Quick Tips for Tuning
- Adjust kernel sizes (3x3 vs 5x5) based on how large your noise spots are.
- For
adaptiveThreshold, tweak the block size (must be odd) and constant value to match your image’s contrast. - For non-local means, start with
h=10and increase if noise is still visible, but don’t go too high (you’ll lose detail).
内容的提问来源于stack exchange,提问作者flamelite

