본문 바로가기
Robot/ROS

킴 [OpenCV]

by 9루트 2022. 3. 10.

 

http://wiki.ros.org/usb_cam

 

usb_cam - ROS Wiki

kinetic melodic noetic   Show EOL distros:  EOL distros:   electric fuerte groovy hydro indigo jade lunar diamondback: Only showing information from the released package extracted on Unknown. No API documentation available. Please see this page for in

wiki.ros.org

 

먼저, openCV의 버전을 확인해보자

kw-cobot@kwcobot-HGDT-Series:~$ pkg-config --modversion opencv
3.2.0

 

 

kw-cobot@kwcobot-HGDT-Series:~$ python

을 통해 파이썬으로 들어와주고

>>> import cv2
>>> cv2.__version__
'3.2.0'

 ctrl + D를 누르면 python을 나오게 된다.고

kw-cobot@kwcobot-HGDT-Series:~$ python -m pip install opencv-python==4.1.1.26

4.1.1 버전을 위 명령어로 설치해주면

4.1.1이 뜬다.

>>> cv2.__version__
'4.1.1'

 

어떤 버전을 설치할 수 있는지 한번 봐보자

kw-cobot@kwcobot-HGDT-Series:~$ python -m pip install opencv-python==dsffsaf
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
Defaulting to user installation because normal site-packages is not writeable
ERROR: Could not find a version that satisfies the requirement opencv-python==dsffsaf (from versions: 3.1.0.0, 3.1.0.5, 3.2.0.6, 3.2.0.7, 3.2.0.8, 3.3.0.9, 3.3.0.10, 3.3.1.11, 3.4.0.12, 3.4.0.14, 3.4.1.15, 3.4.2.16, 3.4.2.17, 3.4.3.18, 3.4.4.19, 3.4.5.20, 3.4.6.27, 3.4.7.28, 3.4.8.29, 3.4.9.31, 3.4.10.37, 4.0.0.21, 4.0.1.23, 4.0.1.24, 4.1.0.25, 4.1.1.26, 4.1.2.30, 4.2.0.32, 4.3.0.38)
3.1.0.0, 3.1.0.5, 3.2.0.6, 3.2.0.7, 3.2.0.8, 3.3.0.9, 3.3.0.10, 3.3.1.11, 3.4.0.12, 3.4.0.14, 3.4.1.15, 3.4.2.16, 3.4.2.17, 3.4.3.18, 3.4.4.19, 3.4.5.20, 3.4.6.27, 3.4.7.28, 3.4.8.29, 3.4.9.31, 3.4.10.37, 4.0.0.21, 4.0.1.23, 4.0.1.24, 4.1.0.25, 4.1.1.26, 4.1.2.30, 4.2.0.32, 4.3.0.38)

 

 

카메라가 없는 관계로 시뮬레이터로 카메라를 켜보자.

kw-cobot@kwcobot-HGDT-Series:~$ roslaunch scout_sim_launch simulater.launch 

와 함께 시뮬레이터를 켜준다.

527]: Client connected.  7 clients total.

가 나오도록 한다.

 

 

 

kw-cobot@kwcobot-HGDT-Series:~$ rqt_image_view 

를 켜면

카메라 화면이 정상적으로 뜨게 만든다.

 

 

새로운 패키지를 만들고 환경을 설정해준다.

kw-cobot@kwcobot-HGDT-Series:~/catkin_ws/src$ catkin_create_pkg opencv_sim rospy
Created file opencv_sim/package.xml
Created file opencv_sim/CMakeLists.txt
Created folder opencv_sim/src
Successfully created files in /home/kw-cobot/catkin_ws/src/opencv_sim. Please adjust the values in package.xml.

 

kw-cobot@kwcobot-HGDT-Series:~/catkin_ws/src/opencv_sim$ mkdir -p opencv_sim/scripts
kw-cobot@kwcobot-HGDT-Series:~/catkin_ws/src/opencv_sim$ cd opencv_sim/scripts/
kw-cobot@kwcobot-HGDT-Series:~/catkin_ws/src/opencv_sim/opencv_sim/scripts$ 

 


파일 만들고 실행권한을 준다.

kw-cobot@kwcobot-HGDT-Series:~/catkin_ws/src/opencv_sim/opencv_sim/scripts$ subl cv_example1.py
kw-cobot@kwcobot-HGDT-Series:~/catkin_ws/src/opencv_sim/opencv_sim/scripts$ chmod +x cv_example1.py 

 

코드를 작성한다.

 

 

kw-cobot@kwcobot-HGDT-Series:~$ rostopic list
/Object_topic
/client_count
/cmd_vel
/connected_clients
/image_jpeg/compressed
/imu
/lidar2D
/rosout
/rosout_agg
/rqt_gui_cpp_node_21324/compressed/parameter_descriptions
/rqt_gui_cpp_node_21324/compressed/parameter_updates
/scout_light_control
/scout_status
/tf

중에서

/image_jpeg/compressed 를 import 해주어야 한다.

 

 

http://docs.ros.org/en/lunar/api/cv_bridge/html/python/index.html

 

