Edge란 경계선, 윤곽선을 의미하며 영상처리에서는 밝기가 급격하게 변하는 부분을 말한다. 

 

픽셀 값이 급격하게 변하는 지점이 Edge부분이며 Edge를 검출함으로써 물체의 의치, 모양, 크기, 방향성 등에 대한 정보를 쉽게 찾을 수 있다.

 

픽셀은 곡선 그래프처럼 연속 공간에 있는 것이 아니기에 미분 근삿값으로 Edge을 찾을 수 있다. 이 말은 서로 붙어 있는 픽셀 값의 차를 구하면 된다는 것이다.

 

 

💡 Sobel Filter

Sobel이 고안해낸 가장자리 검출 알고리즘으로 3X3 크기의 행렬을 사용하여 연산하였을 때 중심을 기준으로 각 방향 값을 비교하여 픽셀 값의 변화량을 검출한다. 

 

X축 필터세로 성분을 검출하고 Y축 필터가로 성분을 검출한다.

 

대각선을 검출하는 Sobel filter는 다음과 같다.

Sobel Filter는 모든 방향의 Edge 추출이 가능하지만 대각선 방향 Edge에 더욱 민감하게 반응한다. 또한 돌출한 화소 값을 평균화하므로 잡음에 강하다.

 

 

 

원본 영상을 각각 Sobel 필터를 적용해서 Edge을 검출한 것이다. 위에서부터 오른쪽 방향으로 수직을 검출하는 X축 필터, 수평을 검출하는 Y축 필터, 각각 대각선을 검출하는 필터이다.

 

 

💡 Canny Edge

Edge 검출 알고리즘에서 가장 신뢰성이 높고 간편하여 보편화된 알고리즘이다. 도형의 윤곽을 하나의 선으로 얻을 수 있으며 이미지의 특징 추출을 위한 전처리로 많이 활용한다.

 

✌ Canny Edge Detection

1️⃣ 노이즈 제거 : 가우시안 필터 사용

 

2️⃣ Edge Gradient(기울기) 계산하여 Gradient값이 높은 부분을 찾기(=Sobel filter 사용)

함수의 점에서 미분을 하면 접선의 기울기가 나오며 기울기는 연속된 픽셀 값의 차이 즉 Edge가 된다.

따라서 함수의 그래프를 미분하는 방법은 모든 픽셀을 Sobel Filter로 Convolution 연산하는 것이다.

 

3️⃣ 최댓값이 아닌 픽셀의 값을 0으로 만들기

Edge에 기여도가 적은 픽셀을 제거하기 위해 이미지를 전체 스캔합니다. 이미지를 스캔하면서 기울기 방향으로 기울기 값이 최댓값을 가진 픽셀을 찾는다.

A는 수직 방향 위의 에지 위에 있는 픽셀이다. 기울기 방향을 수평이고 B와 C는 기울기 방향에 놓인 픽셀이다. A지점에서 기울기 값이 B, C보다 큰지 확인하며 A값이 크다면 넘어가고 아닐 경우 0으로 만들어 픽셀을 억제한다.

 

4️⃣ Hyteresis Thresholding

기울기 강도가 maxVal보다 크면 Edge, minVal보다 작으면 Edge가 아니라고 판단하여 제거한다.

 

A는 maxVal보다 위에 있으므로 확실한 에지이고 B는 A(확실한 에지)와 연결되어 있지 않으므로 제거한다. C는 A와 연결되어 있기에 A와 C만 남겨두고 B는 제거한다.

 

위의 알고리즘을 구현한 함수가 cv2.Canny() 함수이다.

 

cv2.Canny(img, minimum thresholding value, maximum thresholding value)

 

함수의 인자는 이미지와 minVal, maxVal만 설정하여주면 된다.

 

Sobel filter 적용 후
Canny Edge 적용 후

 

💡 허프변환

연결 관계가 명확하지 않거나 잡음으로 인해 작은 조각으로 끊어져 있는 경우가 많다. 따라서 허프 변환은 전체 공간을 조사해서 연결 과정 없이 바로 직선을 검출한다.

 

