제12회 임베디드SW 경진대회 인기상 수상작

1. 작품 개요
이 시스템은 주차장의 남은 자리를 사용자가 쉽게 파악 할 수 있게 도와주는 장치이다. 카메라를 사용하였기 때문에 각 주차공간마다 인식 센서를 설치할 필요 없이 카메라 한대로 광범위하게 인식 할 수 있으며 서버에서 데이터 처리 과정 없이도 무선으로 정보를 사용자에게 전달 해 줄 수 있는 것이 큰 장점이다. 

카메라로 들어오는 영상을 디지털 이미지 프로세싱 알고리즘을 이용하여 주차장의 특정 자리의 주차상태를 판별해서 서버에 업로드를 시키고 안드로이드가 서버에서 정보를 받아와 사용자가 애플리케이션을 통해 확인하는 방법으로 개발하였다.

이 시스템은 임베디드 보드 라즈베리 파이에서 구동되는 카메라의 영상 인식기술, JAVA 기반의 안드로이드 프로그래밍을 통한 애플리케이션 개발 두 가지의 주요한 기술이 사용되었으며, 두 장치를 연결해주는 아파치 서버를이용한 복합적인 시스템으로 구성되어 있다.

 

2. 목적
IoT(Internet of Things) 기술을 적용한 스마트 파킹 시스템을 구축하여 주차 공간 상황을 사용자에게 거주 지역 및 이동 거리 내에 있는 주차 가능 공간에 대한 실시간 안내기능을 제공한다.

빈 주차 공간에 대한 가장 최적화 된 길을 사용자는 스마트 폰 애플리케이션을 통하여 원격으로 주차 공간을 확인할 수 있으며 실시간으로 빈 곳의 위치를 파악해 빠르게 차를 댈 수 있다. 

그 결과 주차 공간을 찾는 수고를 덜어 교통 혼잡도를 줄일 수 있을 뿐만 아니라 주차에 소요되는 시간과 시민의 편의를 향상 시키는 기대 효과를 바랄 수 있고, 교통 당국의 불법 주차 단속 체계를 개선하고 지자체의 차등적 주차 요금제 운영 기반을 마련할 수 있다.

 

3. 작품 설명 
3.1. Software 구성
IoT 주차관리 시스템의 구성은 크게 서버와 클라이언트로 나누어진다. 다시 말하면 주차장의 정보를 주는 ‘제공자’와 그 정보를 받아 실제 사람에게 보여주는 ‘리시버’가 있는 것이다.

주차 공간에 대한 정보를 판단 할 중추적 기술은 DIP(Digital Image Processing)이다. 데이터 처리 절차를 설명하면 다음과 같다. 빈 주차공간은 센서(카메라)를 통해 감지되고, 감지된 화면 데이터는 영상처리기술을 통해서 각 차선내의 좌표에 자동으로 자동차가 있는지 없는지 여부를 판단한다.

좌표 데이터는 MCU를 이용하여 처리된 것으로 사용자가 필요로 하는 정보인 빈자리인지 아닌지 또는 어디에 빈자리가 있는지 등의 데이터를 분석한다. 각 주차 공간에 따른 웹캠으로 이미지를 받아온 후 그 그림을 좌표로 받아 주차 공간의 위치 값을 산출 하였다.

그리고 IoT (Internet of Things)을 이용해서 데이터를 스마트 폰으로 위치정보와 주차 가능 정보를 전송한다. 본 과제에서 이러한 처리과정을 수행할 MCU는 라즈베리파이 (Raspberry Pi)이다.

리눅스 기반의 라즈베리 파이는 싱글 보드 컴퓨터로써 그래픽 성능이 뛰어나면서도 저렴한 가격의 장점을 가지고 있다. 라즈베리 파이는 전체적인 시스템에서 영상처리와 서버의 역할을 한다.

정보를 받는 쪽은 안드로이드 앱이다. 앱은 사용자가 쉽게 접근할 수 있는 UI가 표현되어 있다. 메인 화면에서 ‘주차장 찾기’를 누르면 다양한 주차장이 리스트에 표시되는데 이때 리스트에 남은 자리를 표시해 준다. 이것은 사용자가 최대한 빠르게 빈 주차장을 찾을 수 있게 하기 위함이다.

