OpenCV에서 합성곱을 사용한 이미지 필터링
포토샵이나 모바일 애플리케이션을 사용하여 이미지를 흐리게 처리하거나 선명하게 만들어 본 적이 있나요? 그렇다면 이미 합성곱 커널을 사용해 보셨을 겁니다. 여기에서는 OpenCV에서 이미지 필터링을 위해 합성곱을 사용하는 방법을 설명합니다.

2D 합성곱 커널과 OpenCV 컴퓨터 비전 라이브러리를 사용하여 이미지에 다양한 블러링 및 샤프닝 기법을 적용합니다. Python과 C++로 이러한 기법을 구현하는 방법을 보여드리겠습니다.
Table of Contents
- 이미지 처리에서의 합성곱 커널 소개
- 커널을 사용하여 이미지를 선명하게 하거나 흐리게 만드는 방법은?
- OpenCV에서 이미지에 Identity Kernel 적용
- 사용자 정의 2D 합성 커널을 사용하여 이미지 흐리게 만들기
- OpenCV의 내장 블러링 함수를 사용하여 이미지 블러링
- OpenCV에서 이미지에 가우시안 블러링 적용
- OpenCV에서 이미지에 중앙 흐림 효과 적용
- 사용자 정의 2D 합성 커널을 사용하여 이미지 선명도 향상
- OpenCV에서 이미지에 양측 필터링 적용
- 흥미로운 응용 프로그램
- 요약
이 시리즈의 튜토리얼 목록은 다음과 같습니다.
2. OpenCV를 사용하여 이미지 읽기, 표시 및 쓰기
7. OpenCV 이미지에 글씨 쓰기 - LearnOpenCV
10. OpenCV 이미지 임계값 처리 Thresholding
11. OpenCV 블롭 탐지 (Python, C++)
15. OpenCV 동영상 배경 단순 추정 C++, Python
16. OpenCV DNN 모듈을 활용한 딥 러닝: 완벽 가이드
먼저 이미지 필터링에 사용되는 코드를 살펴보겠습니다. 각 코드 줄을 자세히 설명하여 완전히 이해할 수 있도록 하겠습니다.
파이썬
import cv2
import numpy as np
image = cv2.imread('test.jpg')
# Print error message if image is null
if image is None:
print('Could not read image')
# Apply identity kernel
kernel1 = np.array([[0, 0, 0],
[0, 1, 0],
[0, 0, 0]])
identity = cv2.filter2D(src=image, ddepth=-1, kernel=kernel1)
cv2.imshow('Original', image)
cv2.imshow('Identity', identity)
cv2.waitKey()
cv2.imwrite('identity.jpg', identity)
cv2.destroyAllWindows()
# Apply blurring kernel
kernel2 = np.ones((5, 5), np.float32) / 25
img = cv2.filter2D(src=image, ddepth=-1, kernel=kernel2)
cv2.imshow('Original', image)
cv2.imshow('Kernel Blur', img)
cv2.waitKey()
cv2.imwrite('blur_kernel.jpg', img)
cv2.destroyAllWindows()
C++
// Import dependencies
#include <opencv2/opencv.hpp>
#include <iostream>
// Using namespaces to nullify use of c::function(); syntax and std::function(); syntax
using namespace std;
using namespace cv;
int main()
{
// Read Image
Mat image = imread("test.jpg");
// Print Error message if image is null
if (image.empty())
{
cout << "Could not read image" << endl;
}
// Apply identity filter using kernel
Mat kernel1 = (Mat_<double>(3,3) << 0, 0, 0, 0, 1, 0, 0, 0, 0);
Mat identity;
filter2D(image, identity, -1 , kernel1, Point(-1, -1), 0, 4);
imshow("Original", image);
imshow("Identity", identity);
waitKey();
imwrite("identity.jpg", identity);
destroyAllWindows();
// Blurred using kernel
// Initialize matrix with all ones
Mat kernel2 = Mat::ones(5,5, CV_64F);
// Normalize the elements
kernel2 = kernel2 / 25;
Mat img;
filter2D(image, img, -1 , kernel2, Point(-1, -1), 0, 4);
imshow("Original", image);
imshow("Kernel blur", img);
imwrite("blur_kernel.jpg", img);
waitKey();
destroyAllWindows();
}
시스템에 이미 OpenCV가 설치되어 있다고 가정합니다. OpenCV를 설치해야 하는 경우 아래 관련 링크를 방문하세요.
Windows에 OpenCV 설치
MacOS에 OpenCV 설치
Ubuntu에 OpenCV 설치
이미지 처리에서의 합성곱 커널 소개
이미지 처리에서 합성곱 커널은 이미지를 필터링하는 데 사용되는 2차원 행렬입니다. 합성곱 행렬이라고도 하는 합성곱 커널은 일반적으로 MxN 크기의 정사각 행렬이며, M 과 N은 모두 홀수(예: 3×3, 5×5, 7×7 등)입니다. 아래 3×3 행렬 예시를 참조하세요.

