December 18, 2018

디바이스마트 미디어:

[49호]장애인 주차구역 불법단속 시스템

Cap 2018-07-12 14-10-54-440

  2018 ICT 융합 프로젝트 공모전 우수상  

장애인 주차구역 불법단속 시스템

글 | 경상대학교 박주형

 

1. 심사평

칩센 실용적인 아이디어로 판단됩니다. 사실 주차장에 대한 초음파 감지 장치와 주차관리를 위한 번호판독기는 모두 구현되어 있는 기술이지만, 공공질서를 위한 형태로 융합한 형태가 좋다고 판단됩니다.

뉴티씨 장애인 주차구역에 등록되지 않은 비장애인 차량이 주차할 경우, 경보를 일으킨다는 컨셉으로 만들어졌는데 차량 번호판 인식, 차량 접근 인식, 경보 울림 등의 여러가지 기술들을 잘 구현한 듯 합니다. 다만, 보고서의 완성도가 많이 부족하여, 실제 구현을 잘 한 것이라는 부분에 대한 인식을 확실히 하기 어렵습니다. 잘 만드는 것도 중요하지만, 보고서로 다른 사람들도 잘 이해할 수 있도록 하는 부분도 매우 중요하다는 점을 인식하셔서, 다음에는 꼭 보고서도 잘 작성하시기 바랍니다. 전반적으로 높은 점수를 드렸습니다.

위드로봇 불법 주차 단속을 무인으로 할 수 있다는 점에서 작품성이 높다고 생각합니다. 서버에서 문자 인식을 하도록 되어 있는데, 이럴 경우라면 단순히 사진을 찍어서 압축한 뒤 서버에서 처리하는 것이 나으며, 더 좋은 방법은 라즈베리파이에서 직접 문자 인식을 수행하도록 구성하면 완성도가 높은 작품이 될 것 같습니다. 보고서 내용 만으론 어느 정도 인식률로 동작했는지 알 수가 없어 완성도 부분에서 점수가 차감되었습니다.

2. 작품 개요
2.1. 작품 소개
장애인 전용주차구역에 장애인 차량 외의 차량이 주차할 경우 경보음을 내고, 차량의 번호판을 관리자 서버에 바로 전송합니다.
2.1.1. 기획의도
· 매년 장애인 구역에 불법주차차량증가
· 장애인 전용주차 구역에 불법주차 된 차량이 보여도 애플리케이션을 다운받아서 신고해야하는 번거로움이 있어 대부분 그냥 보고 넘김
· 장애인 전용주차구역에 불법 주차된 차량의 수들을 감소시키고, 장애인 분들의 편의 제공을 목표로 함
· 불법주차를 할 수 없게 만들어 주차를 할 수 없는 문화로 만들어서 시민의식을 높여 선진국으로 발전

2.2. 작품의 개발 배경 및 필요성

49 ICT_불법단속 (1)
장애인 주차구역은 걷기가 불편한 사람들을 위해 만들어진 주차시설로 일반 주차 구역에 비해 약 1.5배가 크다. 크기가 넓은 이유는 걷기가 불편한 사람들이 목발이나 휠체어를 이용하는 경우 차를 타고 내릴 때 더 많은 공간을 필요로 하며, 보행 안전 통로가 확보되어야 하기 때문이다. 하지만 다리가 불편한 사람들을 위한 장애인 전용 주차구역에 위반사례들이 매년 급증하고 있다. 대구 지역에서만 보더라고 2014년에는 3,687건, 2015년에는 6,990건, 그리고 2016년에는 10,502건으로 해가 지날수록 거의 2배의 값으로 증가하고 있다.
일일이 단속하는 것에도 어려움이 있다. 장애인 주차 표지를 대여하거나 위변조한 차량은 일일이 근접해서 관찰하지 않으면 식별하기 어렵다. 인력 부족 또한 심각하다. 지난 18일부터 오는 5월 20일까지 실시하는 올 상반기 장애인전용주차구역 집중 점검 기간동안 불법주차 단속에 나서는 복지부 소속 장애인정책과 직원은 8명이 전부다.
현재 시행되고있는 장애인 주차구역신고에 대한 행정망 또한 비효율적이다. 장애인 주차구역 위반 차량을 신고하기 위해서는 생활불편 신고 앱을 다운 받아서 글을 쓰고 사진과 위치까지 올려야 한다. 이것을 올린다 해도 바로 처리되는 것이 아니라 행정업무의 분할로 1건을 처리하는 20~60분 걸린다. 그러면 처리되는 시간동안 그 차량이 빠져나갈 수가 있다. 따라서 이런 현재의 문제상황을 인식하고 증가하는 불법주차 사례를 감소시키기 위해 프로젝트를 하게 되었다.

