Путешествие в область восстановления изображений и оптического дешифрования для получения более четких газетных изображений и разборчивых номерных знаков

Какова основная цель этой задачи или проекта

у нас есть зашумленное изображение автомобиля с нечитаемым номерным знаком, и мы хотим улучшить видимость номерного знака с помощью методов обработки изображений.
Обработка изображений включает в себя манипулирование цифровыми изображениями для улучшения их качества, извлечения полезной информации и исправления искажений. вызвано получением или передачей изображения.
Конечная цель этой задачи обработки изображения — сделать номерной знак читаемым, чтобы мы могли извлечь из него полезную информацию. Это может быть полезно в различных приложениях, таких как наблюдение за дорожным движением, правоохранительные органы или управление парковкой.

Приступим………

1. Импортировать необходимые библиотеки для данной задачи

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.pyplot import imshow
import cv2
from numpy.fft import fft2, fftshift, ifft2,ifftshift
from scipy import signal

Здесь мы собираемся использовать библиотеки OpenCV для задач, связанных с компьютерным зрением.

2. Прочитайте изображение как изображение в градациях серого

  • Преобразование оттенков серого необходимо для упрощения задач обработки изображений, таких как обнаружение краев, сегментация и повышение контрастности.
image = cv2.imread('car.png',cv2.IMREAD_GRAYSCALE)
image= cv2.resize(image,(500,333))
imshow(image,cmap='gray')

3. Рассчитать дискретное преобразование Фурье изображения автомобиля.

  • Дискретное преобразование Фурье (ДПФ) — это математический алгоритм, используемый для преобразования сигнала во временной области в его представление в частотной области. Он разлагает сигнал на составляющие его частоты, что может быть полезно для анализа частотного содержания сигнала и для фильтрации нежелательных частот.
  • Для этого шага мы рассчитали двумерное дискретное преобразование Фурье (ДПФ) входного изображения автомобиля в градациях серого с использованием алгоритма быстрого преобразования Фурье (БПФ).
#apply 2d DFT
f=np.fft.fft2(image)

4. Сместите начало области изображения в центр и вычислите величину преобразования Фурье.

  • мы рассчитали спектр величин преобразования Фурье с помощью функции np.abs() и применили логарифмическое преобразование, чтобы подавить большой динамический диапазон значений величин и сделать его более заметным.
#shift to center
fshift=np.fft.fftshift(f)

#magnitude
magnitude_spectrum=20*np.log(np.abs(fshift))
#visualizing
plt.subplot(121), plt.imshow(image, cmap='gray')
plt.title('Input image'), plt.xticks([]),plt.yticks([])
plt.subplot(122), plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('Magnitude'), plt.xticks([]),plt.yticks([])
plt.show()

5. Обратите внимание, что белые пики в области Фурье улавливают периодический шум, присутствующий в исходном изображении.

  • Чтобы удалить периодический шум, мы использовали функцию «peak_local_max», чтобы найти координаты локальных максимумов в логарифмически преобразованной величине преобразования Фурье. Мы устанавливаем параметр «min_distance» равным 6, что является разумной оценкой, основанной на изображении магнитуды. Это означает, что мы выбираем только пики, которые находятся на расстоянии не менее 6 пикселей друг от друга. Это помогает избежать выбора ложных пиков, которые могут быть вызваны шумом или другими артефактами на изображении.
  • Сдвинутое преобразование Фурье в каждой точке (u,v) представляет собой значение преобразования Фурье после его сдвига таким образом, что центр частотной области соответствует нулевой частоте. Это необходимо для выполнения обратного преобразования Фурье и получения отфильтрованного изображения.
# coordinates of the white peaks in the image the center is [150, 175]
from skimage.feature import peak_local_max
coordinates = peak_local_max(magnitude_spectrum, min_distance= 6, exclude_border=0)

coordinates

7. Вы хотите очистить исходное изображение в области Фурье, чтобы его величина имела только одну яркую «звезду» в центре. Ниже приведен скрипт, который поможет вам поэкспериментировать с шириной фильтра (2L+1 x 2L+1), перекрывающего частотные составляющие периодического шума, который мы хотим удалить.

#clean the image to get single star in the center
L = 3
dx,dy=np.shape(image)[0], np.shape(image)[1]
new= magnitude_spectrum.copy()

for coord in coordinates:
    i=coord[0]
    j=coord[1]
    if i==dx//2 and j==dy//2:
        continue
    else:    
        for k1 in np.arange(-L,L,1):
            for k2 in np.arange(-L,L,1):
                if i+k1>=0 and j+k2>=0 and i+k1<dx and j+k2<dy:
                    new[i+k1,j+k2]=0
                    fshift[i+k1,j+k2]=0 # shifted DFT of car image 
imshow(new, cmap='gray')
plt.title("The size of the neighbourhood is "+str(2*L+1)+"x"+str(2*L+1))