3×3 2D 합성곱 커널
이러한 커널은 이미지의 각 픽셀에 대해 수학 연산을 수행하여 원하는 효과(이미지를 흐리게 하거나 선명하게 하는 효과 등)를 얻는 데 사용할 수 있습니다. 그런데 이미지를 흐리게 처리하는 이유는 무엇일까요? 두 가지 중요한 이유는 다음과 같습니다.
- 이미지에서 특정 유형의 노이즈를 줄이기 때문입니다. 이러한 이유로 블러링은 종종 스무딩이라고 합니다.
- 방해가 되는 배경을 제거하려면 모바일 기기 카메라의 '인물 사진' 모드에서처럼 의도적으로 이미지의 일부를 흐리게 처리할 수 있습니다.
커널을 이용한 이미지 필터링은 컴퓨터 비전의 기본적인 처리 기술이지만, 그 활용 분야는 매우 다양합니다.
커널을 사용하여 이미지를 선명하게 하거나 흐리게 만드는 방법
소스 이미지의 필터링은 커널을 이미지와 합성곱(convolution)하여 수행됩니다. 간단히 말해, 이미지와 커널의 합성곱은 커널과 이미지의 해당 요소 간의 간단한 수학 연산을 의미합니다.
- 커널의 중심이 이미지의 특정 픽셀( p ) 위에 위치한다고 가정합니다.
- 그런 다음 커널의 각 요소 값(이 경우 1)을 소스 이미지의 해당 픽셀 요소(즉, 픽셀 강도)와 곱합니다.
- 이제 곱셈의 결과를 합산하고 평균을 계산합니다.
- 마지막으로, 픽셀( p ) 값을 방금 계산한 평균값으로 바꿉니다.
위의 3x3 커널을 사용하여 소스 이미지의 모든 픽셀에 대해 이 연산을 수행하면 필터링된 결과 이미지가 흐릿하게 보입니다. 이는 이 커널을 사용한 합성곱 연산이 평균화 효과를 가져 이미지를 부드럽게 하거나 흐릿하게 만드는 경향이 있기 때문입니다. 곧 커널의 개별 요소 값이 필터링의 특성을 어떻게 결정하는지 직접 확인하게 될 것입니다. 예를 들어, 커널 요소의 값을 변경하여 선명도 효과를 얻을 수도 있습니다. 이 개념은 간단하지만 매우 강력하여 수많은 이미지 처리 파이프라인에서 사용됩니다.
이제 합성곱 커널을 사용하는 방법을 배웠으니, OpenCV에서 이를 어떻게 구현하는지 살펴보겠습니다.
여기를 클릭하여 이 튜토리얼의 Colab 노트북을 방문 할 수도 있습니다 . 로컬 시스템을 설정하지 않고도 모든 실험을 실행할 수 있습니다.
우리는 모든 코딩 작업에 다음 이미지를 사용할 것입니다.
나무의 입력 이미지 예시입니다. OpenCV에서 합성곱을 논의하기 위해 모든 커널 연산에 이 이미지를 사용할 것입니다.

입력 이미지 예시입니다. 모든 커널 연산에 이 이미지를 사용합니다.
OpenCV에서 이미지에 Identity Kernel 적용하기
블러링 및 샤프닝 커널을 구현하는 방법을 설명하기 전에 먼저 항등 커널 에 대해 알아보겠습니다 . 항등 커널은 아래와 같이 가운데 원소가 1이고 나머지 원소는 모두 0인 정사각 행렬입니다.