2.3. 작품의 특징 및 장점
가. 단속 신고 자동화
장애인을 위한 주차 관리 시스템은 장애인 주차 구역 내 차량 주차 시 차량 번호를 추출하고 기존 데이터베이스와 대조하여 장애인 차량인지 확인한다. 미등록 차량일 경우 즉시 데이터를 전송하여 신고를 자동화한다.

나. 장애인 차량 주차증 불필요
기존의 장애인 주차 구역 단속은 장애인 등록 차량이라도 장애인 주차증을 분실하거나 부착하지 않을 경우 단속의 대상이 된다. 또한 주차증의 허점을 이용해 차량 번호와 장애인 자동차 스티커에 새겨진 번호가 다른 경우나 주차증을 위변조하여 부착하는 등 단속을 피한 장애인 주차 구역 주정차 위반 사례가 발견되고 있다.
하지만 장애인을 위한 주차 관리 시스템은 장애인 주차 구역에 차량 주차 시 장애인 차량인지 확인하고 미등록 차량임을 인식하는 즉시 신고하기 때문에 스티커 부착 유무나 위변조와 관련 없이 정확한 단속을 할 수 있다.

다. 일반 주차 관리 시스템과 차이
기존에 상용화된 주차 관리 시스템은 주차장 입구에서 차량 번호 영상을 인식하는 것에 비해 장애인을 위한 주차 관리 시스템은 장애인 주차 구역 내 주차 시 데이터를 추출한다. 이로 인해 현재 특정 차량이 어느 구역에 주차되어 있는지를 알 수 있다.

라. 장애인 주차 구역 관리 시스템 부재 해결
장애인 주차 구역에 대해서는 대수롭지 않다는 인식이 만연하여 주차 위반에 대한 문제점 또한 크게 의식되지 않고 있기 때문인지 장애인 주차 구역 통제 시스템이 제대로 마련되어 있지 않다. 장애인을 위한 주차 관리 시스템은 이러한 부재를 메꿀 새로운 시스템이다.

3. 작품 설명
3.1. 주요 동작 및 특징

49 ICT_불법단속 (1)

차량이 들어오면 일단 인지를 하고, 카메라를 이용하여 차량 번호 판을 인식하여 이 차량이 장애인 차량인지 비장애인 차량인지 구별을 한다. 만약 비장애인 차량이라면 경보음을 울리고 데이터가 관리자에게 전송된다.
3.2. 전체 시스템 구성

49 ICT_불법단속 (2)

차량이 들어오면 일단 인지를 하고, 카메라를 이용하여 차량 번호판을 인식하여 이 차량이 장애인 차량인지 비장애인 차량인지 구별을 한다. 만약 비장애인 차량이라면 경보음을 울리고 데이터가 관리자에게 전송된다.

49 ICT_불법단속 (3)

3.3. 개발 환경

49 ICT_불법단속 (4)
4. 단계별 제작 과정
초음파센서 알고리즘

49 ICT_불법단속 (5)

쉘스크립트 알고리즘

49 ICT_불법단속 (6)

데이터베이스 저장화면

49 ICT_불법단속 (2)

번호판 인식화면

49 ICT_불법단속 (3)

홈페이지 저장화면

49 ICT_불법단속 (7)

5. 기타
5.1. 작품의 기대효과
가. 단속 인력 최소화 및 효율적 행정 처리
장애인을 위한 주차 관리 시스템은 단속 신고 자동화를 내세우고 있어 단속 관련 업무를 최소화하고 업무 처리에 소비되는 시간을 단축시킬 수 있다. 또한 신고 자동화로 인한 항시 단속으로 단속 인력 부족에 대한 문제를 해결할 수 있으며 단속 신고 포상과 관련된 비용을 축소할 수 있다.

나. 인식 개선
단속 업무 자동화로 인해 불법 주차 차량에 대한 확실한 증거를 확보하게 되고, 확증이 생긴 단속 대상은 결격 사유에 해당하지 않기 때문에 자동으로 과태료 부과 대상이 된다. 항시 단속하여 불법 주차 차량이 신속히 적발되어 처벌되면 장애인 주차 구역에 대한 인식 개선을 노릴 수 있다.

다. 불법 주차 감소
수시로 단속하여 쉽게 처벌 대상이 되고 주차 구역 위반에 대한 인식이 변화하면 불법 주차 차량의 감소를 기대할 수 있다. 이로 인해 장애인 전용 주차 구역이 필요한 이들이 마땅한 자리를 얻을 수 있다.

