본문 바로가기

Programming/ROS

WSL2에서 OpenCV로 웹캠 스트리밍 하는 방법

출처 : https://blog.naver.com/112fkdldjs/223427966518

 

WSL에서 OpenCV로 웹캠 스트리밍 하는 간단한 방법(Build 없음)

서론 WSL에 아나콘다 환경 등을 만들어놓고, OpenCV로 웹캠을 실시간 스트리밍 하여 무언가를 하고 ...

blog.naver.com

 

 

IP 설정 부분은 WSL에서 ROS2 구성하면서 이미 맞춰두었다. 
나는 Windows의 IP가 192.168.32.1이고 netmask  255.255.240.0 이다.
WSL쪽의 IP는 192.168.47.137  netmask 255.255.240.0 

widnwos 쪽 python Code (출처 블로그에서 사용한 코드가 아니라 인공지능으로 생성한 코드이다. )

app.py

from flask import Flask, render_template, Response
import cv2

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

def gen_frames():
    cap = cv2.VideoCapture(0)
    while True:
        ret, frame = cap.read()
        if not ret:
            break
        cv2.imshow('frame', frame)
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + cv2.imencode('.jpg', frame)[1].tobytes() + b'\r\n')

@app.route('/video_feed')
def video_feed():
    return Response(gen_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')

if __name__ == '__main__':
    app.run(host='192.168.32.1', port=5000, debug=True) # WSL과 연결되는 IP를 설정한다.

 

app.py 파일과 같은 위치에 templates 폴더를 하나 만들고 그 폴더 안에 index.html 파일을 다음과 같이 생성 한다. 
index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Live Camera Feed</title>
</head>
<body>
    <h1>Live Camera Feed</h1>
    <img src="{{ url_for('video_feed') }}" width="640" height="480">
</body>
</html>

Windows에서 app.py 파일을 실행 시키고 웹싸이트 http://192.168.32.1:5000 로 접속하면 영상이 보인다. 

 

WSL쪽에서 작성한 python code (인공지능이 생성한 코드이다.)

camera_test.py

import cv2


# 웹캠에서 비디오 캡처 객체를 생성합니다.
url = 'http://192.168.32.1:5000/video_feed'
cap = cv2.VideoCapture(url)

if not cap.isOpened(): 
    print("비디오 스트림을 열 수 없습니다.") 
    exit()

# 비디오 스트림을 반복적으로 처리합니다.
while True:
    # 현재 프레임을 캡처합니다.
    ret, frame = cap.read()

    # 프레임이 제대로 캡처되었는지 확인합니다.
    if not ret:
        print("Failed to grab frame")
        #break

    # 캡처된 프레임을 윈도우에 표시합니다.
    cv2.imshow('Webcam Stream', frame)

    # 'q' 키를 누르면 반복문에서 빠져나옵니다.
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break


# 사용이 끝난 자원을 해제합니다.
cap.release()
cv2.destroyAllWindows()

실행 : python3 camera_test.py 

ROS2를 설치히면서 XLanuch 를 설치했기 때문에 위와같이 XLaunch를 이용하여 영상이 출력되는것을 볼 수 있다. 

 

ROS2에서 위 영상을 스트리밍하여 topic으로 뿌리는 테스트 코드

cv_bridge 설치

sudo apt update
sudo apt install ros-<distro>-cv-bridge
sudo apt install ros-<distro>-image-transport

 

video_subscriber.py (인공지능이 생성한 코드)

import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
import cv2

class VideoSubscriber(Node):
    def __init__(self):
        super().__init__('video_subscriber')
        self.subscription = self.create_subscription(
            Image,
            'video_frames',
            self.listener_callback,
            10)
        self.bridge = CvBridge()

    def listener_callback(self, msg):
        cv_image = self.bridge.imgmsg_to_cv2(msg, "bgr8")
        cv2.imshow("Video Feed", cv_image)
        cv2.waitKey(1)

def main(args=None):
    rclpy.init(args=args)
    node = VideoSubscriber()

    cap = cv2.VideoCapture("http://192.168.32.1:5000/video_feed")
    if not cap.isOpened():
        print("비디오 스트림을 열 수 없습니다.")
        return

    while rclpy.ok():
        ret, frame = cap.read()
        if not ret:
            print("프레임을 읽을 수 없습니다.")
            break
        
        msg = node.bridge.cv2_to_imgmsg(frame, "bgr8")
        node.get_logger().info('Publishing video frame')
        node.subscription.publish(msg)

        rclpy.spin_once(node, timeout_sec=0.01)

    node.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

 

RQt에서 확인 

 

'Programming > ROS' 카테고리의 다른 글

ROS2 Windows 설치  (0) 2024.12.24
VSCode Font 변경 방법  (0) 2024.11.27
로보틱스 개발자가 되기 위한 학습 경로  (0) 2024.11.19
Windows WSL2에 ROS2 설치하기  (0) 2024.11.14