한 점이 가질 수 있는 직선은 많기에 기울기와 절편을 고정시킬 수 없다.

따라서 [a-b] 공간으로 바뀐다면 한 점이 가질 수 있는 모든 직선을 하나의 직선으로 표현할 수 있다.

 

그러나 이를 다시 [x-y] 공간으로 바꿀 시 a, b의 범위가 무한대가 될 수 있다. 영상에는 화소가 존재하는 디스플레이의 세로, 가로 범위가 유한하기에 영상에는 범위가 존재하여 무한대가 되면 안 된다. 그래서 범위가 유한한 변수들을 사용하여 공간을 변환해야 한다. 

[x-y] 공간에서 [θ-r] 공간으로 변환하는 것을 허프 공간으로의 변환이라고 한다. 즉 직선 위에 있는 점이 곡선으로 변한다. 

 

허프 변환의 OpenCV함수로는 cv2.HoughLines가 있다.

 

cv2.HoughLines(img, rho, theta, threshold, lines, srn=0, stn=0, min_theta, max_theta)

 

인수는 아래와 같다.

img: 입력 이미지, 1 채널 바이너리 스케일
rho: 거리 측정 해상도, 0~1
theta: 각도, 라디안 단위 (np.pi/0~180)
threshold: 직선으로 판단할 최소한의 동일 개수 (작은 값: 정확도 감소, 검출 개수 증가 / 큰 값: 정확도 증가, 검출 개수 감소)
lines: 검출 결과, N x 1 x 2 배열 (r, Θ)
srn, stn: 멀티 스케일 허프 변환에 사용, 선 검출에서는 사용 안 함
min_theta, max_theta: 검출을 위해 사용할 최대, 최소 각도

픽셀 처리는 단일 픽셀 처리픽셀 그룹 처리로 나눌 수 있다.

  의미 종류
단일 픽셀 처리 이웃 픽셀과는 독립적으로 입력 영상의 각 픽셀 값을 변환한 후 결과 영상의 동일한 위치에 출력하는 연산 산술연산, 논리연산, 그레이스케일, 고정 임계값으로 이진화
픽셀 그룹 처리 출력 영상의 새로운 픽셀 값을 결정 할 때 그 주위의 이웃 픽셀들도 함께 고려하는 공간 영역 연산, 컨볼루션 연산으로 처리 블러링 & 샤프닝, 가변 임계값으로 지역 이진화

 

👀 컨볼루션 연산 (Convolution, 합성곱)

처리하고 하는 픽셀 값을 이웃 픽셀과 각각에 대응하는 2차원 배열 내의 가중치(필터의 값)를 곱하여 곱한 값들을 모두 더한 값으로 변경하는 연산

 

필터 (Filter, Mask)

입력되는 신호의 일부 성분을 제거하거나 일부 특성을 변경하기 위해 설계된 하나의 시스템

 

✌ cv2.filter2D(src, ddepth, kernel)

컨볼루션 연산을 수행하는 함수로 src는 입력 영상, ddepth는 출력 영상의 데이터 타입으로 -1로 지정하면 입력 영상과 같은 데이터 타입으로 생성한다. kernel은 필터 행렬의 값이다.

 

 

👀 이진화

어떤 주어진 임계값(threshold) 보다 밝은 픽셀들을 모두 흰색으로 그렇지 않은 픽셀들은 모두 검은색으로 바꾸는 작업이다.

 

1️⃣ 전역 이진화

단일 픽셀 처리의 종류인 전역 이진화각 픽셀 값이 고정 임계값보다 작으면 0, 크면 255로 픽셀 값을 변경한다. 

 

✌ cv2.threshold(src, thresh, maxval, type)

전역 이진화 함수로써 src는 입력 영상, thresh는 임계값, maxval은 임계값보다 클 때 적용되는 최댓값, type은 임계값 적용 방법이다.

 

코드에서의 임계값은 127이고 maxval은 255, cv2.THRESH_BINARY은 픽셀 값이 thresh보다 크면 maxval, 작으면 0으로 할당하는 임계값 적용 방법이다.

 

전역 이진화는 임계값이 고정되어있다보니 밝기 변화가 심한 영상에는 임계값 설정이 어렵다.

 

