Programing

OpenCV에서 이미지를 선명하게하는 방법?

crosscheck 2020. 8. 3. 17:41
반응형

OpenCV에서 이미지를 선명하게하는 방법?


OpenCV를 사용하여 이미지를 선명하게하는 방법은 무엇입니까? 부드럽게하거나 흐리게하는 방법에는 여러 가지가 있지만 선명하게 볼 수있는 방법은 없습니다.


언 샤피 마스킹에 대한 위키피디아 기사 에서 일반적인 절차 중 하나를 설명 합니다. 가우시안 스무딩 필터를 사용하고 원본 이미지에서 스무딩 된 버전을 뺍니다 (가중 방식으로 일정 영역의 값이 일정하게 유지됨).

의 날카로운 버전을 얻으려면 frame로를 image(모두 cv::Mat)

cv::GaussianBlur(frame, image, cv::Size(0, 0), 3);
cv::addWeighted(frame, 1.5, image, -0.5, 0, image);

매개 변수에는 스스로 조정해야 할 것이 있습니다.

laplacian sharpening도 있습니다 .Google에서 찾을 수 있습니다.


간단한 커널filter2D 함수를 시도 할 수 있습니다 ( 예 : Python).

kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
im = cv2.filter2D(im, -1, kernel)

Wikipedia에는 ​​커널에 대한 좋은 개요가 있습니다-https://en.wikipedia.org/wiki/Kernel_(image_processing )

이미지 처리에서 커널, 컨벌루션 매트릭스 또는 마스크는 작은 매트릭스입니다. 블러 링, 샤프닝, 엠보싱, 에지 감지 등에 사용됩니다. 이것은 커널과 이미지 사이의 컨볼 루션을 수행함으로써 달성됩니다.


OpenCV Documentation 에서 "unsharp mask"알고리즘사용하여 이미지 선명 화 에 대한 샘플 코드를 찾을 수 있습니다 .

값 변경 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);

모든 이미지는 다양한 주파수의 신호 모음입니다. 높은 주파수는 가장자리를 제어하고 낮은 주파수는 이미지 내용을 제어합니다. 인접 셀에서 하나의 픽셀 값에서 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이지만 최대 허용 픽셀 범위로 인해 255로 잘립니다. 이것은 정보 손실이며 이미지가 씻겨 나옵니다.

addWeighted(frame, 1.5, image, -0.5, 0, image);

언샵 마스크를 사용하여 이미지를 선명하게 할 수 있습니다 . 언샵 마스킹에 대한 자세한 내용은 여기를 참조하십시오 . 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)

이 주제를 명확히하기 위해 실제로 몇 가지 사항을 고려해야합니다.

  1. 이미지를 선명하게하는 것은 잘못된 문제입니다. 다시 말해, 블러 링은 손실 된 작업이며 일반적으로 그로부터 되돌아가는 것은 불가능합니다.

  2. To sharpen single images, you need to somehow add constraints (assumptions) on what kind of image it is you want, and how it has become blurred. This is the area of natural image statistics. Approaches to do sharpening hold these statistics explicitly or implicitly in their algorithms (deep learning being the most implicitly coded ones). The common approach of up-weighting some of the levels of a DOG or Laplacian pyramid decomposition, which is the generalization of Brian Burns answer, assumes that a Gaussian blurring corrupted the image, and how the weighting is done is connected to assumptions on what was in the image to begin with.

  3. Other sources of information can render the problem sharpening well-posed. Common such sources of information is video of a moving object, or multi-view setting. Sharpening in that setting is usually called super-resolution (which is a very bad name for it, but it has stuck in academic circles). There has been super-resolution methods in OpenCV since a long time.... although they usually dont work that well for real problems last I checked them out. I expect deep learning has produced some wonderful results here as well. Maybe someone will post in remarks on whats worthwhile out there.


To sharpen an image we can use the filter (as in many answers above )

kernel = np.array([[-1, -1, -1],[-1, 8, -1],[-1, -1, 0]], np.float32) 

kernel/=denominator*kernel

it will the most when the denominator is 1 and will decrease as increased(2.3..)

the most used one is when the denominator is 3.

below is the implementation.

kernel = np.array([[-1, -1, -1],[-1, 8, -1],[-1, -1, 0]], np.float32)

kernel=1/3*kernel

dst=cv2.filter2D(image,-1,kernel)


Try with this:

cv::bilateralFilter(img,9,75,75);

You might find more info here

참고URL : https://stackoverflow.com/questions/4993082/how-to-sharpen-an-image-in-opencv

반응형