3×3 항등 커널
단위 행렬의 특별한 점은 다른 행렬과 곱하면 원래 행렬이 반환된다는 것입니다. 이제 OpenCV 필터링 함수와 함께 이 단위 커널을 사용하는 방법을 살펴보겠습니다. 첫 번째 예제에서는 위의 단위 커널을 사용하여 필터링 연산이 원본 이미지를 변경하지 않는다는 것을 보여줍니다.
아래 코드와 같이 OpenCV와 Numpy를 가져오는 것으로 시작합니다.
파이썬
import cv2
import numpy as np
C++
// Import dependencies
#include <opencv2/opencv.hpp>
#include <iostream>
// Using namespaces to nullify use of c::function(); syntax and std::function(); syntax
using namespace std;
using namespace cv;
아래 코드에서는 다음 단계가 수행됩니다.
- 테스트 이미지를 읽어보세요
- 3×3 NumPy 배열을 사용하여 항등 커널을 정의합니다.
- OpenCV의 함수를 사용하여 filter2D() 선형 필터링 작업을 수행합니다.
- 원본 이미지와 필터링된 이미지를 표시합니다.imshow()
- 필터링된 이미지를 디스크에 저장하려면 다음을 사용하세요.imwrite()
filter2D(src, ddepth, kernel)
이 filter2D()함수에는 세 개의 입력 인수가 필요합니다.
- 첫 번째 인수는 소스 이미지입니다.
- 두 번째 인수는 ddepth결과 이미지의 깊이를 나타내는 입니다. -1 값은 최종 이미지의 깊이도 원본 이미지와 동일함을 나타냅니다.
- 최종 입력 인수는 kernel소스 이미지에 적용하는 입니다.
Python과 C++로 작성된 코드는 다음과 같습니다.
파이썬
image = cv2.imread('test.jpg')
"""
Apply identity kernel
"""
kernel1 = np.array([[0, 0, 0],
[0, 1, 0],
[0, 0, 0]])
# filter2D() function can be used to apply kernel to an image.
# Where ddepth is the desired depth of final image. ddepth is -1 if...
# ... depth is same as original or source image.
identity = cv2.filter2D(src=image, ddepth=-1, kernel=kernel1)
# We should get the same image
cv2.imshow('Original', image)
cv2.imshow('Identity', identity)
cv2.waitKey()
cv2.imwrite('identity.jpg', identity)
cv2.destroyAllWindows()
C++
// Apply identity filter using kernel
Mat kernel1 = (Mat_<double>(3,3) << 0, 0, 0, 0, 1, 0, 0, 0, 0);
Mat identity;
filter2D(image, identity, -1 , kernel1, Point(-1, -1), 0, 4);
imshow("Original", image);
imshow("Identity", identity);
waitKey();
imwrite("identity.jpg", identity);
destroyAllWindows();
아래 이미지에서 볼 수 있듯이 필터링된 이미지(오른쪽)는 원본 이미지(왼쪽)와 동일하게 보입니다. 원본 이미지와 항등 합성곱 후의 결과입니다.


원본 이미지와 identity convolution 후의 결과, 항등 커널을 적용한 후의 결과 이미지
사용자 정의 2D-Convolution 커널을 사용하여 이미지 흐리게 만들기
다음으로 이미지를 블러 처리하는 방법을 살펴보겠습니다. 여기서도 사용자 지정 커널을 정의하고, filter2D()OpenCV 함수를 사용하여 원본 이미지에 필터링 작업을 적용해 보겠습니다.
1로만 구성된 5×5 커널을 정의하는 것으로 시작합니다. 커널을 25로 나누는 것에도 유의하세요 . 왜 그럴까요? 2D 합성곱 행렬을 사용하여 이미지에 합성곱을 적용하기 전에 모든 값이 정규화되었는지 확인해야 합니다. 이는 커널의 각 요소를 커널의 요소 개수(이 경우 25)로 나누어서 수행됩니다. 이렇게 하면 모든 값이 [0, 1] 범위 내에 있게 됩니다.
이제 filter2D()함수를 사용하여 이미지를 필터링합니다. 보시다시피, filter2D() 사용자 정의 커널을 사용하여 이미지를 합성곱하는 데 사용할 수 있습니다.
파이썬
"""
Apply blurring kernel
"""
kernel2 = np.ones((5, 5), np.float32) / 25
img = cv2.filter2D(src=image, ddepth=-1, kernel=kernel2)
cv2.imshow('Original', image)
cv2.imshow('Kernel Blur', img)
cv2.waitKey()
cv2.imwrite('blur_kernel.jpg', img)
cv2.destroyAllWindows()
C++
// Blurred using kernel
// Initialize matrix with all ones
Mat kernel2 = Mat::ones(5,5, CV_64F);
// Normalize the elements
kernel2 = kernel2 / 25;
Mat img;
filter2D(image, img, -1 , kernel2, Point(-1, -1), 0, 4);
imshow("Original", image);
imshow("Kernel blur", img);
imwrite("blur_kernel.jpg", img);
waitKey();
destroyAllWindows();
아래 이미지의 결과를 살펴보고 필터링된 이미지(오른쪽)가 원본 이미지(왼쪽)에 비해 흐릿해진 것을 확인하세요. 원본 이미지와 블러링 커널을 사용하여 블러링한 결과입니다.