앱은 4종류의 액티비티(하나의 실행화면)으로 구성되었다. MainActivity는 처음 앱을 실행시켰을 때 만날 수 있는 화면, 메인화면을 구성한다. MainActivity를 통하여 ‘주차장 찾기’를 통해 주차장 공석여부를 보거나 ‘주차장 보기’를 통해 자신이 주차한 차의 상황을 사진으로 볼 수 있다.

ListActivity, CListActivity는 주차장의 종류를 나열해놓은 리스트를 표시하는 역할을 한다. 주차장이 선택되면 선택된 주차장의 정보를 다른 액티비티에 보낸다.

htmlPas, ListPasActivity는 아파치 서버상에 올라온 html파일을 읽고, 읽은 정보를 처리하여 다른 액티비티에 보낸 후 실행하는 역할을 한다. htmlPas는 주차장의 공석 여부를 처리하고, ListPasActivity는 주차장 공석의 합을 처리하여 ListActivity에 보낸다. 본 액티비티는 실제 사용자에게 보이지 않는다.

CameraActivity, SignalActivity는 읽어온 데이터를 직접 표시하는 역할을 하는 액티비티이다. SignalActivity는 주차장 공석 여부를 버튼을 이용해 표시해주고, CameraActivity는 ‘내 차 보기’에서 자신의 차가 찍힌 사진을 표시해준다.

 

3.2. Software 흐름도 및 클래스 다이어그램 (개발언어에 따라 선택)

▲ 그림 1. 시스템 구조도.

3.3. Software 기능
3.3.1 DIP 
차량이 주차공간으로 들어오고 난 이후 바뀐 픽셀 값을 인지하여 주차공간에 차량이 들어오면 1로 변환시켰고, 그렇지 않으면 600프레임마다 체크하여 주기적인 주차 여부를 확인 할 수 있게 하였다. 이는 차량이 오인식을 줄이기 위해 첨가하였다.

 

3.3.2 안드로이드
안드로이드 앱의 기능은 크게 2가지가 있다. 그 중에서도 중요한 기능은 주차장의 주차 여부에 따른 공석 여부를 표시해주는 기능이다. MainActivity에서 ‘주차장 찾기’를 누르면 ListpasActivity를 실행시킨다. ListpasActivity는 주차장 공석여부가 표시되어있는 서버상의 모든 html문서를 읽어 들인다.

그리고 읽은 데이터를 띄어쓰기(공백) 단위로 잘라서 배열에 넣는다. 더 이상 읽어 들일 데이터가 없으면 배열의 모든 요소의 합을 주차장 자리의 총 개수에서 뺀다. 뺀 값은 주차장 빈자리 개수의 총 합을 의미한다.

주차장의 종류별로 각각 같은 과정을 거친 후 뺀 값들만 모아서 intent를 이용해 ListActivity에 보낸다. 정보를 보낸 후 ListActivity를 실행시킨다. ListActivity는 주차장을 종류별로 리스트로 표현해주는 액티비티이다. 받은 정보를 남은 자리로 표시한다. 여러 주차장이 표시된 리스트에서 자신이 찾고자 하는 주차장을 누르면 선택된 목록에 따라서 htmlPas에 전달하는 값이 달라진다. 

htmlPas도 ListActivity와 같게 웹상의 html을 읽고 정리하는 역할을 한다. 전달 값에 따라서 읽어 들여야 하는 html의 주소가 바뀐다. 읽어 들여야 하는 html은 찾고자 하는 주차장의 html이다. ListActivity와 같은 과정으로 주차장의 공석여부를 담은 정보를 배열에 넣고 배열을 intent에 담아 SignalActivity에 보내고 실행시킨다. 

SignalActivity는 받은 정보 즉, 배열의 요소에 따라 주차장 공석여부를 표시해주는 역할을 한다. 전달 받은 배열의 요소들을 각각 주차장의 공석여부를 표시해주는 버튼의 배열에 대입한다. 반복 문을 돌려 버튼 배열의 요소 별로 텍스트와 클릭 이벤트를 설정해준다.

배열의 요소가 1일 경우는 버튼의 텍스트가 ‘주차가능’으로 표시되고 배열의 요소가 0일 경우는 텍스트가 ‘주차불가’로 표시된다.

주차가능한 곳의 버튼을 누르면 그곳까지 가는 경로가 표시된다. 반면에 주차불가로 표시된 버튼을 누르면 ‘주차 불가한 자리입니다’라는 토스트 메시지가 뜬다. 새로 고침 버튼을 누르면 본 주차장에 해당하는 htmlPas를 실행시킴으로써 주차장의 자리 정보를 업데이트 할 수 있다.