라. 시민의식 함양
불법 주차 감소함에 따라 불법에 대하여 하지 못하도록 사회 인식을 바꾸고 대한민국 사회에서 불법을 하지 않는 나라로 바뀌어 시민의식을 깨우치고 조금 더 선진국으로 나아가는 방향을 기대하여 본다.

마. 불법 주차 처리성
지금 현재 불법 주차 시에 어플리케이션으로 신고를 하게 되면 신고를 처리하면 신고처리를 하는 시간이 1시간정도의 시간이 걸리는 데 주차공간에 있는 차량이 빠져나오는데 이렇게 오랜 시간이 걸리게 되면 정작 주차를 하려고 하였던 장애인 차량은 기다리기만 할 수도 없는 노릇이다. 하지만 이 시스템을 사용하게 되면 불법 주차로 간주되는 즉시 바로 경고음과 주차관리자 및 교통과 관리자에게 통보가 되므로 불법주차 차량을 바로 빠져나오게 할 수 있다. 이렇게 되면 기다리는 사람도 발생하지 않아 고생하지 않아도 된다.

5.2. 프로젝트를 통해 배우거나 느낀 점
비효율적인 행정 처리
민원은 많지만 이를 수용할 인력도 효율적인 프로세스도 없다. 또한 20%가량의 민원은 정보가 부족하다는 이유로 처리되지 않는다. 이러한 문제점은 민원이 민원을 만들어 낸다고 생각했다. 즉각 단속이 가능해 진다면 처리 속도는 물론이고 단속 인원도 필요없다. 무엇보다 중요한 것은 정보가 부족하다는 이유로 민원이 처리 되지 않는 일은 없을 것이다.

인식 개선
많은 기사를 통해 놀라운 문구를 접했다.
“장애인 구역에 주차하면 어때서?”, “장애인 주차 구역에 주차한 시장”, “장애인 주차 구역 주차 후 과태료 물자 도리어 화를 낸다.” 이렇듯 많은 사람들이 장애인 주차공간에 주차하는 것을 별것 아니라고 생각한다. 이런 생각들이 쌓여서 현재 수많은 민원과 민원에 따른 행정 업무가 필요해졌다. 불법 주차 시 즉각 단속을 할 수 있다면 장애인 주차 구역에 주차를 하지 않을 것이며 추후에는 인식 개선으로 이어질 것이다. 장애인 주차 구역뿐만 아니라 무단 행단과 음주 운전 같이 쉽게 어겨지는 행위들도 즉각 단속을 통한 인식 개선이 필요하다고 느낀다.

5.3. 영상처리 소스코드

#include <opencv2/opencv.hpp>

#include <iostream>
#include <cstdlib>
#include <stack>

using namespace cv;
using namespace std;

int main()
{
Mat image, image1, image2, image3, drawing;
Rect rect, temp_rect;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
double ratio, delta_x, delta_y, gradient;
int select, plate_width, count, friend_count = 0, refinery_count = 0;
stack<int> Stack;
stack<int> Stack2;
image = imread(“C:\\Users\\aucun\\Documents\\Visual Studio 2018\\Projects\\opencv_basic\\Plates\\3.JPG”); // 이미지 읽기

imshow(“Original”, image);
waitKey(0);

image.copyTo(image2); // 이미지 복사
image.copyTo(image3);

cvtColor(image2, image2, CV_BGR2GRAY); // 회색으로 변환
imshow(“Original->Gray”, image2);
waitKey(0);

Canny(image2, image2, 100, 300, 3); // 외각선 추출
imshow(“Original->Gray->Canny”, image2);
waitKey(0);

 

// Finding contours.
findContours(image2, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point());
vector<vector<Point> > contours_poly(contours.size());
vector<Rect> boundRect(contours.size());
vector<Rect> boundRect2(contours.size());

for (int i = 0; i< contours.size(); i++) {
approxPolyDP(Mat(contours[i]), contours_poly[i], 1, true);
boundRect[i] = boundingRect(Mat(contours_poly[i]));
}

drawing = Mat::zeros(image2.size(), CV_8UC3);

for (int i = 0; i< contours.size(); i++) {

ratio = (double)boundRect[i].height / boundRect[i].width;

if ((ratio <= 2.5) && (ratio >= 0.5) && (boundRect[i].area() <= 700) && (boundRect[i].area() >= 100)) {

drawContours(drawing, contours, i, Scalar(0, 255, 255), 1, 8, hierarchy, 0, Point());
rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), Scalar(255, 0, 0), 1, 8, 0);

boundRect2[refinery_count] = boundRect[i];
refinery_count += 1;
}
}

