* Receptive Field은 filter가 한번에 볼 수 있는 입력의 Spatial area이다, filter size와 동일한 의미
Convolution
- 미리 정해져있는 컨볼루션 커널이 이미지의 각 픽셀들과 곱해지면서 컨볼루션 아웃풋을 만들어내는 연산
- 인풋 이미지의 선형적 연산이라고도 함
- 교환법칙, 결합법칙, 분배법칙 성립
스무딩: 노이즈 줄일 수 있음
패딩: 이미지 필터링에서 바운더리 이펙트를 없애기 위해 주로 사용하게 되는 것
Edge and Corner
엣지는 점들의 집합, 픽셀의 강도가 갑자기 변하는 부분
텍스처, 뎁스의 차이, 방향성이 달라질때, 조도 등으로 엣지가 만들어짐
Edge Detection Process

smoothing > Gradient magnitude > Non-max suppression(맥스 아닌 값들 0치환) & thresholding
소벨 엣지
- 이미지에서 밝기 값의 변화를 감지하여 엣지를 찾는데 사용
- 소벨 필터는 이미지의 각 픽셀에 대해 주변 픽셀과의 밝기 차이를 계산하고 이를 기반으로 픽셀의 엣지 강도와 방향을 계산

https://m.blog.naver.com/roboholic84/220482877717
라플라시안 엣지
- 이미지의 밝기나 픽셀 값의 변화를 분석하여 이미지에서 엣지 부분을 감지
- 이미지에서 높은 공간 주파수를 가지는 부분을 강조할 때 사용
- 라플라시안은 이미지의 두 번 미분을 해서 주변 픽셀 간의 밝기 변화를 감지함
케니 엣지
- 소벨 마스크를 이용해 이미지의 그레디언트를 계산한 후 그레디언트의 크기와 방향을 모두 고려해 변환한 엣지 위치를 찾음
- 또한 엣지는 서로 연결되어 있는 가능성이 높다는 점을 고려해 그레디언트 크기가 작게 나오는 엣지도 놓지지않음
import cv2
import os
from matplotlib import pyplot as plt
import numpy as np
import torch
import torchvision
import kornia as K
def image_read(path):
image = cv2.imread(path,cv2.IMREAD_COLOR)
# image = np.rot90(image, 3)
image = K.utils.image_to_tensor(image)
image = image[None,...].float() / 255.
x_rgb: torch.Tensor = K.color.bgr_to_rgb(image)
gray_image = K.color.rgb_to_grayscale(x_rgb)
return gray_image
def imshow(input: torch.Tensor):
out = torchvision.utils.make_grid(input, nrow=2, padding=5)
out_np: np.ndarray = K.utils.tensor_to_image(out)
plt.imshow(out_np)
plt.axis('off')
plt.show()
image_1 = image_read('C:/Users/kimhyesu/Desktop/dog.jpeg')
# sobel
x_sobel: torch.Tensor = K.filters.sobel(image_1)
imshow(1. - x_sobel)
# laplacian
x_laplacian: torch.Tensor = K.filters.laplacian(image_1, kernel_size=5)
imshow(1. - x_laplacian.clamp(0., 1.))
# canny edges
x_canny: torch.Tensor = K.filters.canny(image_1)[0]
imshow(1. - x_laplacian.clamp(0., 1.))

sobel filter

laplacian filter

canny filter

corners
- 이미지의 특정 영역들이 변화하는 부분, 엣지들이 만나는 부분
해리스 코너 디텍션

- 코너는 모든 방향으로 큰 변화가 있는 것, 엣지는 엣지방향을 따라 변화가 없는 것, 플랫 리젼은 오든 방향에서 변화가 없는 것
- 헤리스 코너 검출은 이미지 내에서 각 점이 주변 영역과 얼마나 다른지를 측정하여 "코너"로 간주되는 지점을 찾는 알고리즘
- 이미지의 각 픽셀 위치에서 특정 윈도우의 크기의 작은 영역을 추출하고 이 작은 영역의 강도 변화를 계산합니다.
(변화가 의미하는 건 해당 위치에서 경사도 또는 엣지 정보를 나타냄) 그래서 헤리스 코너 검출은 이러한 강도 변화 정보를 이용해서 각 위치에서의 코너 정도를 계산하고 코너 정도가 높은 지점을 "코너"라고 판단