다른 하나의 기능은 ‘주차장 보기’이다. MainActivity에서 ‘주차장 보기’를 누르면 CListpasActivity를 실행시킨다. CListpasActivity는 ListpasActivity와 비슷한 기능으로 주차장을 종류별 리스트 형식으로 표시해 주는 역할을 한다.

주차장을 선택하면 선택한 주차장의 CameraActivity를 실행한다. CameraActivity는 서버상의 주차장 이미지를 읽어 들여 표시해주는 역할을 한다. 이미지가 있는 URL을 받고 이미지를 버퍼에 저장한다. 그리고 저장된 이미지를 화면 크기에 맞게 resize하고 resize된 이미지를 ImageView를 통해 표시한다. 새로 고침 버튼을 누르면 본 주차장에 해당되는 CameraActivity를 재실행 하여 새로운 사진을 업데이트 할 수 있다.

 

3.4. 프로그램 사용법 (Interface)
3.4.1 DIP

웹캠을 통해 정확한 인식이 필요하므로 각 구역의 주차지역이 정확하게 인식되는 위치에 카메라를 설치하여야 하는 것이 중요하다. 또 라즈베리 파이와 연결시켜 주차 공간의 데이터를 자동적으로 수신 받기 때문에 라즈베리 파이에서 발생하는 열을 식혀 줄 수 있는 공간에 설치하여 성능의 저하가 없도록 하는 것이 필요하다.

 

3.4.1 안드로이드 
웹캠을 통해 정확한 인식이 필요하므로 각 구역의 주차지역이 정확하게 인식되는 위치에 카메라를 설치하여야 하는 것이 중요하다.

또한 라즈베리 파이와 연결시켜 주차 공간의 데이터를 자동적으로 수신 받기 때문에 라즈베리 파이에서 발생하는 열을 식혀 줄 수 있는 공간에 설치하여 성능의 저하가 없도록 하는 것이 필요하다.

안드로이드 앱의 메인 화면은 주차장 찾기 및 주차장 보기 아이콘 두 가지가 있다. 주변의 주차장 및 주차장의 남은 자리를 확인할 때에는 주차장 찾기 아이콘을 터치하여 주차장 정보와 주차장 빈자리를 찾고, 주차가능한 자리를 터치하여 주차자리까지의 길을 안내받는다.

주차장의 모습을 실시간 영상으로 받아보고 싶을 때에는 주차장 보기 아이콘을 터치하여 현재 주차장의 모습을 본다.

 

3.5. 개발환경
사용언어는 OpenCV, Linux, JAVA이며, 사용된 tool은 Visual Studio 2010 C++, Eclipse, Android SDK가 있다. 개발 환경은 Window7, Android, Linux, Raspberry Pi이다.
 

▲ 그림 2. 안드로이드 앱 화면.

4. 프로그램 설명
4.1. 파일 구성
application에서 주요한 기능을 담당하는 파일은 src폴더에 있는 Activity를 담당하는 JAVA 파일이다. layout폴더의 xml파일은 각 Activity의 UI를 담당한다. Activity들을 앱에 추가하고 여러 permission을 넣은 AndroidManifest.xml. values폴더의 String.xml은 앱내부에서 쓰이는 언어 정보를 담고 있다.

 

4.2. 함수별 기능 
4.2.1 DIP 

자동차의 유무를 확인하기 위해 Opencv(Open Source Computer Vision )라는 C++ 라이브러리를 사용했다.

#include “opencv2/highgui/highgui.hpp”
#include <cv.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>

웹캠을 이용해 영상정보를 라즈베리파이로 받아오기 위해 CvCapture* capture를 사용하였다.

CvCapture* capture = cvCaptureFromCAM(0);

그 외 받아온 영상정보를 활용하기 위해 IplImage *를 사용하였다.

IplImage *frame=0;
IplImage *gray = 0;
IplImage *bin = 0;
IplImage *tmp=0;
IplImage *park[9];

▲ 그림 3. 안드로이드 파일구성 1.
▲ 그림 4. 안드로이드 파일구성 2.