boundRect2.resize(refinery_count);

imshow(“Original->Gray->Canny->Contours&Rectangles”, drawing);
waitKey(0);

// Bubble Sort accordance with X-coordinate.
for (int i = 0; i<boundRect2.size(); i++) {
for (int j = 0; j<(boundRect2.size() – i); j++) {
if (boundRect2[j].tl().x > boundRect2[j + 1].tl().x) {
temp_rect = boundRect2[j];
boundRect2[j] = boundRect2[j + 1];
boundRect2[j + 1] = temp_rect;
}
}
}
for (int i = 0; i< boundRect2.size(); i++) {
rectangle(image3, boundRect2[i].tl(), boundRect2[i].br(), Scalar(0, 255, 0), 1, 8, 0);
count = 0;
// Snake moves to right, for eating his freind.
for (int j = i + 1; j<boundRect2.size(); j++) {

delta_x = abs(boundRect2[j].tl().x – boundRect2[i].tl().x);

if (delta_x > 150) // Can’t eat snake friend too far ^-^.
break;
delta_y = abs(boundRect2[j].tl().y – boundRect2[i].tl().y);
if (delta_x == 0) {
delta_x = 1;
}
if (delta_y == 0) {
delta_y = 1;
}
gradient = delta_y / delta_x;
//cout << i << endl;

if (gradient < 0.25) {
count++;

if (!Stack.empty()) {
if ((boundRect2[j].tl().x > (boundRect2[Stack.top()].tl().x + (boundRect2[Stack.top()].width / 2)))) {
Stack.push(j);
}
}
else {
Stack.push(j);
}
}
}
if (count > friend_count) {
while (!Stack2.empty()) Stack2.pop();
while (!Stack.empty()) {
Stack2.push(Stack.top());
Stack.pop();
cout << Stack2.top() << endl;
}
select = i;
friend_count = count;
rectangle(image3, boundRect2[select].tl(), boundRect2[select].br(), Scalar(255, 0, 0), 1, 8, 0);
plate_width = delta_x;
}
while (!Stack.empty()) Stack.pop(); //스택 비우기
} // 네모칸을 이미지에 표시
rectangle(image3, boundRect2[select].tl(), boundRect2[select].br(), Scalar(0, 0, 255), 2, 8, 0);
line(image3, boundRect2[select].tl(), Point(boundRect2[select].tl().x + plate_width, boundRect2[select].tl().y), Scalar(0, 0, 255), 1, 8, 0);

imshow(“Rectangles on original”, image3);
waitKey(0);
image(Rect(boundRect2[select].tl().x, boundRect2[select].tl().y , boundRect2[select].width, boundRect2[select].height)).copyTo(image1);//차번호판 부분만 복사
resize(image1, image1, Size(image1.cols*4, image1.rows*4), 0, 0, CV_INTER_LINEAR);//크기 조정

int k;
for (int i = 0; i < friend_count-1; i++) {
if (!Stack2.empty()) {
k = Stack2.top();
Stack2.pop();
image(Rect(boundRect2[k].tl().x, boundRect2[k].tl().y, boundRect2[k].width, boundRect2[k].height)).copyTo(image1);//숫자나 문자 하나씩 추출
resize(image1, image1, Size(image1.cols * 4, image1.rows * 4), 0, 0, CV_INTER_LINEAR);//크기 조정
imwrite(“C:\\Users\\aucun\\Desktop\\test\\” + to_string(i + 2) + “.JPG”, image1);//잘려진 사진을 저장
}
}
// Shows license plate, and save image file.
imshow(“Region of interest”, image1);
waitKey(0);
//imwrite(“C:\\Users\\aucun\\Desktop\\test\\1.JPG”, image1);
exit(0);
}

ㅇ라즈베리파이 쉘스크립트
#/!/bin/bash

flag=1
for((;;))

do
echo $flag
check=`./test`
echo $check

if [ $check = "carin" -a ${flag} == 1 ] then
flag=0
raspistill -o car.jpg

var=`curl -F myfile=@/home/pi/test/car.jpg http://han.mysterlee.com/a.jsp`

echo $var

if [ $var = "8" ] then
echo “장애인차”
echo $var

else
echo “비장애인차”
echo $var
./jong

#else if [ $var = "1" ] #echo “인식안됨 or 오류”
#./jong

fi

fi
if [ $check = "carout" ] then
flag=1
fi
done

exit 0

 

 

 

 

Leave A Comment

*