본문 바로가기
공부(연습문제 정답)/컴퓨터 비전과 딥러닝

[4장]컴퓨터 비전과 딥러닝 : 에지와 영역

by lovedeveloping 2024. 9. 19.
반응형

컴퓨터 비전과 딥러닝
컴퓨터 비전과 딥러닝

 

Chapter 04 에지와 영역

오늘은 4장 연습문제에 대해 작성해 보겠습니다.  여기선 아이디어 제시하거나 이유를 설명하라는 게 있는데, 몇몇 부분은 작성하지 않습니다. 참조 부탁드립니다! 그럼 바로 시작해 보겠습니다.

 

01 [그림 4-7] 영상의 아래 위치에서 f'y, f'x, s, d를 구하시오

 

1. (y, x) = (4, 4)
정답: 아래 표를 참고 부탁드립니다.

1 3 3 f'y :  -6
f'x : 6
s : 8.485
d : -45도
1 1 3
1 1 1

 

2.  (y, x) = (5, 2)
정답: 아래 표를 참고 부탁드립니다.

1 1 1 f'y :  0
f'x : 0
s : 0
d : 0
1 1 3
1 1 1

 

02 [그림 4-18] 영상에서 105 값을 가진 화소에 대해 LBP와 LTP를 [그림 4-18]처럼 제시하시오.

정답: 아래 표를 참고 부탁드립니다.

LBP 1 0 0 = 225 LTP 1 0 0 = 193
1   0 1   0
1 1 0 1 0 0

04 자연 영상에는 그림자가 만든 에지와 물체 경계가 만든 에지 등이 혼재되어 있다. 4.1~4.2절에서 소개한 에지 검출 알고리즘만으로 이들을 구분할 수 있는가? 예/아니오로 답하고, 그렇게 답한 이유를 설명하시오.

정답: 아니오 
이유: 앞에서 나온 지금까지 에지 검출은 모두 명암 변화에만 의존한다. 따라서 물체 경계에 나타난 에지와 그림자로 인해 발생한 가짜 에지를 구분하지 못한다. 또한 인접한 두 물체가 비슷한 명암을 가져 명암 변화가 적은 경우 경계에서 에지가 발생하지 않고, 사람은 에지를 검출할 때 명암 변화에만 의존하지 않는다. 물체의 모양을 표현한 3차원 모델과 눈에 비치는 2차원 겉모습 모델을 동시에 사용하기 때문이다.

05 [그림 4-1]은 자연 영상과 사람이 영역 분할하여 레이블링 한 결과를 보여준다. 사람에 따라 다르게 분할할 수 있는데, 버클리 팀에서는 이 문제를 어떻게 해결했는지 조사하시오.

정답:

1. 30명의 인간 피험자로부터 1,000개의 Corel 데이터 세트 이미지의 12,000개의 수작업 레이블 분할 수집

2. 분할의 절반은 피험자에게 컬러 이미지를 제시하여 얻었고, 나머지 절반은 회색조 이미지를 제시하여 얻었다.

또한 이미지의 하위 집합에 대한 그림-배경 레이블을 생성

(자세한 내용은 버클리 비전 프로젝트 )를 참고 부탁드립니다.

06 [프로그램 4-7] 40행에 있는 인수 5의 의미를 쓰시오. 5를 1로 바꾸면 프로그램 실행 결과가 어떻게 달라지는지 확인하고 이유를 설명하시오.

정답

- 5의 의미 : 5번 반복

- 5를 1로 바꾸면 반환하기 전에 알고리즘이 수행해야 하는 반환 횟수를 1로 바뀝니다.

07 OpenCV는 [그림 4-6]의 에지 연산자 이외에 Scharr 에지 연산자를 제공한다. Scharr 연산자에 대해 조사하시오. 
같은 영상에 Sobel 연산자를 착용하고 결과가 어떻게 다른지 비교 실험하시오.

정답 : 아래 내용을 참고해주세요.

Sobel : 연산자를 사용하여 첫 번째, 두 번째, 세 번째 또는 혼합 이미지 파생물을 계산

Scharr: 연산자를 사용하여 첫 번째 x 또는 y 이미지 차생물을 계산 ( 첫 번째 x 또는 두 번째 y 공간 이미지 파생물을 계산 )

08 OpenCV가 제공하는 Canny 함수의 선언을 보면, image, edges, threshold1, threshold2, apertureSize, L2 gradient, 총 6개의 매개변수가 있다. 각각의 의미를 쓰고, 뒤에 있는 네 매개변수를 변화시키면서 효과를 분석하시오.

정답: 아래 표를 참고해주세요.

