다음 동영상은 역광이 대단히 심한 대낮 시간에 사무실 창가에서 라즈베리 Pi 카메라로 촬영한 영상을 OpenCV 파이선 컴퓨터 비전 코드로 캡츄어 한 짤이다. 청색 공의 움직임에 따른 원주의 움직임과 편심된 중심의 위치 및 및 출력되는 중심좌표 값을 잘 관찰하여 보자. https://youtu.be/IEwqdylaNkw OpenCV에 의한 Computer Vision은 Haarcascade 라이브러리를 사용하여 사람의 얼굴과 신체 부위를 인식하거나 또는 고양이 얼굴을 인식한다든지 또는 자동차인지 여부를 인식할 수 있다. 하지만 Haarcascade가 라이브러리 모듈로 지원하지 않는 오브젝트는 어떤 방식으로 처리할 것인지가 코딩의 관심사다. 대표적인 오브젝트로서는 자동차 자율주행에서 반드시 필요로 하는 흰색 또는 노란색으로 표현되는 주행 차선이며 아울러 RC카에서 자주 시험해 보는 컬러 공의 인식 문제들이다. 지금까지 지속적으로 본 블로그 예제에서 사용하는 카메라 해상도는 camera.resolution = (320, 256) 으로 주어진다. 물론 필요에 따라서 해상도 변경은 가능하다. 아울러 framerate = 32로 지정한 상태에서 for loop 코드에서 연속 촬영할 때에 이 framerate 가 적용되며 루틴 내에서 frame.array를 image로 설정하게 된다. 물론 Pi 카메라로 실시간 촬영하는 동영상을 볼 수 있도록 코딩 되어 있지만 필요하다면 cv2.imread(‘jpg 사진 파일명’) 명령을 사용하여 사진을 Pi카메라 앞에 두는 효과를 얻을 수도 있다. Pi 카메라가 매초 32 프레임으로 캡츄어 한 화면에서 컬러 공을 컬러 오브젝트로 인식하기 위한 방법은 BGR2HSV 이미지를 생성하여 주어진 hue 값 범위에 들어오는 오브젝트 만을 마스킹하여 분리시킨 흑백의 binary 이미지 파일을 만들어야 한다. 이와같이 마스킹된 파일로 원래의 이미지 파일에 마스킹 정보를 적용하면 해당되는 컬러 공만을 분리해 낼 수 있다. 하지만 실제 해보면 컬러 공에 해당하는 부위뿐만 아니라 주의 환경으로부터 조명 영향에 의해 창문을 비롯한 노이즈 현상 소스들도 나타나기도 한다. 마스킹된 결과 이미지를 관찰해 보면 컬러 공뿐만 아니라 조명 영향에 의해서 주위 환경으로부터의 영상 노이즈들도 개입이 된다. 컬러 공을 비롯한 영상 노이즈를 합해 흰색으로 처리 되는 기하학적 모양의 부분을 Blob 이라 한다. 물방울 모양들과 라인 형태 및 반점들의 집합으로 나타나기도 한다.  Blop이란 비누방울을 만들어 보면 꼭 공 모양만 나오는 것은 아니고 모양이 많이 변하면서 찌그러진 형태의 방울 모양들이 나타는데 이런 기하학적 형상을 Blob이라고 한다. 반면에 OpenCV에서 말하는 Blob이란 일단의 같은 gray 픽셀 값들을 가지게 되는 집합체로서 결국은 traking 하려는 오브젝트 외에 카메라 스크린에 잡히는 노이즈 형상들 까지를 포함한다. 특히 초당 32매 정도로 카메라 프레임을 잡게 되면 화면에 컬러로 이미지가 찍히지만 특별한 hue 값 범위를 주어 masking 작업을 해 보면 오브젝트 외에도 주변의 테이블이나 창문 벽 같은 대상들도 Blob 으로 함께 잡히기도 한다. 이번 코딩에서의 주요 관심 사항은 찾아낸 오브젝트에 해당하는 Blob을 처리하는 방법을 제시하는 것이다. 일단 Pi카메라로 잡은 영상 fram을 image 로 두자. image = frame.array image 파일을 그대로 HSV 적용을 하게 되면 위 Blob 사진에서처럼 작은 반점들이 많이 나타나는데 이 반점들은 GaussianBlur(0 명령을 사용하여 상당 부분 제거가 가능하다. GaussianBlur() 는 일종의 CNN(컨볼루션 뉴럴 네트워크)기법으로서 사진을 대상으로 국부적으로 스캔작업을 진행하면서 Gaussian 스타일로 averaging 을 하게 되면 흰색의 작은 요소들이 평균화되어 검정색의 백그라운드 컬러에 묻혀버리게 된다. image = cv2.GaussianBlur(image, (11,11), cv2.BORDER_DEFAULT) (11,11) ksize 파라메터는 영상 화면의 필터링을 지정하는데 반드시 홀수를 사용해야 한다. 이 값 설정에 따라 image 파일이 제법 영향을 받게 된다. GaussianBlur() 처리가 된 image를 대상으로 컬러 공을 분리해 내기 위한 작업으로서 BGR2GRAY 가 아닌 BGR2HSV 로 속성을 바꾸어 준다. BGR2GRAY 는 말 그대로 Gray 이미지가 되는데 이는 Haarcascade 방식에 이한 안면 인식과 같은 작업에 사용되며 반면에 BGR2HSV는 컬러 공처럼 색상을 hue 값에 의해 쉽게 분리해 내는데 편리한 이미지이다. 불리해 내고자하는 청색 공의 hue 값의 하한과 상한 범위를 정의하자.  hue 값 범위가 설정 되었으면 cv2.inRange() 명을 사용하여 마스킹 작업을 하고 그 결과 이미지를 maskb 라고 하자. 이 마스크 이미지 maskb는 binary 이지지 파일이며 원래의 image 파일과 AND 또는 OR 로직연산이 가능하다. image 파일과 cv2.bitwise_and 연산을 하게 되면 image 영상과 maskb 영상의 공통부분에 해당하는 컬러 볼만이 흰색으로 얻어지며 나머지 백그라운드는 검정색으로 처리 된다. 한편 이와 같이 hue 값을 이용하여 마스킹된 컬러 공을 추적하기 위해서는 maskb에서 Blop 으로 파악된 오브젝트의 중심의 좌표 값을 찾아내는 일이다. 이 중심 값을 계산하기 위해서는 우선 공 모양 Blob을 둘러싸는 윤곽선()Contous)을 찾을 필요가 있다.  찾은 윤곽선을 그려보면 조명의 영향으로 꼭 원형으로 나오지는 않는다. 그래서 일단 찾아낸 Contours 데이타를 대상으로 최소크기의 원 모양을 결정하고 이어 모멘트를 계산하여 중심좌표를 계산해서 찾는다. 이 과정에서 라즈베리 파이선 코드가 실시간 계산을 하지만 때때로 조명 영향으로 인해 실수를 많이하므로 코드가 실행 중 끓어지지 않도록 요령껏 코드를 잘 짜야 한다. 이 문제는 영상처리의 본질적인 문제가 아니라 Contours를 찾기 위한 단순한 수학 연산과정에서 분모의 값이 0으로 나타나게 되는 일종의 노이즈와 같은 현상이다.  공에 의해 생성된 Blob 의 반지름을 계산해 보아 10 이상일 경우 원주를 원으로 작도하고 중심의 좌표를 출력한다.  하지만 공이 정확하게 원 모양 Blob 으로 캡츄어되지 못하면 모멘트 계산 결과에 의한 중심의 원치가 어는 한쪽으로 쏠릴 수도 있음에 유의하자. 위 사진에서 왼쪽은 역광이 심한 경우이며 오른쪽은 구름에 의해 했빛이 다소 약해진 경우로서 쏠림 현상이 많이 완화된 경우이다. 커버에 올려둔 동영상에서 Blob 의 모양이 심한 역광 현상으로 인해 원의 윗부분에 쏠린 쪽만 체크되고 있어 모멘트 법으로 계산한 중심 좌표가 원의 중심과 괴리를 보이고 있다. 그 아래에 출력되는 수치 값들은 계산된 중심 좌표와 면접 값이다. 이 중심 값을 추적하면 청색공이 운동함에 따라 그 좌표를 traking 할 수 있으며 이 데이터를 사용하여 RC 밸런싱 로봇의 추진 모터를 제어하여 구동할 수 있게 된다.  필자의 블로그에 파이선 코드를 올려두었으니 다운받아서 실행해 보도록 하자. 파이선 코드에서는 사용자 별로 indentation 설정 값이 다르기 때문에 콜론(:) 기호 다음에 오는 명령문들을 콜론 바로 뒤에 위치시칸 후 엔터키를 먹여 제대로 indentation을 회복시켜 코드를 실행해 보기 바란다. http://blog.daum.net/ejleep1/37
author | codingart |
---|---|
permlink | 6-16-color-ball-tracking-opencv |
category | kr |
json_metadata | {"tags":["kr","kr-newbie","manamine","jjangjjangman","kr-dev"],"image":["https://img.youtube.com/vi/IEwqdylaNkw/0.jpg","https://cdn.steemitimages.com/DQmTgdmmztCTiHGP2VSgRu3qSGaecDRiE8yLz5YLZYKtRKS/noname01.png","https://cdn.steemitimages.com/DQmQcwSxeWGVR7MwKoZreGiKgEST7RpfWqb9WuqXUfVsMgJ/noname02.png","https://cdn.steemitimages.com/DQmTN228igkirfXiYrDX8H2pEVwtnrztJ2YHV9cCjWVc75d/noname03.png","https://cdn.steemitimages.com/DQmcwNBjtszwwcKWEDcUndBF3Sz8n4srxMUVmnwJLLLx5Tt/noname04.png","https://cdn.steemitimages.com/DQmZJ2QPFENZxQaiC5uBQv7uFDf5fJNLJbKLDpp5UCXvRFS/noname05.png","https://cdn.steemitimages.com/DQmSBRm6XoWc3PZANy47q4dY6fJVAVkowHyBQvpbwgDoMMC/noname06.png"],"links":["https://youtu.be/IEwqdylaNkw","http://blog.daum.net/ejleep1/37"],"app":"steemit/0.1","format":"markdown"} |
created | 2018-10-11 04:56:30 |
last_update | 2018-10-11 06:59:57 |
depth | 0 |
children | 0 |
last_payout | 2018-10-18 04:56:30 |
cashout_time | 1969-12-31 23:59:59 |
total_payout_value | 10.694 HBD |
curator_payout_value | 3.476 HBD |
pending_payout_value | 0.000 HBD |
promoted | 0.000 HBD |
body_length | 4,386 |
author_reputation | 41,833,111,979,966 |
root_title | "6-16 라즈베리 컴퓨터 비전에 의한 Color Ball Tracking OpenCV" |
beneficiaries | [] |
max_accepted_payout | 1,000,000.000 HBD |
percent_hbd | 10,000 |
post_id | 73,050,494 |
net_rshares | 10,049,835,966,360 |
author_curate_reward | "" |
voter | weight | wgt% | rshares | pct | time |
---|---|---|---|---|---|
eforucom | 0 | 759,230,929 | 1% | ||
wony | 0 | 232,215,253,245 | 30% | ||
jamjamfood | 0 | 9,445,699,713 | 25% | ||
virus707 | 0 | 7,301,994,836,530 | 50% | ||
beoped | 0 | 27,721,765,142 | 20% | ||
sensation | 0 | 268,280,893 | 100% | ||
bramd | 0 | 2,312,545,986,344 | 30% | ||
crowsaint | 0 | 31,955,633,891 | 50% | ||
jesusjacr | 0 | 494,258,388 | 0.4% | ||
mishana | 0 | 13,321,813,274 | 60% | ||
nephilimz | 0 | 40,504,928,024 | 100% | ||
anpigon | 0 | 11,109,187,540 | 49% | ||
sonsory | 0 | 5,135,182,698 | 9% | ||
pairplay | 0 | 22,378,667,838 | 10% | ||
vadkaabish | 0 | 494,256,915 | 100% | ||
leakingunder | 0 | 494,407,350 | 100% | ||
romansilenkov | 0 | 494,876,939 | 100% | ||
pooruthenium | 0 | 495,085,589 | 100% | ||
weegel | 0 | 495,084,118 | 100% | ||
listlabcoat | 0 | 495,254,646 | 100% | ||
kiryuha11 | 0 | 494,988,375 | 100% | ||
paelladiamond | 0 | 495,841,929 | 100% | ||
strelkaworkshop | 0 | 15,029,381,182 | 100% | ||
nfc | 0 | 9,026,806,555 | 1% | ||
ploverka | 0 | 498,778,953 | 100% | ||
jappinesswrench | 0 | 498,735,038 | 100% | ||
sweetsbury | 0 | 498,650,192 | 100% | ||
triflesleepy | 0 | 498,775,083 | 100% | ||
ergotverdant | 0 | 498,776,350 | 100% | ||
bigblock | 0 | 498,710,520 | 100% | ||
helpscode | 0 | 498,705,217 | 100% | ||
antonsergienko | 0 | 498,740,530 | 100% | ||
teqila777 | 0 | 498,805,848 | 100% | ||
pomarinerose | 0 | 498,705,248 | 100% | ||
caringirish | 0 | 498,743,985 | 100% | ||
germgosts | 0 | 498,681,349 | 100% | ||
belliedas | 0 | 498,737,042 | 100% | ||
acceptremove | 0 | 498,726,292 | 100% | ||
showershormones | 0 | 498,706,941 | 100% | ||
appliedhandbag | 0 | 498,669,789 | 100% | ||
baggygruesome | 0 | 498,652,255 | 100% | ||
bootedchork | 0 | 498,704,386 | 100% | ||
currishpiquillo | 0 | 498,652,623 | 100% | ||
dayerlogistic | 0 | 498,660,344 | 100% | ||
piesaves | 0 | 498,740,678 | 100% | ||
mexicanrichest | 0 | 498,645,507 | 100% | ||
hodgkinamusing | 0 | 498,749,786 | 100% | ||
earedfinalist | 0 | 498,804,357 | 100% |