그 이후 동영상으로 영상처리를 하기 위해 while함수를 무한 루프로 돌려 영상이 진행되는 동안 계속 해서 영상처리를 진행 하였다. 먼저 우리 모델의 영상인식 방법은 영상을 이진화하고 RoI(Region Of Interest)를 통해 개별 주차장 마다 주차장부분만의 명도를 체크하여 흰색 명도가 높을 경우 자동차를 흰색으로 인지하여 자동차가 있는지 없는지를 확인하게 된다.

frame =cvQueryFrame(capture);
gray=cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U,1);
bin=cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U,1);;
cvCvtColor(frame,gray,CV_RGB2GRAY);
cvThreshold(gray,bin,230,255,CV_THRESH_BINARY);
<이진화 과정>

white_ful = cvCountNonZero(bin);
if((prev_wt-white_ful>3500 || white_ful-prev_wt >3500) &&
(white_ful-prev_wt<65000 || prev_wt-white_ful <65000)|| count%600==0)
{
che =true;
}
else
che = false;
prev_wt=white_ful;
if(che==true)
{
tmp= (IplImage*)cvClone(bin);
cvSetImageROI(tmp,cvRect(52,18,85,50));
park0= (IplImage*)cvClone(tmp);
tmp = (IplImage*)cvClone(bin);
cvSetImageROI(tmp,cvRect(135,18,85,50));
park1 = (IplImage*)cvClone(tmp);
tmp = (IplImage*)cvClone(bin);
cvSetImageROI(tmp,cvRect(100,18,85,50));
park2=(IplImage*)cvClone(tmp);
tmp = (IplImage*)cvClone(bin);
cvSetImageROI(tmp,cvRect(110,18,85,50));
park3=(IplImage*)cvClone(tmp);
tmp = (IplImage*)cvClone(bin);
cvSetImageROI(tmp,cvRect(120,18,85,50));
park4=(IplImage*)cvClone(tmp);
tmp=(IplImage*)cvClone(bin);
cvSetImageROI(tmp,cvRect(52,20,55,50));
park5=(IplImage*)cvClone(tmp);
tmp = (IplImage*)cvClone(bin);
cvSetImageROI(tmp,cvRect(135,10,55,50));
park6=(IplImage*)cvClone(tmp);
tmp= (IplImage*)cvClone(bin);
cvSetImageROI(tmp,cvRect(128,20,55,50));
park7=(IplImage*)cvClone(tmp);
tmp=(IplImage*)cvClone(bin);
cvSetImageROI(tmp,cvRect(121,20,55,50));
park8=(IplImage*)cvClone(tmp);
tmp=(IplImage*)cvClone(bin);
cvSetImageROI(tmp,cvRect(120,20,55,50));
park9= (IplImage*)cvClone(tmp);
}
for(int ss=0; ss<10; ss++)
{
if(hall[ss]>4000)
{
parking[ss]=false;
ress[ss]=1;
}
else
{
parking[ss]=true;
ress[ss]=0;
}

<RoI를 이용해서 개별 주차장마다 자동차가 있는지 여부 판별>

그 이후에 판별된 정보를 주차장에 차가 있는 주차장은 1 없는주차장은 0의 정보를 html 파일로 만들어 낸다.

cout<<”Pixels : “<<hall[0]<<” “<<hall[1]<<” “<<hall[2]<<” “<<hall[3]<<”
“<<hall[4]<<” “<<hall[5]<<” “<<hall[6]<<” “<<hall[7]<<” “<<hall[8]<<” “<<hall[9]<<”
Frames”<<count<<endl;
cout<<”CarPark Number :”;
FILE *wfp = fopen(“carpark.html”,”w”);
for(int aa=0; aa<10; aa++)
{
cout<<ress[aa]<<” “;
fprintf(wfp,”%d”, ress[aa]);
}
fprintf(wfp,”n”);
fclose(wfp);
cout<<endl;

다음에는 나머지 함수별 기능에 대해 알아보겠다.

 

글 : Convergence (김건형, 신용준 외 8명 / 서울과학기술대학교)
자료제공 : 임베디드소프트웨어·시스템산업협회

 

회원가입 후 이용바랍니다.
개의 댓글
0 / 400
댓글 정렬
BEST댓글
BEST 댓글 답글과 추천수를 합산하여 자동으로 노출됩니다.
댓글삭제
삭제한 댓글은 다시 복구할 수 없습니다.
그래도 삭제하시겠습니까?
댓글수정
댓글 수정은 작성 후 1분내에만 가능합니다.
/ 400
내 댓글 모음
저작권자 © 테크월드뉴스 무단전재 및 재배포 금지