원본 이미지와 블러링 커널을 사용하여 블러링한 결과입니다. 사용자 정의 2D-Convolution 커널을 사용하여 흐릿한 이미지 생성
OpenCV 내장 함수를 사용하여 이미지 흐리게 만들기
OpenCV 내장 blur() 함수를 사용하여 이미지를 블러 처리할 수도 있습니다. 이 함수는 편의를 위해 만들어진 것으로, 커널을 별도로 정의할 필요 없이 이미지를 블러 처리하는 데 사용할 수 있습니다. ksize아래 코드와 같이 입력 인수를 사용하여 커널 크기를 지정하기만 하면 됩니다. 블러 함수는 내부적으로 5x5 블러 커널을 생성하여 원본 이미지에 적용합니다.
이 함수를 사용하는 아래 예제는 해당 함수를 blur() 사용한 위 예제와 정확히 동일한 출력을 생성합니다 filter2d() .
파이썬
"""
Apply blur using `blur()` function
"""
img_blur = cv2.blur(src=image, ksize=(5,5)) # Using the blur function to blur an image where ksize is the kernel size
# Display using cv2.imshow()
cv2.imshow('Original', image)
cv2.imshow('Blurred', img_blur)
cv2.waitKey()
cv2.imwrite('blur.jpg', img_blur)
cv2.destroyAllWindows()
C++
// Blurred using OpenCV C++ blur() function
Mat img_blur;
blur(image, img_blur, Size(5,5));
imshow("Original", image);
imshow("Blurred", img_blur);
imwrite("blur.jpg", img_blur);
waitKey();
destroyAllWindows();
OpenCV에서 이미지에 가우시안 블러링 적용
이제 OpenCV를 사용하여 이미지에 가우시안 블러를 적용해 보겠습니다. 이 기법은 가우시안 필터를 사용하는데, 이는 첫 번째 예제에서 설명한 균일 평균과 달리 가중 평균을 구하는 방식입니다. 이 경우, 가우시안 블러는 커널 중심에서의 거리를 기준으로 픽셀 값에 가중치를 부여합니다. 중심에서 멀리 떨어진 픽셀은 가중 평균에 미치는 영향이 적습니다. 다음 코드는 GaussianBlur() OpenCV의 함수를 사용하여 이미지를 컨볼루션합니다.
GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]])
이 GaussianBlur() 함수에는 4개의 입력 인수가 필요합니다.
- 첫 번째 인수는 src필터링할 소스 이미지를 지정합니다.
- 두 번째 인수는 ksize가우시안 커널의 크기를 정의하는 입니다. 여기서는 5×5 커널을 사용합니다.
- 마지막 두 인수는 와 sigmaX이며 sigmaY, 둘 다 0으로 설정됩니다. 이는 X(수평) 및 Y(수직) 방향의 가우시안 커널 표준 편차입니다. 의 기본 설정은 sigmaY0입니다. 를 0으로 설정하면 sigmaX표준 편차는 커널 크기(각각 너비와 높이)를 기준으로 계산됩니다. 각 인수의 크기를 0보다 큰 양수 값으로 명시적으로 설정할 수도 있습니다.
파이썬
"""
Apply Gaussian blur
"""
# sigmaX is Gaussian Kernel standard deviation
# ksize is kernel size
gaussian_blur = cv2.GaussianBlur(src=image, ksize=(5,5), \\
sigmaX=0, sigmaY=0)
cv2.imshow('Original', image)
cv2.imshow('Gaussian Blurred', gaussian_blur)
cv2.waitKey()
cv2.imwrite('gaussian_blur.jpg', gaussian_blur)
cv2.destroyAllWindows()
C++
// Performing Gaussian Blur
Mat gaussian_blur;
GaussianBlur(image, gaussian_blur, Size(5,5), SigmaX=0, SigmaY=0);
imshow("Original", image);
imshow("Gaussian Blurred", gaussian_blur);
imwrite("gaussian_blur.jpg", gaussian_blur);
waitKey();
destroyAllWindows();
결과는 아래 그림과 같습니다. 보시다시피, 오른쪽 필터링된 이미지에 약간의 흐릿함이 있습니다. 원본 이미지와 가우시안 블러를 적용한 후의 흐릿한 이미지입니다.