2️⃣ 지역 이진화

전역 이진화의 단점을 개선하기 위해 가변 임계값을 사용하는 지역 이진화가 있다. 픽셀 그룹 단위마다 임계값을 설정하고 그 값보다 작으면 0, 크면 255로 픽셀 값을 변경한다.

 

✌ cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C)

지역 이진화 함수로써 src는 입력 영상, maxvalue는 임계값보다 클 때 적용되는 최댓값, adaptiveMethod는 적용할 지역 이진화 알고리즘, thesholdType은 임계값 적용 방법, blocksize는 지역 이진화를 할 때 고려할 주변 픽셀 크기 (블록 크기), C는 블록 내 평균값에서 뺄 값(임계값을 결정하는 파라미터)을 의미한다.

 

여기서 cv2.ADAPTIVE_THRESH_MEAN_C는 주변 영역의 평균값으로 지역 이진화를 하겠다는 것을 의미한다.

 

 

💡 블러링 (Blurring)

이웃 픽셀들의 차이를 감소시켜 영상을 부드럽게 만드는 기법으로 영상의 잡음(Noise)을 제거하기 위해 쓰인다.

블러링에 사용되는 필터로는 평균값 필터, 미디언 필터, 가우시안 필터가 있다.

 

1️⃣ 평균값 필터

영상의 특정 픽셀과 주변 픽셀등의 산술 평균을 결과 영상 픽셀 값으로 설정하는 필터로써 가장 간편하게 사용할 수 있는 블러링 방법이다. 필터의 크기가 커질수록 더 흐려진다.

 

1. 3 X 3 평균 값 필터 사용하기

2. 5 X 5 평균 값 필터 사용하기

 

5 X 5 평균값 필터를 사용할 시 더 흐려지는 것을 확인할 수 있다 ❗

 

2️⃣ 미디언 필터

입력 영상에서 주변 픽셀들의 값들을 오름 또는 내림차순으로 정렬하여 그 중앙에 있는 값으로 픽셀 값을 대체하는 방식의 필터로 소금 & 후추 잡음을 효과적으로 제거한다.

 

✌ cv2.medianBlur(src, ksize)

src는 입력 영상, ksize는 필터의 크기를 의미한다. 필터의 크기는 3,5,9를 가질 수 있다.

 

 

3️⃣ 가우시안 필터

가우시안 분포를 이용한 정규화 필터로써 모든 가우시안 필터의 합은 1이다. 빠른 처리가 가능하다.

 

3 X 3의 가우시안 필터와 5 X 5의 가우시안 필터를 적용하였다. 자세히 보면 크기가 5인 필터가 더 흐리다.

 

✌ cv2.getGaussianKernel(ksize, sigma, ktype)

가우시안 필터를 만들어주는 함수로써 ksize는 필터 크기, sigma는 가우시안 함수 식 중 시그마 값, ktype은 필터 타입을 의미하며 default 값은 float64이다. 

 

 

💡 샤프닝 (Sharpening)

이웃 픽셀들의 차이를 크게 만들어 영상을 날카롭게 만드는 기법이다.

 

총 3가지의 샤프닝 필터가 존재한다.

 

오른쪽으로 갈수록 더욱 샤프닝 된 사진이 출력되는 것을 확인할 수 있다.

OpenCV란 Open Source Computer Vision으로 실시간 컴퓨터 비전을 목적으로 한 프로그래밍 라이브러리이다.

 

흑백 이미지의 밝기 조절을 해보자 

 

👀 for문을 이용하여 밝기 조절

 

먼저 bright라는 0으로 초기화된 2차원 배열을 선언한다. 배열의 크기는 그레이 이미지의 가로 픽셀 수 X 세로 픽셀 수인 512 X 512 인 2차원 배열이다. 다음 그레이 이미지의 2차원 배열을 반복문으로 돌면서 배열의 값에 50을 더한 것이 255보다 크다면 배열의 값을 최대인 255로 설정하는 예외처리를 하였다. 그렇지 않다면 원래의 배열 값에 50을 더해 bright 배열 값에 저장한다. 

 