import os
import numpy as np
import cv2
import matplotlib.pyplot as plt
image_1 = cv2.imread('C:/Users/kimhyesu/Desktop/ddog.png')
gray = cv2.cvtColor(image_1, cv2.COLOR_BGR2GRAY)
gray = np.float32(gray)
dst1 = cv2.cornerHarris(gray, 2, 3, 0.04)
dst = cv2.dilate(dst1, None)
image_1[dst>0.01*dst.max()]=[0,0,255]
dst1일때

dst일때


본 강의에서는 cv와 kornia 예시 두가지를 다 보여줬음
import os
import numpy as np
import cv2
import matplotlib.pyplot as plt
import torch
from torchvision import transforms
import kornia.feature as KF
from PIL import Image
def cv_harris_corner_det(path, show=False):
img = cv2.imread(path)
img1 = img.copy()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.float32(gray)
dst1 = cv2.cornerHarris(gray, 2, 3, 0.04)
dst = cv2.dilate(dst1, None)
img1[dst>0.01*dst.max()]=[0,0,255]
if show == True:
plt.figure(figsize=(15,8))
plt.imshow(img1[:,:,::-1])
plt.show()
def kornia_harris_corner_det(path, show=False):
tensor = transforms.ToTensor()(Image.open(path).convert('L')).unsqueeze(0)
harris = KF.responses.CornerHarris(0.05)
cornerness = harris(tensor)
if show == True:
plt.imshow(cornerness.squeeze(), cmap='gray')
plt.show()
path = 'C:/Users/kimhyesu/Desktop/ddog.png'
cv_harris_corner_det(path, show=True)
kornia_harris_corner_det(path, show=True)
blob detection
* 한번더 복습하기
- 블랍이란 image region인데 주변보다 밝거나 더 어두운 영역에 대해서 BLOB이라고 함
- 블랍 디텍션은 이미지에서 객체나 물체의 형태를 나타내는 덩어리나 덩어리로 이루어진 영역을 검출하는 작업
- 이미지 내에서 연결된 픽셀 그룹으로 나타나고 주로 물체나 객체의 경계를 나타내거나 특정한 패턴 또는 특징을 가진 부분을 나타냄
- 과정: 이미지 스무딩 > 라플라시안, 디퍼런스 of 가우시안 연산 적용 > 최적의 스케일, 파라미터 찾음

- 엣지 디텍션은 가우시안을 쓰는데 블랍에서는 가우시안 필터에서 라플라시안 오퍼레이터를 적용시켜 만들어진 필터를 쭉 통과 시켜서 응답이 제일 큰 위치를 근처로 특정한 리전을 BLOB이라고 말함

- 라플라시안 오퍼레이터는 두 개의 그래디언트 벡터 오퍼레이터의 이너 프로덕트

SIFT(scale invariant feature transform)

- 이미지의 크기와 회전에 불변하는 특징을 추출하는 알고리즘
- 서로 다른 두 이미지에서 sift 특징을 각각 추출한 다음에 서로 가장 비슷한 특징끼리 매칭해주면 두 이미지에서 대응되는 부분을 찾을 수 있다는 것
- 과정: scale space 만들기 > Difference of Gaussian(DOG)연산 > keypoint들 찾기 > 나쁜 Keypoint들 제거 > keypoint들에 방향 할당해주기 > sift 특징들 산출하기
관련 블로그 링크: https://bskyvision.com/entry/SIFT-Scale-Invariant-Feature-Transform%EC%9D%98-%EC%9B%90%EB%A6%AC
import os
import cv2
import numpy as np
def img_read(path):
image = cv2.imread(path)
image = np.rot90(image, 3)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
return gray
def sift(gray_img1, gray_img2):
detector = cv2.SIFT_create()
kp1, desc1 = detector.detectAndCompute(gray_img1, None)
kp2, desc2 = detector.detectAndCompute(gray_img2, None)
matcher = cv2.BFMatcher(cv2.NORM_L1, crossCheck=True)
matches = matcher.match(desc1, desc2)
return kp1, kp2, matches
path = 'C:/Users/kimhyesu/Desktop/images_check/images_check/grande/Cup_type/'
image_1 = img_read(os.path.join(path, '300_grande_11.png'))
image_2 = img_read(os.path.join(path,'300_grande_12.png'))
kp1, kp2, matches = sift(image_1,image_2)
res = cv2.drawMatches(image_1, kp1, image_2, kp2, matches, None,flags=cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS)
cv2.imshow('BFMatcher + SIFT', res)
cv2.waitKey()
cv2.destroyAllWindows()