원본 이미지와 가우시안 블러를 적용한 후의 흐릿한 이미지입니다.
OpenCV에서 이미지에 중앙 흐림 효과 적용
OpenCV의 함수를 사용하여 중간값 블러링을 적용할 수도 있습니다 medianBlur() . 중간값 블러링에서는 소스 이미지의 각 픽셀을 커널 영역에 있는 이미지 픽셀들의 중간값으로 대체합니다.
medianBlur(src, ksize)
이 함수에는 두 개의 필수 인수만 있습니다.
- 첫 번째는 소스 이미지입니다.
- 두 번째는 커널 크기인데, 이는 홀수이고 양의 정수여야 합니다.
파이썬
"""
Apply Median blur
"""
# medianBlur() is used to apply Median blur to image
# ksize is the kernel size
median = cv2.medianBlur(src=image, ksize=5)
cv2.imshow('Original', image)
cv2.imshow('Median Blurred', median)
cv2.waitKey()
cv2.imwrite('median_blur.jpg', median)
cv2.destroyAllWindows()
C++
// Apply Median Blur
Mat median_blurred;
medianBlur(image, median_blurred, (5,5));
imshow("Original", image);
imshow("Median Blurred", median_blurred);
imwrite("median_blur.jpg", median_blurred);
waitKey();
destroyAllWindows();
아래 그림에서 중간값 블러링의 결과를 확인하세요. 동일한 커널 크기에서 중간값 블러링의 효과가 가우시안 블러링보다 더 두드러지는 것을 확인할 수 있습니다. 중간값 버링은 이미지에서 '소금 후추' 노이즈를 줄이는 데 자주 사용됩니다(그림 참조 ) .
원본 이미지와 중앙 흐림 효과를 적용한 흐릿한 이미지입니다.

원본 이미지와 중앙 흐림 효과를 적용한 흐릿한 이미지입니다. 중앙선 흐림 효과를 보여주는 결과 이미지
사용자 정의 2D 합성곱 커널을 사용하여 이미지 선명도 향상
2D 컨볼루션 커널을 사용하여 이미지를 선명하게 만들 수도 있습니다. 먼저 사용자 지정 2D 커널을 정의한 다음, 해당 filter2D() 함수를 사용하여 이미지에 컨볼루션 연산을 적용합니다.
아래 코드에서 3×3 커널은 선명화 커널을 정의합니다. 일반적으로 사용되는 커널 에 대해 자세히 알아보려면 이 자료를 참조하세요 .
파이썬
"""
Apply sharpening using kernel
"""
kernel3 = np.array([[0, -1, 0],
[-1, 5, -1],
[0, -1, 0]])
sharp_img = cv2.filter2D(src=image, ddepth=-1, kernel=kernel3)
cv2.imshow('Original', image)
cv2.imshow('Sharpened', sharp_img)
cv2.waitKey()
cv2.imwrite('sharp_image.jpg', sharp_img)
cv2.destroyAllWindows()
C++
// Apply sharpening using kernel
Mat sharp_img;
Mat kernel3 = (Mat_<double>(3,3) << 0, -1, 0,
-1, 5, -1,
0, -1, 0);
filter2D(image, sharp_img, -1 , kernel3, Point(-1, -1), 0, BORDER_DEFAULT);
imshow("Original", image);
imshow("Sharpenned", sharp_img);
imwrite("sharp_image.jpg", sharp_img);
waitKey();
destroyAllWindows();
그렇다면 어떤 결과가 나올까요? 아래 그림을 살펴보세요. 선명화 효과가 매우 인상적입니다. 오른쪽의 선명화된 이미지는 이전에는 보이지 않았던 나무의 균열을 보여줍니다.