cv_bridge — cv_bridge 0.1.0 documentation

cv_bridge cv_bridge contains a single class CvBridge that converts ROS Image messages to OpenCV images. class cv_bridge.CvBridge The CvBridge is an object that converts between OpenCV Images and ROS Image messages. >>> import cv2 >>> import numpy as np >>>

docs.ros.org

참고

 

 

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import rospy
from sensor_msgs.msg import CompressedImage
from cv_bridge import CvBridge

import cv2

class ImageSubscriber(object):
	def __init__(self):
		rospy.Subscriber("/image_jpeg/compressed", CompressedImage, self.compressed_image_callback)
		self.Bridge = CvBridge()
	# ===========================================
	#              CALLBACK FUNCTION
	# ===========================================
	def compressed_image_callback(self, image):
		frame = self.Bridge.compressed_imgmsg_to_cv2(image)
		cv2.imshow("frame", frame)
		cv2.waitKey(1) # 반드시 waitkey로 1msec 정도를 걸어주어야 알맞게 나온다.


def run():
	rospy.init_node("ImageSubscriber")
	ImageSubscriber()
	rospy.spin()

if __name__== "__main__":
	run()

catkin build를 한 후에

source devel/setup.bash

 

 

kw-cobot@kwcobot-HGDT-Series:~/catkin_ws$ rosrun opencv_sim cv_example1.py 

를 하면

화면이 나온다.

 

왜 compressed에서 cv2로 바꿔줌

ros내 이미지 타입과 opencv는 cv2 타입을 쓰므로 다르다.

image: 
<class 'sensor_msgs.msg._CompressedImage.CompressedImage'>
frame: 
<type 'numpy.ndarray'>

이런 식으로 변환이 가능하다.

frame에 openCV에 사용하는 Image Type로 변환이 되었다.

이후,

frame 변수에 영상 처리를 진행하면 된다.

 

 

1. 그림 그리기

 

1. 선 그리기

cv2.line은 영상 위에 선을 그리는 함수

(그림 그릴 이미지, 시작점, 끝나는 점, 색깔(B, G, R), 두께)

 

FRAME = 640(가로) X 480 IMAGE이므로 (0,0)에서 (400,400)으로 파란선이 그려진다.

이미지는 왼쪽 위가 원점이고 Y축은 아래로 갈수록 커지는 구조이다.

		frame = cv2.line(frame, (0,0), (400,400), (255,0,0), 5)

 

2. 사각형 그리기

cv2.rectangle은 영상 위에 사각형을 그리는 함수

(그림 그릴 이미지, 좌측 상단점, 우측 하단점, 색깔(B, G, R), 두께)

끝 부분에  -1을 쓰면 안이 채워진다.

		frame = cv2.rectangle(frame, (384,0), (510,128), (0,225,0), -1)

 

3. 원 그리기

cv2.circle은 영상 위에 원을 그리는 함수

(그림 그릴 이미지, 중심점, 반지름, 색깔(B, G, R), 두께)

		frame = cv2.circle(frame, (447,63), 63,(0,255,225), -1)

 

		frame = cv2.line(frame, (0,0), (400,400), (255,0,0), 5)
		## 사각형 그리기
		frame = cv2.rectangle(frame, (384,0), (510,128), (0,225,0), -1)
		frame = cv2.circle(frame, (447,63), 63,(0,255,225), -1)

로 하면

으로 원과 사각형 모두 안이 채워지게 나온다.

 

 

		frame = cv2.line(frame, (0,0), (400,400), (255,0,0), 5)
		## 사각형 그리기
		frame = cv2.rectangle(frame, (384,0), (510,128), (0,225,0), 5, -1)
		## 원 그리기 
		frame = cv2.circle(frame, (447,63), 63,(0,255,225), 5, -1)

이면

두께 항목이 안을 채울지의 항목을 덮어버린다.

따라서 안은 안 채워지고 두께만 5인 원과 사각형이 그려진다.

 

 

def compressed_image_callback(self, image):
		frame = self.Bridge.compressed_imgmsg_to_cv2(image)
		# print("frame: ")
		# print(type(frame))
		# print("image: ")
		# print(type(image))
		## 선그리기
		frame = cv2.line(frame, (0,0), (400,400), (255,0,0), 5)
		## 사각형 그리기
		frame = cv2.rectangle(frame, (384,0), (510,128), (0,225,0), 5, -1)
		## 원 그리기 
		frame = cv2.circle(frame, (447,63), 63,(0,255,225), 5, -1)
		cv2.imshow("frame", frame)
		cv2.waitKey(1) # 반드시 waitkey로 1msec 정도를 걸어주어야 알맞게 나온다.

또한 주의해야할 점은

코드를 보면

frame은 선 -> 사각형 -> 원으로 바뀌는 것이 아니라 추가되어 저장되는 구조이다.

 

4. 타원 그리기

cv2.ellipse

(그림 그릴 이미지, 중심점, (장축, 단축),  기울기(degree), 시작각도(degree), 끝각도(degree), 색깔, 두께)

