Восстановление изображений для улучшения деталей с помощью OpenCV - PullRequest
3 голосов
/ 28 июня 2019

Я пытаюсь восстановить и улучшить детали изображения на нескольких фотографиях. Я попытался выявить детали, увеличив резкость с cv2.filter2D() и простыми ядрами .

Я пробовал ядро ​​обнаружения ребер

[-1 -1 -1]
[-1  9 -1]
[-1 -1 -1]

и заостренное ядро ​​

[ 0 -1  0]
[-1  5 -1]
[ 0 -1  0]

но результаты выглядят зернистыми и неестественными. Чтобы сгладить шум, я попробовал методы размытия, такие как cv2.medianBlur() и cv2.GaussianBlur(), но результаты не так уж хороши. Изображения имеют размытый фон или темный цвет, что затрудняет их различение. Есть ли лучший способ выделить больше деталей, особенно в фоновом режиме? Открыто для Python или C ++

Входные изображения

enter image description here

Текущие результаты enter image description here

import numpy as np
import cv2

img = cv2.imread('people.jpg')
grayscale = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# edge_kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
sharpen_kernel = np.array([[0,-1,0], [-1,5,-1], [0,-1,0]])
img = cv2.filter2D(grayscale, -1, sharpen_kernel)

# Smooth out image
# blur = cv2.medianBlur(img, 3)
blur = cv2.GaussianBlur(img, (3,3), 0)

cv2.imshow('img',img)
cv2.imwrite('img.png',img)
cv2.imshow('blur',blur)
cv2.waitKey(0)

Ответы [ 4 ]

3 голосов
/ 29 июня 2019

Просто для сравнения, у меня есть скрипт ImageMagick, который делает пространственно адаптивное контрастное усиление (называемое пробелом). Смотри http://www.fmwconcepts.com/imagemagick.

Введите:

enter image description here

space -c 2 -w 20 img.jpg result.png


enter image description here

Более подробно, но немного зернисто.

Вот результат из моего варианта space2, который может быть вам более приятен.

space2 -w 5 -m 10 img.jpg result_space2_w5_m10.jpg


enter image description here

Пояснение:

SPACE2 - это адаптивная техника для повышения яркости и контрастности изображения. SPACE - это аббревиатура для пространственно-адаптивного усиления контраста.

Адаптивная формула R = M + G * (I-M). Здесь R - результирующее изображение. Я является входным изображением. M - это среднее изображение, которое является фильтрованной версией входного изображения. Он генерируется изменением размера входного изображения до некоторой доли входного размера. Размер изменения вычисляется из размера окна. Это изображение затем снова расширяется до исходного размера. Метод изменения размера - это быстрый способ применения скользящего среднего окна большого размера. Термин (I-M) является фильтрованной версией версии входного изображения. G является изображением усиления, которое включает в себя S, стандартное отклонение входного изображения, сгенерированное той же техникой изменения размера, которая используется для создания среднего изображения, M. G также включает желаемое стандартное отклонение (dstd) и коэффициент максимального усиления. Изображение усиления, G, используется для установки количества деталей (резкости) на выходе, а также для ограничения усиления при разгоне. Максимальное усиление обычно составляет порядка 1-10, по умолчанию 2,5. Размер окна блока обычно составляет порядка 5-20% от размера изображения и номинально 8%. В некоторых случаях может потребоваться увеличить максимальное значение усиления по сравнению с настройками по умолчанию, например, при попытке извлечь информацию из туманного изображения. Алгоритм имеет опции для управления яркостью, контрастностью и насыщенностью. Яркость и контраст имеют автоматически рассчитанные значения по умолчанию, которые зависят от изображения. Они применяются через сигмоидальные нелинейные функции. Насыщенность - это линейная корректировка в цветовом пространстве LAB, по умолчанию она не изменяется.

3 голосов
/ 29 июня 2019

Вы можете попробовать применить гауссовую фильтрацию с сохранением краев вместо GaussianBlur.

Например, вы можете попробовать двусторонний фильтр или управляемый фильтр

Существуют реализации OpenCV, но я никогда не пробовал их.

Следующий код MATLAB демонстрирует фильтры:

I = rgb2gray(im2double(imread('I.jpg')));

G = imguidedfilter(I, 'DegreeOfSmoothing', 0.005);
J = imsharpen(G, 'Amount', 2);

figure;imshow(J)

B = imbilatfilt(I);
K = imsharpen(B, 'Amount', 2);
figure;imshow(K)

Управляемый фильтр:
Guided filter

Двусторонний фильтр:
enter image description here

3 голосов
/ 29 июня 2019

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

image

from matplotlib import pyplot as plt
import cv2

# Load in image as grayscale
image = cv2.imread('1.jpg', 0)

plt.hist(image.ravel(), 256, [0,256])

Пиксели сгруппированы вокруг интенсивностей среднего диапазона.Чтобы увеличить контраст изображения, выравнивание гистограммы растягивает значения интенсивности по всему диапазону, чтобы получить более широкое и более равномерное распределение.Вы можете сделать это с помощью встроенной функции cv2.equalizeHist()

image

equalize = cv2.equalizeHist(image)
plt.hist(equalize.ravel(), 256, [0,256])

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

enter image description here


В некоторых случаях, когда существуют различия в интенсивности в большой области, CLAHE (уравнивание адаптивной гистограммы с ограниченной контрастностью) может бытьлучше.CLAHE реализован в OpenCV как cv2.createCLAHE()

image

clahe = cv2.createCLAHE().apply(image)
plt.hist(clahe.ravel(), 256, [0,256])

Этот вариант делит пиксели на небольшие блоки перед выполнением адаптивной коррекции гистограммы.

enter image description here

Вот визуализация между двумя методами enter image description here

2 голосов
/ 29 июня 2019

Вы можете сделать фильтр более слабым, например,

sharpen_kernel = np.array([[0,-.5,0], [-.5,3,-.5], [0,-.5,0]])

Или, возможно, попробовать нечеткую маскировку

gaussian_3 = cv2.GaussianBlur(grayscale, (9,9), 10.0)
img = cv2.addWeighted(img, 1.5, gaussian_3, -0.5, 0, img)
...