Как инвертировать ДПФ с величиной с помощью opencv python - PullRequest
2 голосов
/ 30 января 2020

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

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('IMG.jpg',0)

dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)

m, a = np.log(cv2.cartToPolar(dft_shift[:,:,0],dft_shift[:,:,1]))

# do somthing with m

x, y = cv2.polarToCart(np.exp(m), a)


back = cv2.merge([x, y])


f_ishift = np.fft.ifftshift(back)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])

plt.subplot(131),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(132),plt.imshow(m, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.subplot(133),plt.imshow(img_back, cmap = 'gray')
plt.title('result'), plt.xticks([]), plt.yticks([])
plt.show()

результат

result

Можете ли вы, ребята, помочь мне выяснить, почему это так темно.

Заранее спасибо:)

РЕДАКТИРОВАТЬ

Я попытался нормализовать изображение, но это не работает. У меня все еще очень темное изображение.


import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('IMG.jpg',0)

dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)

m, a = np.log1p(cv2.cartToPolar(dft_shift[:,:,0],dft_shift[:,:,1]))

# modify m, then use the modify m to reconstruct


x, y = cv2.polarToCart(np.expm1(m), a)


back = cv2.merge([x, y])


f_ishift = np.fft.ifftshift(back)
img_back = cv2.idft(f_ishift, flags=cv2.DFT_SCALE)
img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])


min, max = np.amin(img, (0,1)), np.amax(img, (0,1))
print(min,max)

# re-normalize to 8-bits
min, max = np.amin(img_back, (0,1)), np.amax(img_back, (0,1))
print(min,max)
img_back = cv2.normalize(img_back, None, alpha=0, beta=252, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)


min, max = np.amin(img_back, (0,1)), np.amax(img_back, (0,1))
print(min,max)


