본문 바로가기
Robot/ROS

킴 [이미지 처리]

by 9루트 2022. 3. 10.

컬러 스페이스

OS에 따라서 이미지가 RGB 또는 BGR로 다르게 들어온다.

 

Binary image는 0,1으로 흑백만 보여준다.

Gray Scale image는 0-255까지 밝기를 나타낸다.

 

각 R, G, B 채널에 8BIT씩 할당되어있다.

HSV Color-space는 색, 채도, 명도를 나타낸다.

cv2.cvtColor()를 사용하면 변경이 가능하다.

 

 

3가지 컬러별로 채널

		cv2.imshow("image", self.frame)
		cv2.imshow("b", self.frame[:, :, 0]) # 0번째 채널을 보여달라.
		cv2.imshow("g", self.frame[:, :, 1])
		cv2.imshow("r", self.frame[:, :, 2])

 


hsv

 

		cv2.imshow('hsv', hsv)
		cv2.imshow('v', hsv[:, :, 0])
		cv2.imshow('s', hsv[:, :, 1])
		cv2.imshow('h', hsv[:, :, 2])

 

 


함수 3개를 알려주겠다.

1. cvtColor 함수 : hsv 를 뽑아내는 함수

 

 

 

2. cv2.inRange: 특정 영역의 값만 남겨준다.(이진화)

(입력 이미지, Lower Threshld, Higher Threshold)

ex) lower: [110, 50, 50], higher:[130, 255, 255]

전체 픽셀을 각각 확인해서 첫번째 값이 110~130, 두번째 값이 50~255, 세번째 값이 50~255로 나오게 된다.

조건을 맍고하는 값만 255로 바꾸고, 나머지는 다 0으로 처리한다.

색상이 없는 아예없는 흰색 부분이 검정으로 차선이 나온다.

 

cv2.circle(self.frame,(x,y),radius,(b, g, r),-1)
		hsv = cv2.cvtColor(self.frame, cv2.COLOR_BGR2HSV)


		lower_blue = np.array([0, 0, 50])
		upper_blue = np.array([130, 255, 255])
        
        # 이미지에서 blue 영역만 검출(inRange 함수를 사용)
		mask = cv2.inRange(hsv, lower_blue, upper_blue)
		cv2.imshow("maskedImage", mask)

 

미션

lower_white, higher_write --> 흰색 차선만 남게 (HSV)
ex) cv2.inRange(hsv, lower_white, higher_white)

lower_white = np.array([50, 0, 200])
		higher_white = np.array([150, 255, 255])
		white = cv2.inRange(hsv, lower_white, higher_white)
		cv2.imshow("white", white)

 


Lower_yellow, higher_yellow --> 노란색 차선만 남게(BGR)
ex) cv2. inRanged(self.frame, lower_yellw, higher_yellow)

lower_yellow = np.array([0, 100, 100])
		higher_yellow = np.array([80, 255, 255])
		yellow = cv2. inRange(self.frame, lower_yellow, higher_yellow)
		cv2.imshow("yellow", yellow)

나는 노가다로 일일히 값을 넣어 선을 검출하였다.

#!/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)
		hsv = cv2.cvtColor(self.frame, cv2.COLOR_BGR2HSV)


		lower_blue = np.array([0, 0, 50])
		upper_blue = np.array([130, 255, 255])

		## lower_white, higher_write _--> 흰색 차선만 남게 (HSV)
		# ex) cv2.inRange(hsv, lower_white, higher_white)
		lower_white = np.array([50, 0, 200])
		higher_white = np.array([150, 255, 255])
		white = cv2.inRange(hsv, lower_white, higher_white)
		cv2.imshow("white", white)

		## Lower_yellow, higher_yellow --> 노란색 차선만 남게(RGB)
		# ex) cv2. inRanged(self.frame, lower_yellw, higher_yellow)
		# lower_yellow = np.array([18, 94, 140])
		# higher_yellow = np.array([48, 255, 255])
		# yellow = cv2. inRange(hsv, lower_yellow, higher_yellow)

		lower_yellow = np.array([0, 100, 100])
		higher_yellow = np.array([80, 255, 255])
		yellow = cv2. inRange(self.frame, lower_yellow, higher_yellow)
		cv2.imshow("yellow", yellow)

		# lower_blue = np.array([110, 50, 50])
		# upper_blue = np.array([130, 255, 255])

		# 이미지에서 blue 영역만 검출(inRange 함수를 사용)
		# mask = cv2.inRange(hsv, lower_blue, upper_blue)
		# cv2.imshow("maskedImage", mask)

		# cv2.imshow('hsv', hsv)
		# cv2.imshow('v', hsv[:, :, 0])
		# cv2.imshow('s', hsv[:, :, 1])
		# cv2.imshow('h', hsv[:, :, 2])

		cv2.imshow("image", self.frame)
		# cv2.imshow("b", self.frame[:, :, 0]) # 0번째 채널을 보여달라.
		# cv2.imshow("g", self.frame[:, :, 1])
		# cv2.imshow("r", self.frame[:, :, 2])
		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()

 

트랙바를 이용한 하얀, 노란색 선 검출