8. Выполните обратное преобразование Фурье (используя модифицированные частотные компоненты), чтобы вернуть изображение. Визуализируйте свой результат.

  • · Обратное преобразование Фурье — это операция, обратная преобразованию Фурье. Он используется для преобразования сигнала, преобразованного в частотную область, обратно во временную область. Это полезно, когда вы хотите анализировать или манипулировать сигналом в частотной области, но затем вам нужно преобразовать его обратно во временную область, чтобы выполнить над ним операции.
# Perform inverse Fourier transform to obtain the filtered image
filtered_image = np.fft.ifftshift(fshift)
filtered_image = ifft2(filtered_image)

# Take the real part of the filtered image (imaginary part is negligible)
filtered_image = np.real(filtered_image)
image_back= (filtered_image-np.min(filtered_image))*255.0/(np.max(filtered_image)-np.min(filtered_image)) 

# Visualize the filtered image
plt.imshow(image_back, cmap='gray')
plt.title('Filtered Image')

9. Разрежьте изображение, чтобы получить только область номерного знака.

import skimage
from skimage import transform
#scaled= transform.rescale(image_back,1.2, anti_aliasing=False)
image_back = image_back[150:280,100:300]
plt.imshow(image_back,cmap='gray')

10. Применить фильтр Гаусса

  • Потому что он известен своей способностью устранять локальные шумы в области Фурье.
  • Фильтр Гаусса — это фильтр нижних частот, который удерживает низкочастотные компоненты, связанные со структурой изображения, и ослабляет высокочастотные компоненты, которые часто связаны с шумом или мелкими деталями.
from scipy import signal

# create a low-pass Gaussian filter
kernel = np.outer(signal.gaussian(image_back.shape[0], 1), signal.gaussian(image_back.shape[1], 1))
# find Fourier transform of the image f(x,y)
freq = fft2(image_back)
# generate a kernel whose origin is in the top-left corner
kern = ifftshift(kernel)  # h(x,y)
# calculate FFT of the kernel
freq_kernel = fft2(kern)
# multiply in the frequency domain
low_pass_product = freq * freq_kernel
# compute the low-pass filtered image
low_pass_im = ifft2(low_pass_product).real

plt.imshow(low_pass_im, cmap='gray')

11. Примените гамма-коррекцию для улучшения контраста.

  • Гамма-коррекция — это нелинейная регулировка, которая применяется к значениям интенсивности изображения, что может привести к тому, что более темные области станут темнее, а более яркие области — ярче, в зависимости от используемого значения гаммы.
  • Значение гаммы меньше 1 сделает темные области изображения более яркими, оставив светлые области относительно неизменными. Это иногда называют «гамма-сжатием». И наоборот, значение гаммы больше 1 сделает темные области изображения темнее, а светлые области — ярче. Иногда это называют «гамма-расширением».
from skimage import exposure,img_as_float

fig,ax = plt.subplots(nrows=2, ncols=2, figsize=(10,5))
# Gamma corrected
gamma_corrected = exposure.adjust_gamma(image_back, 2)

# logarithmic corrected
logarithmic_corrected = exposure.adjust_log(image_back, 1)

ax[0,0].imshow(gamma_corrected,cmap='gray')
ax[0,1].imshow(logarithmic_corrected,cmap='gray')
ax[1,0].hist(gamma_corrected.ravel(), bins=30, histtype='step', color='b' )
ax[1,1].hist(logarithmic_corrected.ravel(), bins=30, histtype='step', color='b' )

12. Выберите среднюю точку, вокруг которой вы хотите растянуть контраст и нормализовать предыдущий результат.

  • Контрастное растяжение — это метод обработки изображений, используемый для регулировки контраста изображения. Он часто используется для улучшения визуального качества изображений, которые кажутся размытыми или имеют низкую контрастность. Контрастное растяжение включает изменение масштаба значений интенсивности изображения для распространения диапазона значений по всему динамическому диапазону изображения. Это может помочь выявить больше деталей на изображении и сделать его визуально более привлекательным.
def normalize(intensity, m, E):
    I = intensity
    dx, dy = np.shape(intensity)[0], np.shape(intensity)[1]
    eps = 0.001
    cs = np.zeros((dx, dy))
    for i in range(dx):
        for j in range(dy):
            cs[i, j] = (I[i, j] - m) * (E / (1 - m - eps))
    return cs

# choose a midpoint of 128 and maximum intensity value of 255
m = 100
E = 200

# apply contrast stretching to the Fourier-reconstructed image
g = normalize(gamma_corrected, m, E)

# display the resulting image
plt.imshow(g, cmap='gray')

Выводы

После нормализации мы получили сегментированную область изображения с определенной четкостью, но не полностью. Это может быть BHT 042 / BHT 012. Мы могли ясно видеть номерной знак при гамма- и логарифмической коррекции, но не так четко при нормализации.

Спасибо за прочтение

Если вам нравится моя работа и вы хотите меня поддержать…

  1. ЛУЧШИЙ способ поддержать меня — подписаться на меня на Medium здесь.
  2. Будьте одним из ПЕРВЫХ, кто подпишется на меня в nstagram здесь.
  3. Подпишитесь на меня в LinkedIn здесь.
  4. Следуйте за мной на GitHub здесь.