plt.subplot(131),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(132),plt.imshow(m, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.subplot(133),plt.imshow(img_back, cmap = 'gray')
plt.title('result'), plt.xticks([]), plt.yticks([])
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()

Вывод:

0 252
0.36347726 5867.449
0 252

Я хотел бы изменить спектр спектра и использовали модифицированную версию для восстановления изображения.

Ответы [ 3 ]

1 голос
/ 31 января 2020

Если вам нужно изменить величину, увеличив ее до степени, близкой к 1 (называемой коэффициентом корня или альфа-корнем), то это просто простая модификация моего кода выше с использованием Python / OpenCV. Просто добавьте cv2.pow (mag, 1.1) перед преобразованием величины и фазы обратно в реальные и мнимые компоненты.

Ввод:

enter image description here

import numpy as np
import cv2

# read input as grayscale
img = cv2.imread('lena.png', 0)

# convert image to floats and do dft saving as complex output
dft = cv2.dft(np.float32(img), 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 for viewing only
spec = np.log(mag) / 30

# NEW CODE HERE: raise mag to some power near 1
# values larger than 1 increase contrast; values smaller than 1 decrease contrast
mag = cv2.pow(mag, 1.1)

# convert magnitude and 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])

# re-normalize to 8-bits
min, max = np.amin(img_back, (0,1)), np.amax(img_back, (0,1))
print(min,max)
img_back = cv2.normalize(img_back, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)

cv2.imshow("ORIGINAL", img)
cv2.imshow("MAG", mag)
cv2.imshow("PHASE", phase)
cv2.imshow("SPECTRUM", spec)
cv2.imshow("REAL", real)
cv2.imshow("IMAGINARY", imag)
cv2.imshow("COEF ROOT", img_back)
cv2.waitKey(0)
cv2.destroyAllWindows()

# write result to disk
cv2.imwrite("lena_grayscale_opencv.png", img)
cv2.imwrite("lena_grayscale_coefroot_opencv.png", img_back)


Исходная шкала серого:

enter image description here

Результат укоренения с коэффициентом:

enter image description here

Вот анимация, показывающая различия (созданные с помощью ImageMagick):

enter image description here

0 голосов
/ 06 февраля 2020

Вот как удалить повторяющиеся узорные шумы из изображения с помощью режекторной фильтрации в области Фурье с использованием Python / OpenCV

  • Считать изображение
  • Do DFT
  • Generate амплитудные и фазовые составляющие от действительных и мнимых
  • Создать спектр От величины
  • Пороговое значение спектрального изображения для создания маски, покрывающей область D C в центре порогового изображения с черным
  • Примените маску к величине
  • Объедините новую величину и исходную фазу
  • Преобразуйте их в реальные и мнимые компоненты
  • Do IDFT
  • Сохранить результат

Ввод с повторяющимся узорным шумом:

enter image description here

import numpy as np
import cv2

# read input as grayscale
img = cv2.imread('clown.jpg', 0)

# get min and max values of img
img_min, img_max = np.amin(img, (0,1)), np.amax(img, (0,1))
print(img_min,img_max)

# convert image to floats and do dft saving as complex output
dft = cv2.dft(np.float32(img), 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

# create mask from spectrum keeping only the brightest spots as the notches
mask = cv2.normalize(spec, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX)
mask = cv2.threshold(mask, 0.65, 1, cv2.THRESH_BINARY)[1]

# dilate mask
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
mask = cv2.morphologyEx(mask, cv2.MORPH_DILATE, kernel)

# cover center DC component by circle of black leaving only a few white spots on black background
xcenter = mask.shape[1] // 2
ycenter = mask.shape[0] // 2
mask = cv2.circle(mask, (xcenter,ycenter), radius=10, color=0, thickness=cv2.FILLED)

# apply mask to magnitude such that magnitude is made zero where mask is one, ie at spots
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])

# re-normalize to 8-bits in range of original
min, max = np.amin(img_back, (0,1)), np.amax(img_back, (0,1))
print(min,max)
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("MAG", mag)
cv2.imshow("PHASE", phase)
cv2.imshow("SPECTRUM", spec)
cv2.imshow("MASK", mask)
cv2.imshow("NOTCHED", notched)
cv2.waitKey(0)
cv2.destroyAllWindows()

# write result to disk
cv2.imwrite("clown_mask.png", (255*mask).clip(0,255).astype(np.uint8))
cv2.imwrite("clown_notched.png", notched)


Спектр:

enter image description here

Маска:

enter image description here

Notch Filtered Результат ( шум удален):

enter image description here

Анимация (создается отдельно с помощью Imag emagick):

enter image description here

0 голосов
/ 30 января 2020

Вы должны извлечь значения амплитуды и фазы из cartToPolar () без применения журнала. Затем делайте журнал отдельно только для просмотра спектра, сохраняя величину в первоначальном виде. Затем измените исходную величину по своему желанию, прежде чем выполнять обратный сдвиг.

Одна из других проблем заключается в том, что изображение в обоих направлениях необходимо перемасштабировать обратно в 8-битный диапазон и тип данных. Я делаю это с помощью cv2.normalize (). Вы можете увидеть это из напечатанных значений min и max.

Вот как сделать дфт, получить спектр и затем сделать обратный дфт в Python / OpenCV. Я начинаю с цветного изображения, но я преобразую его в оттенки серого при чтении. Последним возвращаемым циклом обхода dft / idft будет все еще оттенки серого.

Ввод:

enter image description here

import numpy as np
import cv2

# read input as grayscale
img = cv2.imread('lena.png', 0)

# convert image to floats and do dft saving as complex output
dft = cv2.dft(np.float32(img), 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 for viewing only
spec = np.log(mag) / 30

# convert magnitude and 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])

# re-normalize to 8-bits
min, max = np.amin(img_back, (0,1)), np.amax(img_back, (0,1))
print(min,max)
img_back = cv2.normalize(img_back, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)

cv2.imshow("ORIGINAL", img)
cv2.imshow("MAG", mag)
cv2.imshow("PHASE", phase)
cv2.imshow("SPECTRUM", spec)
cv2.imshow("REAL", real)
cv2.imshow("IMAGINARY", imag)
cv2.imshow("ORIGINAL DFT/IFT ROUND TRIP", img_back)
cv2.waitKey(0)
cv2.destroyAllWindows()

# write result to disk
cv2.imwrite("lena_dft_ift_opencv.png", img_back)


Результат:

enter image description here

...