Удаление горизонтальных полос с помощью openCV2 - PullRequest
1 голос
/ 03 марта 2020

sample image

Я новичок в openCV, и мне было интересно, есть ли способ удалить полосы c в нижней половине этого изображения.

Я посмотрел этот пост, но не мог понять, что происходит: Удаление периодических c шумов с изображения с помощью преобразования Фурье

1 Ответ

2 голосов
/ 03 марта 2020

Вот как можно смягчить (уменьшить, но не полностью исключить) линии, используя преобразование Фурье и обработку режекторной фильтрации с помощью Python / OpenCV / Numpy. Поскольку горизонтальные линии на входе очень близки, в спектре преобразования Фурье будут горизонтальные линейные структуры, разнесенные далеко друг от друга. Итак, что я сделал:

  • Считайте ввод
  • Пэд со средним значением в степени 2 (чтобы попытаться смягчить любой звонок от разрыва с заполнением)
  • Выполните ДПФ
  • Вычислите изображение спектра по величине
  • Порог изображения и нарисуйте черную горизонтальную линию через центр, чтобы убрать яркую составляющую D C
  • Найдите, где отображаются яркие пятна (линии).
  • Получите координаты ярких пятен и нарисуйте белые горизонтальные линии на пороговом изображении, чтобы сформировать маску
  • Применить маску к Величина изображения
  • Делать IDFT
  • Обрезать до размера и нормализовать к тому же динамическому c диапазону, что и исходное изображение

Ввод:

enter image description here

import numpy as np
import cv2
import math

# read input as grayscale
img = cv2.imread('pattern_lines.png', 0)
hh, ww = img.shape

# get min and max and mean values of img
img_min = np.amin(img)
img_max = np.amax(img)
img_mean = int(np.mean(img))

# pad the image to dimension a power of 2
hhh = math.ceil(math.log2(hh))
hhh = int(math.pow(2,hhh))
www = math.ceil(math.log2(ww))
www = int(math.pow(2,www))
imgp = np.full((hhh,www), img_mean, dtype=np.uint8)
imgp[0:hh, 0:ww] = img

# convert image to floats and do dft saving as complex output
dft = cv2.dft(np.float32(imgp), flags = cv2.DFT_COMPLEX_OUTPUT)

# apply shift of origin from upper left corner to center of image
dft_shift = np.fft.fftshift(dft)

# extract magnitude and phase images
mag, phase = cv2.cartToPolar(dft_shift[:,:,0], dft_shift[:,:,1])

# get spectrum
spec = np.log(mag) / 20
min, max = np.amin(spec, (0,1)), np.amax(spec, (0,1))

# threshold the spectrum to find bright spots
thresh = (255*spec).astype(np.uint8)
thresh = cv2.threshold(thresh, 155, 255, cv2.THRESH_BINARY)[1]

# cover the center rows of thresh with black
yc = hhh // 2
cv2.line(thresh, (0,yc), (www-1,yc), 0, 5)

# get the y coordinates of the bright spots
points = np.column_stack(np.nonzero(thresh))
print(points)

# create mask from spectrum drawing horizontal lines at bright spots
mask = thresh.copy()
for p in points:
    y = p[0]
    cv2.line(mask, (0,y), (www-1,y), 255, 5)

# apply mask to magnitude such that magnitude is made black where mask is white
mag[mask!=0] = 0

# convert new magnitude and old phase into cartesian real and imaginary components
real, imag = cv2.polarToCart(mag, phase)

# combine cartesian components into one complex image
back = cv2.merge([real, imag])

# shift origin from center to upper left corner
back_ishift = np.fft.ifftshift(back)

# do idft saving as complex output
img_back = cv2.idft(back_ishift)

# combine complex components into original image again
img_back = cv2.magnitude(img_back[:,:,0], img_back[:,:,1])

# crop to original size
img_back = img_back[0:hh, 0:ww]

# re-normalize to 8-bits in range of original
min, max = np.amin(img_back, (0,1)), np.amax(img_back, (0,1))
notched = cv2.normalize(img_back, None, alpha=img_min, beta=img_max, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)

cv2.imshow("ORIGINAL", img)
cv2.imshow("PADDED", imgp)
cv2.imshow("MAG", mag)
cv2.imshow("PHASE", phase)
cv2.imshow("SPECTRUM", spec)
cv2.imshow("THRESH", thresh)
cv2.imshow("MASK", mask)
cv2.imshow("NOTCHED", notched)
cv2.waitKey(0)
cv2.destroyAllWindows()

# write result to disk
cv2.imwrite("pattern_lines_spectrum.png", (255*spec).clip(0,255).astype(np.uint8))
cv2.imwrite("pattern_lines_thresh.png", thresh)
cv2.imwrite("pattern_lines_mask.png", mask)
cv2.imwrite("pattern_lines_notched.png", notched)


Спектр (обратите внимание на яркие пятна в середине при y = 64 и 192):

enter image description here

Пороговое изображение:

enter image description here

Bright S Местонахождение банка:

[[   0 1023]
 [   0 1024]
 [   0 1025]
 [   1 1024]
 [  64 1024]
 [  65 1024]
 [ 191 1024]
 [ 192 1024]
 [ 255 1024]]


Маска:

enter image description here

Результат:

enter image description here

...