Відповіді:
Один загальний порядок викладений у статті Вікіпедії про нерізке маскування :
Ви використовуєте фільтр згладжування Гаусса і віднімаєте згладжений варіант від вихідного зображення (зваженим способом, щоб значення постійної області залишалися постійними).
Щоб отримати загострену версію frame
в image
: (обидва cv::Mat
)
cv::GaussianBlur(frame, image, cv::Size(0, 0), 3);
cv::addWeighted(frame, 1.5, image, -0.5, 0, image);
Параметри там є те, що потрібно підкоригувати для себе.
Існує також лаплакійська заточка, ви маєте щось знайти на Google.
Ви можете спробувати просте ядро та функцію filter2D , наприклад в Python:
kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
im = cv2.filter2D(im, -1, kernel)
У Вікіпедії є хороший огляд ядер, ще кілька прикладів тут - https://en.wikipedia.org/wiki/Kernel_(image_processing)
При обробці зображення ядро, матриця згортки або маска - це невелика матриця. Застосовується для розмивання, різкості, тиснення, виявлення країв тощо. Це досягається шляхом згортання між ядром і зображенням.
Ви можете знайти зразок коду щодо різкості зображення за допомогою алгоритму "нерізка маска" в документації OpenCV .
Зміна значень sigma
, threshold
, amount
дають різні результати.
// sharpen image using "unsharp mask" algorithm
Mat blurred; double sigma = 1, threshold = 5, amount = 1;
GaussianBlur(img, blurred, Size(), sigma, sigma);
Mat lowContrastMask = abs(img - blurred) < threshold;
Mat sharpened = img*(1+amount) + blurred*(-amount);
img.copyTo(sharpened, lowContrastMask);
Ви можете чітко зобразити за допомогою нерізкої маски . Ви можете знайти більше інформації про нерізке маскування тут . А ось реалізація Python за допомогою OpenCV:
import cv2 as cv
import numpy as np
def unsharp_mask(image, kernel_size=(5, 5), sigma=1.0, amount=1.0, threshold=0):
"""Return a sharpened version of the image, using an unsharp mask."""
blurred = cv.GaussianBlur(image, kernel_size, sigma)
sharpened = float(amount + 1) * image - float(amount) * blurred
sharpened = np.maximum(sharpened, np.zeros(sharpened.shape))
sharpened = np.minimum(sharpened, 255 * np.ones(sharpened.shape))
sharpened = sharpened.round().astype(np.uint8)
if threshold > 0:
low_contrast_mask = np.absolute(image - blurred) < threshold
np.copyto(sharpened, image, where=low_contrast_mask)
return sharpened
def example():
image = cv.imread('my-image.jpg')
sharpened_image = unsharp_mask(image)
cv.imwrite('my-sharpened-image.jpg', sharpened_image)
amount
- це просто кількість різкості. Наприклад, amount
2,0 дає чіткіше зображення порівняно зі значенням за замовчуванням 1,0. threshold
- поріг для низькоконтрастної маски. Іншими словами, пікселі, для яких різниця між вхідними та розмитими зображеннями менше threshold
, залишаться незмінними.
Будь-яке зображення - це сукупність сигналів різної частоти. Більш високі частоти керують ребрами, а нижчі - керують вмістом зображення. Краї утворюються при різкому переході від одного значення пікселя до іншого значення пікселя, такого як 0 і 255, у сусідній комірці. Очевидно, є різка зміна, а отже, крайка і висока частота. Для різкості зображення ці переходи можна додатково покращити.
Один із способів - це об'єднати власне виготовлене ядро фільтра із зображенням.
import cv2
import numpy as np
image = cv2.imread('images/input.jpg')
kernel = np.array([[-1,-1,-1],
[-1, 9,-1],
[-1,-1,-1]])
sharpened = cv2.filter2D(image, -1, kernel) # applying the sharpening kernel to the input image & displaying it.
cv2.imshow('Image Sharpening', sharpened)
cv2.waitKey(0)
cv2.destroyAllWindows()
Існує ще один метод віднімання розмитої версії зображення від яскравої його версії. Це допомагає відточувати зображення. Але робити це слід обережно, оскільки ми лише збільшуємо значення пікселів. Уявіть значення пікселя в градаціях сірого 190, яке, якщо помножити на вагу 2, становить 380, але обрізане на 255 завдяки максимально допустимому діапазону пікселів. Це втрата інформації та призводить до вимитого зображення.
addWeighted(frame, 1.5, image, -0.5, 0, image);
Для наочності в цій темі слід зробити кілька моментів:
Точність зображень - це неправомірна проблема. Іншими словами, розмивання - це втратна операція, і повернутися назад від неї взагалі неможливо.
Щоб відточувати окремі зображення, потрібно якось додати обмеження (припущення) щодо того, який саме образ ви хочете, і як він розмився. Це область статистики природних зображень. Підходи до різкості чітко або неявно містять цю статистику в своїх алгоритмах (глибоке навчання - це найбільш неявно закодовані). Загальний підхід до збільшення зважування деяких рівнів розпаду піраміди DOG або Лаплакійської піраміди , що є узагальненням відповіді Брайана Бернса, передбачає, що розмиття Гаусса пошкодило зображення, а те, як робиться зважування, пов'язане з припущеннями щодо того, що було в зображенні для початку.
Інші джерела інформації можуть вирішити проблему загострення проблеми. Поширеними такими джерелами інформації є відео рухомого об’єкта або налаштування з кількома переглядами. Загострення в цій обстановці зазвичай називають суперроздільною здатністю (це дуже погана назва, але вона застрягла в академічних колах). Там були методи супер-дозволом в OpenCV , оскільки довгий час .... хоча вони зазвичай не працюють , що добре для реальних проблем останній я перевірив їх. Я думаю, що глибоке навчання також дало чудові результати. Можливо, хтось опублікує зауваження щодо того, що варто там.
Для різкості зображення ми можемо використовувати фільтр (як у багатьох попередніх відповідях)
kernel = np.array([[-1, -1, -1],[-1, 8, -1],[-1, -1, 0]], np.float32)
kernel /= denominator * kernel
Це буде найбільше, коли знаменник дорівнює 1 і зменшиться зі збільшенням (2,3 ..)
Найбільш використовуваний, коли знаменник дорівнює 3.
Нижче наведено реалізацію.
kernel = np.array([[-1, -1, -1],[-1, 8, -1],[-1, -1, 0]], np.float32)
kernel = 1/3 * kernel
dst = cv2.filter2D(image, -1, kernel)