원본 이미지와 선명해진 이미지. 사용자 정의 2D-Convolution 커널을 적용한 후 선명해진 효과
OpenCV에서 이미지에 양측 필터링 적용
블러링은 이미지의 노이즈를 줄이는 효과적인 방법이지만, 중요한 디테일과 선명한 가장자리가 손실될 수 있으므로 이미지 전체를 블러링하는 것은 바람직하지 않은 경우가 많습니다. 이러한 경우 블러링은 bilateral filtering작업을 더 쉽게 만들어 줄 수 있습니다.
- 이 기술은 필터를 선택적으로 적용하여 주변 픽셀의 유사한 강도를 흐리게 만듭니다. 가능한 한 선명한 가장자리가 유지됩니다.
- 필터의 공간적 크기뿐만 아니라, 주변 픽셀이 필터링된 출력에 포함되는 정도도 제어할 수 있습니다. 이는 주변 픽셀의 색상 강도 변화와 필터링된 픽셀과의 거리를 기반으로 결정됩니다.
양방향 필터링은 기본적으로 이미지에 2D 가우시안(가중치) 블러를 적용하는 동시에, 주변 픽셀의 강도 변화를 고려하여 가장자리 근처의 블러링(보존하고자 하는)을 최소화합니다. 즉, 커널의 모양은 모든 픽셀 위치에서 로컬 이미지 콘텐츠에 따라 달라집니다.
구체적인 예를 들어 보겠습니다. 이미지에서 경계선 근처의 영역을 필터링한다고 가정해 보겠습니다. 간단한 가우시안 블러 필터는 필터링된 영역 근처(가우시안 필터의 중심 근처)에 있는 경계선을 흐리게 처리합니다. 하지만 양방향 필터는 픽셀 강도 차이도 고려하기 때문에 경계선을 감지할 수 있습니다. 따라서 경계선에 걸쳐 있는 픽셀에 훨씬 낮은 가중치를 적용하여 필터링된 영역에 미치는 영향을 줄입니다. 강도가 더 균일한 영역은 강한 경계선과 연관되지 않으므로 더 강하게 블러 처리됩니다.
다행히도 OpenCV는 bilateralFilter()이미지를 필터링하는 기능을 제공합니다.
bilateralFilter(src, d, sigmaColor, sigmaSpace)
이 함수에는 4개의 필수 인수가 있습니다.
- 함수의 첫 번째 인수는 소스 이미지입니다.
- 다음 인수 d는 필터링에 사용되는 픽셀 근처의 직경을 정의합니다.
- 다음 두 가지 인수는 sigmaColor각각 sigmaSpace(1D) 색상 강도 분포와 (2D) 공간 분포의 표준 편차를 정의합니다.
- 매개 sigmaSpace변수는 커널의 공간적 범위를 x 및 y 방향 모두로 정의합니다(이전에 설명한 가우시안 블러 필터와 동일).
- 매개 sigmaColor변수는 픽셀 강도의 차이가 허용되는 정도를 지정하는 1차원 가우시안 분포를 정의합니다.
필터링된 이미지에서 픽셀의 최종 (가중치) 값은 공간 가중치와 강도 가중치의 곱입니다. 따라서,
- 필터링된 픽셀과 유사하고 가까운 픽셀은 영향을 받습니다.
- 필터링된 픽셀에서 멀리 떨어진 픽셀은 (공간 가우시안으로 인해) 영향을 거의 받지 않습니다.
- 커널의 중심에 가까우더라도 색상 강도 가우시안으로 인해 강도가 다른 픽셀은 영향을 거의 받지 않습니다.
파이썬
"""
Apply Bilateral Filtering
"""
# Using the function bilateralFilter() where d is diameter of each...
# ...pixel neighborhood that is used during filtering.
# sigmaColor is used to filter sigma in the color space.
# sigmaSpace is used to filter sigma in the coordinate space.
bilateral_filter = cv2.bilateralFilter(src=image, d=9, sigmaColor=75, sigmaSpace=75)
cv2.imshow('Original', image)
cv2.imshow('Bilateral Filtering', bilateral_filter)
cv2.waitKey(0)
cv2.imwrite('bilateral_filtering.jpg', bilateral_filter)
cv2.destroyAllWindows()
C++
// Apply bilateral filtering
Mat bilateral_filter;
bilateralFilter(image, bilateral_filter, 9, 75, 75);
imshow("Original", image);
imshow("Bilateral filtering", bilateral_filter);
imwrite("bilateral_filtering.jpg", bilateral_filter);
waitKey(0);
destroyAllWindows();
return 0;
아래 그림에서 양방향 필터링 결과를 확인해 보세요. 나무의 미세한 균열(모서리)은 그대로 유지하면서 픽셀 강도가 더 균일한 영역이 어떻게 매끄러워졌는지(흐려졌는지) 살펴보세요. 양방향 필터링은 매우 효과적인 기법이지만, (특히 커널 크기가 큰 경우) 계산량이 많을 수 있습니다. 따라서 특정 용도에 맞게 신중하게 선택하세요.
원본 이미지와 양측 필터링을 적용한 결과입니다.

