RoBoLoG

[OpenCV] 로봇에 필요한 유용한 함수/기능 모음 본문

Study/Robot

[OpenCV] 로봇에 필요한 유용한 함수/기능 모음

SKJun 2024. 5. 17. 17:20

[OpenCV] 로봇에 필요한 유용한 함수/기능 모음


 

로봇이 카메라를 사용하여 상황을 인식할 수 있는 기능을 개발하는 데 있어 OpenCV는 다양한 유용한 도구와 알고리즘을 제공합니다. 아래는 로봇의 상황 인식에 도움이 될 수 있는 OpenCV 기능들입니다:

1. 객체 탐지 및 추적

  • Haar Cascades 및 HOG + SVM: 얼굴, 눈, 자동차 등의 객체 탐지에 유용합니다.
  • YOLO, SSD, Faster R-CNN: 딥러닝 기반 객체 탐지 알고리즘으로, 실시간으로 다양한 객체를 정확하게 탐지할 수 있습니다.
# YOLO 객체 탐지 예제
import cv2

net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")
layer_names = net.getLayerNames()
output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]

def detect_objects(image):
    height, width, channels = image.shape
    blob = cv2.dnn.blobFromImage(image, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
    net.setInput(blob)
    outs = net.forward(output_layers)
    
    class_ids, confidences, boxes = [], [], []
    for out in outs:
        for detection in out:
            scores = detection[5:]
            class_id = np.argmax(scores)
            confidence = scores[class_id]
            if confidence > 0.5:
                center_x = int(detection[0] * width)
                center_y = int(detection[1] * height)
                w = int(detection[2] * width)
                h = int(detection[3] * height)
                x = int(center_x - w / 2)
                y = int(center_y - h / 2)
                boxes.append([x, y, w, h])
                confidences.append(float(confidence))
                class_ids.append(class_id)
    return boxes, confidences, class_ids

 

2. 이미지 분할

  • GrabCut: 전경과 배경을 분리하는 데 사용됩니다.
  • Watershed Algorithm: 이미지 분할 및 객체 경계 검출에 유용합니다.
# GrabCut 예제
def segment_image(image):
    mask = np.zeros(image.shape[:2], np.uint8)
    bgd_model = np.zeros((1, 65), np.float64)
    fgd_model = np.zeros((1, 65), np.float64)
    rect = (50, 50, 450, 290)
    cv2.grabCut(image, mask, rect, bgd_model, fgd_model, 5, cv2.GC_INIT_WITH_RECT)
    mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
    image = image * mask2[:, :, np.newaxis]
    return image

 

3. 특징점 검출 및 매칭

  • SIFT, SURF, ORB: 특징점 검출 및 기술자 생성에 사용됩니다.
  • FLANN, BFMatcher: 특징점 매칭에 사용됩니다.
# ORB 특징점 검출 및 매칭 예제
def detect_and_match_features(image1, image2):
    orb = cv2.ORB_create()
    kp1, des1 = orb.detectAndCompute(image1, None)
    kp2, des2 = orb.detectAndCompute(image2, None)
    
    bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
    matches = bf.match(des1, des2)
    matches = sorted(matches, key=lambda x: x.distance)
    
    matched_image = cv2.drawMatches(image1, kp1, image2, kp2, matches[:10], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
    return matched_image

 

4. 이미지 안정화

  • Optical Flow: 객체의 움직임을 추적하거나 이미지 안정화에 사용됩니다.
  • Lucas-Kanade 방법: 실시간 객체 추적에 유용합니다.
# Optical Flow 예제
def track_motion(prev_frame, next_frame):
    prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
    next_gray = cv2.cvtColor(next_frame, cv2.COLOR_BGR2GRAY)
    
    p0 = cv2.goodFeaturesToTrack(prev_gray, mask=None, **feature_params)
    p1, st, err = cv2.calcOpticalFlowPyrLK(prev_gray, next_gray, p0, None, **lk_params)
    
    good_new = p1[st == 1]
    good_old = p0[st == 1]
    
    for i, (new, old) in enumerate(zip(good_new, good_old)):
        a, b = new.ravel()
        c, d = old.ravel()
        cv2.line(next_frame, (a, b), (c, d), (0, 255, 0), 2)
        cv2.circle(next_frame, (a, b), 5, (0, 255, 0), -1)
    
    return next_frame

 

5. 깊이 인식

  • Stereo Vision: 스테레오 카메라를 사용하여 깊이 맵을 생성합니다.
  • Depth Estimation: 단일 이미지에서 깊이를 추정합니다.
# 스테레오 비전 예제
def compute_depth_map(left_image, right_image):
    stereo = cv2.StereoBM_create(numDisparities=16, blockSize=15)
    disparity = stereo.compute(left_image, right_image)
    return disparity

 

6. 장면 이해 및 인식

  • Semantic Segmentation: 이미지 내의 각 픽셀을 클래스로 분류합니다.
  • Scene Classification: 전체 장면을 특정 카테고리로 분류합니다.

7. 경로 계획 및 지도 작성

  • SLAM (Simultaneous Localization and Mapping): 로봇이 환경의 지도를 작성하고 자신의 위치를 추정합니다. OpenCV는 ORB-SLAM, LSD-SLAM 등의 라이브러리와 함께 사용할 수 있습니다.

예제: ORB-SLAM2

  • ORB-SLAM2을 OpenCV와 함께 사용하는 예제입니다.
# ORB-SLAM2 설치 (https://github.com/raulmur/ORB_SLAM2)
git clone https://github.com/raulmur/ORB_SLAM2.git
cd ORB_SLAM2
chmod +x build.sh
./build.sh

 

8. 라인 및 원 검출

  • Hough Transform: 직선과 원을 검출합니다.
# Hough Line Transform 예제
def detect_lines(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(gray, 50, 150, apertureSize=3)
    lines = cv2.HoughLines(edges, 1, np.pi/180, 200)
    for line in lines:
        rho, theta = line[0]
        a = np.cos(theta)
        b = np.sin(theta)
        x0 = a * rho
        y0 = b * rho
        x1 = int(x0 + 1000 * (-b))
        x2 = int(x0 - 1000 * (-b))
        y1 = int(y0 + 1000 * (a))
        y2 = int(y0 - 1000 * (a))
        cv2.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2)
    return image

 

이와 같은 다양한 OpenCV 기능들을 활용하면 로봇이 상황을 인식하고, 실시간으로 주변 환경에 반응할 수 있습니다. 사용 사례에 맞는 기능들을 조합하여 로봇의 상황 인식 성능을 극대화할 수 있습니다.

728x90
반응형