생각보다 코너를 잘 찾지 못하는 아쉬움이 있음
import os
import cv2
import numpy as np
def img_read(path):
image = cv2.imread(path)
image = np.rot90(image, 3)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
return gray
def canny(image):
canny_img = cv2.Canny(image, 0, 50)
return canny_img
def sift(gray_img1, gray_img2):
detector = cv2.SIFT_create()
kp1, desc1 = detector.detectAndCompute(gray_img1, None)
kp2, desc2 = detector.detectAndCompute(gray_img2, None)
matcher = cv2.BFMatcher(cv2.NORM_L1, crossCheck=True)
matches = matcher.match(desc1, desc2)
matches = sorted(matches, key=lambda x:x.distance)[:20]
return kp1, kp2, matches
path = 'C:/Users/kimhyesu/Desktop/images_check/images_check/grande/Cup_type/'
image_1 = img_read(os.path.join(path, '300_grande_11.png'))
image_2 = img_read(os.path.join(path,'300_grande_12.png'))
image_c1 = canny(image_1)
image_c2 = canny(image_2)
kp1, kp2, matches = sift(image_c1, image_c2)
res = cv2.drawMatches(image_1, kp1, image_2, kp2, matches, None,flags=cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS)
cv2.imshow('BFMatcher + SIFT', res)
cv2.waitKey()
cv2.destroyAllWindows()

훨씬더 좋은지는 모르겠지만 그래도 조금은 나아진듯하다
Ransac
- 컴퓨터 비전의 모델 피팅 방법 중 하나
- random sample consensus의 약어로 이상치를 제거하고 모델을 추정하는데 사용되는 통계적인 방법
- 가장 많은 수의 데이터들로부터 지지를 받는 모델을 선택하는 방법
- 많은 이상치가 있는 경우나 모델 추정 시간을 줄일 수 있음
- 과정: 랜덤으로 작은 세트의 데이터 포인트 선택 > 그 세트에 모델을 핏함 > 모두 유지되는 데이터 포인트들을 찾음(아웃라이어는 빼고 모델에 가장 가까운애들만 찾음) > 여러번 돌리고 베스트 모델을 택함
관련 블로그 링크: https://darkpgmr.tistory.com/61
*몰랐는데 객체 추적 라벨링 프로그램인 다크라벨 만드신 분이였음,,신기해라..!
Hough Transform
- 파라미터 스페이스에서 보팅을 통해서 이미지 스페이스에서의 어떤 선분 또는 수식 모델을 찾는다고 했을때
- 허그 공간으로 변환을 하여 교차점으로부터 공통된 직선을 찾아내는 것
- 이미지에서 모양(직선)을 찾는 유명한 방법(서로 직선 관계를 갖는 픽셀들만 골라내는 것이 핵심
- 자율주행차에서 도로의 차선을 검출할 때 쓰는 알고리즘으로 도로의 차선(직선)을 받아서 그 정보를 사용할 수 있게 함
관련 블로그 링크: https://velog.io/@gnoeyhad/Open-CV-%ED%97%88%ED%94%84-%EB%B3%80%ED%99%98-Hough-Transform
fitting and matching
- matching: False positive를 잘 제거하는 아웃라이어 필터링 기법
- fitting: 모델을 다시 찾는 것
'Study 공부할레나' 카테고리의 다른 글
| [컴퓨터비전 정주행 Kit] Part2 ch04 표현학습 (2) | 2024.01.27 |
|---|---|
| [컴퓨터비전 정주행 Kit] Part2 ch03 (0) | 2023.12.23 |
| [컴퓨터비전 정주행 Kit] Part2 ch01 (0) | 2023.12.16 |
| [컴퓨터비전 정주행 Kit] Part1 ch1 (1) | 2023.12.09 |
| [스터디/밑시딥3] 제 4고지 신경망 만들기_47. 소프트맥스 함수와 교차 엔트로피 오차 (0) | 2023.10.16 |