시작각도와 끝각도는 그릴 영역을 각을 기준으로 정하는 것을 의미한다.

		## 타원 그리기
		frame = cv2.ellipse(frame, (256,256), (100,50), 0, 50, 180, (255,255,0), -1)

 

해당 타원의 50도에서 180도부분만 그린 결과

 

5. 다각형 그리기

True를 해 주면 닫힌 도형을 만든다.

cv2.polyline

(그림 그릴 이미지, 연결할 점의 리스트, 닫힌 도형 여부, 색깔, 두께)

		pts = np.array([[10,5], [20,30],[70,20],[50,10]],np.int32)
		pts = pts.reshape((-1, 2))
		frame = cv2.polylines(frame, [pts], True, (0,255,255), 3)

왼쪽 맨 위에 노란색이 다각형이다.

True를 해주었기 때문에 닫힌 도형이 된다.

- reshape(( -1, 2))에서 -1은 자동으로 설정하는 것을 의미한다.

- np.int32는 데이터의 타입을 int32로 지정해줌을 의미한다.

 

 

6. 글씨 써주기

cv2.putText

(글씨 쓸 이미지, 쓸 내용, 쓰기 시작할 왼쪽 아래 점, 폰트, 크기, 선 종류, 픽셀색연결방식)

 

 


 

2. 마우스 이벤트

특정 영역을 마우스로 클릭하면 지정한 이벤트가 발생하도록 한다.

 

 

실시간으로 나오는 이미지에 마우스로 그림그리는 것은 어렵다.

 

3. 트랙바

shape[0] : 행의 개수 - 세로의 길이

shape[1] : 열의 갯수 - 가로의 길이세

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import rospy
from sensor_msgs.msg import CompressedImage
from cv_bridge import CvBridge

import cv2
import numpy as np

class ImageSubscriber(object):
	def __init__(self):
		rospy.Subscriber("/image_jpeg/compressed", CompressedImage, self.compressed_image_callback)
		self.Bridge = CvBridge()

	# ===================================================
	#                   CALLBACK FUNCTION
	# ===================================================
	def compressed_image_callback(self, image):
		self.frame = self.Bridge.compressed_imgmsg_to_cv2(image)
		## frame --> OpenCV에서 사용하는 Image Type으로 변환이 되었음
		## frame 변수에 영상 처리 진행하면 됩니다. 640 x 480 Image
		
		cv2.namedWindow('image')
		cv2.createTrackbar('x', 'image', 0, self.frame.shape[1], self.nothing)
		## cv2.createTrackbar --> 이미지에 트랙바 추가
		## (트랙바 이름, 추가할 창의 이름(namedWindow 참고), 최소값, 최대값, 변경 시 할 내용)
		cv2.createTrackbar('y', 'image', 0, self.frame.shape[0], self.nothing)
		cv2.createTrackbar('radius', 'image', 0, 100, self.nothing)
		cv2.createTrackbar('R', 'image', 0, 255, self.nothing)
		cv2.createTrackbar('G', 'image', 0, 255, self.nothing)
		cv2.createTrackbar('B', 'image', 0, 255, self.nothing)
		x= cv2.getTrackbarPos('x', 'image')
		## cv2.getTrackbarPos --> 이미지에 있는 트랙바의 값을 받아 오기
		## (트랙바의 이름, 받아올 창의 이름)
		y= cv2.getTrackbarPos('y', 'image')
		radius= cv2.getTrackbarPos('radius', 'image')
		b= cv2.getTrackbarPos('B', 'image')		
		r= cv2.getTrackbarPos('R', 'image')
		g= cv2.getTrackbarPos('G', 'image')
		b= cv2.getTrackbarPos('B', 'image')
		cv2.circle(self.frame,(x,y),radius,(b, g, r),-1)
		cv2.imshow("image", self.frame)
		cv2.waitKey(1)

	def nothing(self, x):
		pass

	# 실행 방법
	# cd ~/catkin_ws/
	# catkin build
	# source devel/setup.bash
	# rosrun opencv_sim cv_example1.py


def run():
	rospy.init_node("ImageSubscriber")
	ImageSubscriber()
	rospy.spin()

if __name__ == '__main__':
	run()

 

 

4. 이미지 처리

PADDING

 

 

5. 이미지 연산

+기호를 쓰거나 add()를 하는 방식 간의 차이가 있다.

+ 같은 경우느 255 + 10 = 9

add() 같은 경우는 255 + 10 = 255ㄴ

 

두 개의 이미지를 더할 때 가중치 합이 1이 되도록 하고 트랙바로 비율을 조절한다.

addWeighted를 쓴다.

 

ADD OR NOT XOR 연산으로 처리힌다.

 

 

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

민 - [20강]  (0) 2022.03.14
킴 [이미지 처리]  (0) 2022.03.10
킴 테스트3 토픽 주고 받기  (0) 2022.03.09
킴 테스트3 토픽 주고 받기  (0) 2022.03.08
킴 테스트3 토픽 주고 받기  (0) 2022.03.08