image 8비트 입력 이미지
edges 출려 이미지 -> image와 크기 동일
threshold1 히스테리시스 절차의 첫번째 임계값
threshold2 히스테리시스 절차의 두번째 임계값
apertureSize 소벨연산자의 조리개 크기
L2gradient 기울기 크기에 대해 계산값을 사용할지 True or False를 사용
True: L2norm : G=Gx+Gy
False(기본 값): L1norm: G=Root(Gx2+Gy2​)

09 [프로그램 4-5]에서 compactness와 n-segments를 변화시키면서 효과를 분석하시오.

정답: 아래 코드를 참고해주세요.

import skimage
import numpy as np
import  cv2 as cv

img = skimage.data.coffee()
cv.imshow("Coffee image", cv.cvtColor(img,cv.COLOR_RGB2BGR))

slic1 = skimage.segmentation.slic(img,compactness=20, n_segments=600)
sp_img1 = skimage.segmentation.mark_boundaries(img,slic1)
sp_img1 = np.uint8(sp_img1*255.0)

slic2 = skimage.segmentation.slic(img,compactness=40, n_segments=300)
sp_img2 = skimage.segmentation.mark_boundaries(img, slic2)
sp_img2 = np.uint8(sp_img2*255.0)

cv.imshow("Super pixels(compact 20)", cv.cvtColor(sp_img1, cv.COLOR_RGB2BGR))
cv.imshow("Super pixels(compact 40)", cv.cvtColor(sp_img2, cv.COLOR_RGB2BGR))

cv.waitKey()
cv.destroyAllWindows()

10 [프로그램 4-7]은 사용자가 붓칠을 하면 그를 바탕으로 분할을 한 번 하고 종료한다. 마음에  들지 않으면 사용자가 추가로 붓칠을 하고 프로그램은 새로 붓칠 한 결과를 추가로 반영해 분할하는 일을 반복하도록 [프로그램 4-7]을 확장하시오.

정답: 아래 코드를 참고해주세요.

import cv2 as cv
import numpy as np

# Load the image
img_path = "soccer.jpg"
img = cv.imread(img_path)

# Check if the image was loaded successfully
if img is None:
    print(f"Error: Could not load image at {img_path}")
    exit()

# Create a copy of the image to display and for mask
img_show = np.copy(img)

# Create an initial mask with the probable background
mask = np.zeros((img.shape[0], img.shape[1]), np.uint8)
mask[:, :] = cv.GC_PR_BGD

BrushSiz = 9
LColor, RColor = (255, 0, 0), (0, 0, 255)

def painting(event, x, y, flags, param):
    if event == cv.EVENT_LBUTTONDOWN:
        cv.circle(img_show, (x, y), BrushSiz, LColor, -1)
        cv.circle(mask, (x, y), BrushSiz, cv.GC_FGD, -1)
    elif event == cv.EVENT_RBUTTONDOWN:
        cv.circle(img_show, (x, y), BrushSiz, RColor, -1)
        cv.circle(mask, (x, y), BrushSiz, cv.GC_BGD, -1)
    elif event == cv.EVENT_MOUSEMOVE and flags == cv.EVENT_FLAG_LBUTTON:
        cv.circle(img_show, (x, y), BrushSiz, LColor, -1)
        cv.circle(mask, (x, y), BrushSiz, cv.GC_FGD, -1)
    elif event == cv.EVENT_MOUSEMOVE and flags == cv.EVENT_FLAG_RBUTTON:
        cv.circle(img_show, (x, y), BrushSiz, RColor, -1)
        cv.circle(mask, (x, y), BrushSiz, cv.GC_BGD, -1)

    cv.imshow('Painting', img_show)

cv.namedWindow('Painting')
cv.setMouseCallback('Painting', painting)

# Display the initial image
cv.imshow('Painting', img_show)

while True:
    key = cv.waitKey(1)

    if key == ord('q'):
        # Exit the loop if 'q' is pressed
        break
    elif key == ord('r'):
        # Apply GrabCut when 'r' is pressed to refine the segmentation
        background = np.zeros((1, 65), np.float64)
        foreground = np.zeros((1, 65), np.float64)

        # Apply GrabCut algorithm with the updated mask
        cv.grabCut(img, mask, None, background, foreground, 5, cv.GC_INIT_WITH_MASK)
        mask2 = np.where((mask == cv.GC_BGD) | (mask == cv.GC_PR_BGD), 0, 1).astype('uint8')
        grab = img * mask2[:, :, np.newaxis]

        # Display the refined result
        cv.imshow('GrabCut Result', grab)

cv.destroyAllWindows()
반응형