예외처리를 해야 하는 이유가 무엇일까 ❓

이미지의 결과값이 255 보타 큰 경우에 256으로 나눈 나머지 값을 사용하는 것이 Numpy 연산의 특징이기 때문이다. 이미지를 밝게 하려는 결과를 원했지만 오히려 이미지가 어두워질 수 있다. 예를 들어 150 + 150을 더하면 300 % 256을 할 경우 44로 픽셀 값이 오히려 더 어두워진다.

 

 

하지만 예외처리를 하여도 픽셀값에 50을 더한 것은 하얗게만 나오고 어둡게 한 것도 그림이 많이 날아갔다. 우리가 원하는 결과가 안 나온 이유는 화소 값에 8-bit unsingned 값이 들어가지 않고 float(실수) 값이 들어갔기 때문이다. 실수 값이 들어간 이유는 np.zeros()의 data-type의 디폴트값이 float64이기 때문이다.

 

 

np.zeros함수를 사용하여 0으로 초기화한 bright 배열에 데이터 타입이 float형인 것을 확인할 수 있다. 따라서 이를 정수로 바꿔주어야 한다. 

 

1️⃣ 데이터 타입을 8 비트 부호없는 정수형으로 지정해 줄 경우 해결

 

2️⃣ cv.imshow 함수를 사용할 때 처리

 

Winname : 창이름, mat : 이미지 배열

 

이때 mat의 data type에 따라 처리하여 주면 된다.

현재의 이미지는 64비트의 float형이므로 배열을 255로 나눈다.

 

✌ 그레이 이미지 밝기 조절 성공

 

👀 cv.add 모듈 사용

 

add 모듈을 사용하면 화솟값이 255가 넘어갈 경우 알아서 255로 지정해주기 때문에 예외처리를 할 필요가 없이 간단히 그레이 이미지 밝기 조절이 가능하다.

영상이란 2차원 평면 위에 그려진 시각적 표현물을 말하며 사진과 동영상을 모두 포함하는 개념이다.

 

디지털 영상은 2차원 평면위에 화소들의 집합으로 이루어진 영상을 말한다.

 

그러면 화소란 무엇일까 ❓

 

영상을 구성하는 가장 기본적인 단위로써 Pixel이라 불린다. 

 

가로축 픽셀 수 X 세로축 픽셀 수해상도를 나타내며 숫자가 높을수록 해상도는 선명하며 낮을수록 해상도는 떨어진다.

 

 

예를 들어 256 X 256 과 64 X 64의 해상도가 있다면 256 X 256이 해상도가 더 높다.

 

화소는 화솟값을 가지며 화소의 명암이나 색을 나타내는 정수 이어야 한다. 

 

색공간이란 색 체계를 3차원 공간으로 표현한 개념으로 컴퓨터는 빛의 3원 색인 RGB를 사용하여 밝기 정도를 수치화하고 RGB 각각 0~255의 값을 가진다. 

 

✌ 컬러 이미지라면 하나의 픽셀에 Red, Green, Blue의 값이 각각 들어가 있는 것으로 이를 3 Channel이라 부르며 코드에서 표현할 경우 3차원 배열로 표현된다. 

 

3D matrix로 표현할 시 Img[세로축][가로축][채널]

 

ex) img [640][480][3]

img [640][480][0] - Blue의 화소 값들만 추출

img [640][480][1] - Green의 화소 값들만 추출

img [640][480][2] - Red의 화소 값들만 추출

 

✌ 흑백 이미지라면 하나의 픽셀에는 색이 없으므로 RGB가 없고 명암을 나타내는 0~255의 값이 들어가고 1 Channel이다. 

 

2D matrix로 표현할 시 Img [세로축][가로축]

 

ex) img [640][480]

 

컬러 이미지에서 3 Channel 화소 값이 모두 0일 경우 검은색

 

컬러 이미지에서 3 Channel 화소 값이 모두 255일 경우 하얀색

즉, 3채널 컬러 이미지화소값이 각 채널의 색상값을 나타내고 1채널 그레이 이미지픽셀값이 밝기를 나타낸다.

+ Recent posts