양측 필터의 효과를 보여주는 결과 이미지
요약
먼저 컨볼루션 커널의 개념과 이미지를 필터링하는 데 사용하는 방법에 대해 알아보았습니다. 그런 다음 이미지의 각 픽셀에 수학적 연산을 수행하여 흐림이나 선명하게 하는 등 원하는 효과를 얻기 위해 어떻게 사용할 수 있는지 배웠습니다. OpenCV를 사용하여 2D 필터링을 구현하는 방법을 살펴봤습니다.
아이덴티티 커널을 이해한 후에는 OpenCV의 filter2D() 함수와 함께 사용할 수 있는 더 많은 커스텀 커널을 만들었습니다. MedianBlur() 및 GaussianBlur() 등 OpenCV에 내장된 몇 가지 중요한 필터링 함수를 살펴봤습니다. 마지막으로, 선명한 가장자리를 유지하면서 이미지를 매끄럽게 처리하는 OpenCV의 bilateralFilter()를 시연해 보았습니다.
'OpenCV' 카테고리의 다른 글
| OpenCV DNN 모듈을 활용한 딥 러닝: 완벽 가이드 (0) | 2025.09.12 |
|---|---|
| OpenCV 동영상 배경 단순 추정 C++, Python (1) | 2025.09.12 |
| OpenCV 윤곽선 탐지 Python, C++ (0) | 2025.09.11 |
| OpenCV GUI에서 마우스와 트랙바 (0) | 2025.09.11 |
| OpenCV 에지 검출 (0) | 2025.09.11 |
| OpenCV 블롭 탐지 Python, C++ (0) | 2025.09.10 |
| OpenCV 이미지 임계값 처리 Thresholding (0) | 2025.09.10 |
| OpenCV 색 공간 C++, Python (1) | 2025.09.10 |
취업, 창업의 막막함, 외주 관리, 제품 부재!
당신의 고민은 무엇입니까? 현실과 동떨어진 교육, 실패만 반복하는 외주 계약,
아이디어는 있지만 구현할 기술이 없는 막막함.
우리는 알고 있습니다. 문제의 원인은 '명확한 학습, 실전 경험과 신뢰할 수 있는 기술력의 부재'에서 시작됩니다.
이제 고민을 멈추고, 캐어랩을 만나세요!
코딩(펌웨어), 전자부품과 디지털 회로설계, PCB 설계 제작, 고객(시장/수출) 발굴과 마케팅 전략으로 당신을 지원합니다.
제품 설계의 고수는 성공이 만든 게 아니라 실패가 만듭니다. 아이디어를 양산 가능한 제품으로!
귀사의 제품을 만드세요. 교육과 개발 실적으로 신뢰할 수 있는 파트너를 확보하세요.
지난 30년 여정, 캐어랩이 얻은 모든 것을 함께 나누고 싶습니다.
귀사가 성공하기까지의 긴 고난의 시간을 캐어랩과 함께 하세요.
캐어랩