#!/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)

		hsv = cv2.cvtColor(self.frame, cv2.COLOR_BGR2HSV)

		lower_blue= np.array([110,50,50])
		upper_blue= np.array([130,255,255])

		## lower_white, higher_white --> 흰색 차선만 남게 (HSV) cv2.inRange(hsv, lower_white, higher_white)
		## lower_yellow, higher_yellow --> 노란색 차선만 남게 (RGB) cv2.inRange(self.frame, lower_yellow, higher_yellow)
		cv2.namedWindow("white")
		cv2.createTrackbar('l_h', 'white', 0, 255, self.nothing)
		cv2.createTrackbar('h_h', 'white', 255, 255, self.nothing)
		cv2.createTrackbar('l_s', 'white', 0, 255, self.nothing)
		cv2.createTrackbar('h_s', 'white', 255, 255, self.nothing)
		cv2.createTrackbar('l_v', 'white', 0, 255, self.nothing)
		cv2.createTrackbar('h_v', 'white', 255, 255, self.nothing)
		l_h= cv2.getTrackbarPos('l_h', 'white')
		h_h= cv2.getTrackbarPos('h_h', 'white')
		l_s= cv2.getTrackbarPos('l_s', 'white')
		h_s= cv2.getTrackbarPos('h_s', 'white')
		l_v= cv2.getTrackbarPos('l_v', 'white')
		h_v= cv2.getTrackbarPos('h_v', 'white')

		lower_white = np.array([l_h, l_s, l_v])
		higher_white = np.array([h_h, h_s, h_v])

		# lower_white = np.array([80, 0, 200])
		# higher_white = np.array([160, 30, 255])
		lane_white = cv2.inRange(hsv, lower_white, higher_white)
		cv2.imshow("white", lane_white)

		lower_yellow = np.array([0, 180, 200])
		higher_yellow = np.array([50, 230, 255])
		lane_yellow = cv2.inRange(self.frame, lower_yellow, higher_yellow)



		
		cv2.imshow("yellow", lane_yellow)

		#이미지에서blue영역만검출(inRange함수사용)
		mask= cv2.inRange(hsv,lower_blue,upper_blue)
		## cv2.inRange --> 특정 영역의 값만 남겨줍니다. (이진화)
		## (입력 이미지, Lower Threshold, Higher Threshold)
		## ex) lower --> [110, 50, 50], higher --> [130, 255, 255]
		## 전체 픽셀을 각각 확인해서, 값이 첫번째 값이 110 ~ 130, 두번째 값이 50 ~ 255, 마지막 값이 50 ~ 255
		## 조건을 만족하는 값만 255로 바꾸고, 나머지는 다 0으로 처리 
		cv2.imshow("maskedImage", mask)


		## cv2.cvtColor --> 이미지 컬러 스페이스 변경
		## 변경할 이미지와 변경할 내용이 포함되어야 함

		cv2.imshow("hsv", hsv)
		cv2.imshow("h", hsv[:, :, 0])
		cv2.imshow("s", hsv[:, :, 1])
		cv2.imshow("v", hsv[:, :, 2])

		cv2.imshow("image", self.frame)
		cv2.imshow("b", self.frame[:, :, 0])
		cv2.imshow("g", self.frame[:, :, 1])
		cv2.imshow("r", self.frame[:, :, 2])
		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()

 

 

 


하얀색과 노란색 차선을 검출한 각각의 결과를 하나로 합쳐보자

bitwise_or

 


차선의 원근법 없애기

 

Geometric Transformation 개념 설명

이미지 내에선 원근법이 존재하여 평행한 두 선이 만나게 된다.

perspective transform은 이 만나는 선을 만나지 않도록 이미지를 변경한다.

getaffine TRANSFORM은 잘 사용하지 않는다.

 

위 그림의 차선을 찍고 각 점 부위를 평행하도록 이동시킨다.

 

 


Image Smothing

 

lowpass filter는 저주파 부분만 통과 시킨다.

highpass filter는 고주파 부분만 통과 시켜준다.

색 변화가 다이나믹한 부분을 스무스하게 만들어준다. 즉 뿌옇게 만들어준다.

경계면을 더 선명하게 만들어 주기도 한다.

 

 

Morphological Transformation : 검은색, 흰색만 존재하는 이미지를 처리한다.

Erosion: erode 주변을 깎는다. 주변 픽셀이 하나라도 비어있으면 지운다. -> 돌출된 부분 지울 때 쓴다.

Dilation: 흰색 영역 픽셀들을 정리한다. 주변을 팽창 시킨다. 주변 픽셀이 하나라도 채워져있으면 채운다. -> 전체적인 윤곽파악에 쓰인다.

Opening

Closing

 

 

 

 

pyramid

up하면 해상도가 높아지므로 선명해진다.

 

 

 

 

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

민 - ar_maker  (0) 2022.03.14
민 - [20강]  (0) 2022.03.14
킴 [OpenCV]  (0) 2022.03.10
킴 테스트3 토픽 주고 받기  (0) 2022.03.09
킴 테스트3 토픽 주고 받기  (0) 2022.03.08