프로그래머스 탑 문제

배열의 끝부터 봅니다. 배열의 끝부터 하나씩 자기보다 왼쪽에 있는 것중에 값이 보다 큰 곳의 인덱스를 저장하면 됩니다. 만약 자기보다 큰게 없다면 0을 저장하면 됩니다.

탑.cpp

#include <string>
#include <vector>

using namespace std;

vector<int> solution(vector<int> heights) {
    int heights_size = heights.size();
    vector<int> answer(heights_size, 0);

    for(int i=heights_size-1 ; i>=0; --i)
    {
        int iter = i;
        while(iter--) 
        {
            if(heights[iter] > heights[i])
            {
                answer[i] = iter+1;
                break;
            }
        }
    }
    return answer;
}

프로그래머스 문자열 압축 문제

1 ~ i번째의 문자열씩 끊어가면서 모든 문자를 확인한다. 같은 문자열일 경우 반복 횟수(count)를 1씩 증가시키고, 다른 문자열일 경우 여태 반복된 문자열 정보를 추가한 뒤(반복 횟수 + 문자열) 반복 횟수를 1로 초기화한 후 다시 같은 작업을 반복한다.

문자열 압축.cpp

#include <string>
#include <vector>
#include <iostream>
using namespace std;

int solution(string s) {
    int answer = s.length();
    int len = s.size();

    // i는 부분 문자열의 길이
    // 문자열 길이의 절반까지 반복
    for(int i=1; i <= len / 2; ++i)
    {
        int count = 1; // 반복 횟수, 초기화를 1회로
        string temp_answer = "";
        string pre_sub = s.substr(0, i); // i번째 글자까지

        for(int j=i; j<len; j+=i)
        {
            string now_sub = s.substr(j, i);
            if(pre_sub == now_sub) // 반복되는 경우
            {
                count++;
            }
            else // 반복되지 않을 경우
            {
                if(count == 1)
                {
                    temp_answer = temp_answer + pre_sub;
                }
                else
                {
                    temp_answer = temp_answer + to_string(count) + pre_sub;
                    count = 1; // 다시 반복횟수 1로
                }
                pre_sub = now_sub; // 새로운 문자열이 반복되는지 체크하기 위해
            }
            if(j+i >= len)
            {
                if(count == 1)
                {
                    temp_answer = temp_answer + s.substr(j);
                }
                else
                {
                    temp_answer = temp_answer + to_string(count) + pre_sub + s.substr(j);
                }
                break;
            }
        }
        answer = (answer < temp_answer.length()) ? answer : temp_answer.length();
    }
    return answer;
}

프로그래머스 완주하지 못한 선수 문제

두 가지 방법이 생각났습니다. 하나는 participant, completion을 각각 sort하고 위에서부터 하나씩 비교하는 것과 map을 이용하는 것이였는데 map을 사용하여 풀었습니다.

이름(key)이 들어오면 1씩 증가시키고, 완주했을 경우 1씩 감소시킨 뒤 0이 아닌 값을 출력하는 간단한 방법입니다.

완주하지 못한 선수.cpp

#include <string>
#include <vector>
#include <map>
#include <iostream>
using namespace std;

string solution(vector<string> participant, vector<string> completion) {
    string answer = "";
    map<string, int> m;

    for(auto name : participant)
    {
        m[name]++;
    }

    for(auto name : completion)
    {
        m[name]--;
    }

    for(auto kv : m)
    {
        if(kv.second != 0)
        {
            answer = kv.first;
            break;
        }
    }

    return answer;
}

'알고리즘 & SQL > 프로그래머스' 카테고리의 다른 글

프로그래머스 탑 C++  (0) 2020.01.20
프로그래머스 문자열 압축 C++  (0) 2020.01.20

Bus-only traffic light detection in real-time images

자율 주행에 필요한 신호등 인식 기술에 관한 프로젝트.

딥 러닝을 통해 신호등을 인식하는 모델을 구현했다. 기존의 신호등 인식 모델이 신호등의 위치를 인식하거나 신호의 색(적색, 청색 등)을 구분하는 방향에 집중하였다. 한국의 중앙차로가 있는 신호에는 중앙차로를 위한 신호등, 그 외를 위한 신호등이 같이 있지만 기존의 인식 방법으로는 불가능했다. 그래서 중앙차로 전용 신호와 일반 신호등을 구분하는 프로젝트를 진행했다.

 

첫째로 어떤 방법을 통해서 신호등을 구분하여 인식할 것인지를 결정했다. 자율 주행에서 신호등 인식은 실시간으로 수행되어야 하기 때문에 입력되는 이미지를 초당 30장 이상 처리를 할 수 있어야 했다. 또 신호등을 인식하는 것 뿐 아니라 신호등의 모양(일반 신호, 버스 모양 신호)도 구분해내야 했기 때문에 입력 이미지의 작은 개체를 높은 정확도로 탐지해낼 수 있어야 했다. 이에 적합한 것으로 YOLO와 SSD 모델이 있는데, 이번 프로젝트에서는 YOLOv3를 사용하여 탐지하기로 하였다.

 

두번째로 모델을 학습하기 위해 데이터셋이 필요했는데, 버스 신호등을 따로 모은 데이터셋이 없었다. 데이터셋을 확보하기 위해 직접 차량 주행 중 동영상을 찍고 프레임으로 나누어 데이터셋을 확보했다.

 

세번째로 확보한 데이터셋으로 YOLOv3 모델을 학습했으나, 성능이 좋지 않았다. YOLOv3에는 여러가지 모델이 있는데 그 중 3개(YOLOv3, YOLOv3-spp, YOLOv3-tiny)를 골라 각각에 대해 학습을 했다. 결과에서 모델의 깊이가 가장 얕은 YOLOv3-tiny가 다른 모델과 비교해서 뒤쳐지지 않는 성능을 갖는 것을 알게 됐다. YOLOv3-tiny를 수정해서 성능을 더 높이는 방향으로 정했다.

 

학습 데이터셋의 해상도가 2288x1080이였고, YOLOv3-tiny는 기본적으로 416x416으로 Resizing한 뒤 학습을 하도록 설정이 되어 있다. 2288x1080의 이미지에서 신호등은 작은 개체이기 때문에 Resizing 과정 후에 더 작아져 정확도를 낮추는 원인이 되는 것 같아 Resizing 크기를 최대한 크게 키웠다. 1024x1024 까지가 현재 그래픽카드가 수용할 수 있는 최대의 크기였다. 2288x1080에서 1024x1024가 더 높은 정확도를 가지는 결과를 얻어냈다.

 

그 이후에는 기존의 학습 데이터셋(2288x1080)을 두 장으로 잘라냄(1024x1024, 2장)으로 Resizing 과정에서 손실이 없게 학습을 했다. 이를 통해 이전의 모델보다 좋은 성능을 갖는 결과를 얻어냈다. 최종적으로 학습을 통해 92.90%의 mAP를 갖는 모델을 얻을 수 있었다.

 

데이터셋의 크기가 너무 작아 실행해온 방법들이 다른 경우에도 효과가 있는지 확인 하기 위해 신호 표지판 데이터셋인 Tsinghua-Tencent Dataset으로도 같은 방법을 통해 확인해보니 실제로 성능 향상의 효과가 있는 것을 확인했다.

한계점

기존의 목표는 일반 신호등 위에 버스전용, 혹은 중앙차로전용 이라고 기재 되어있는 표지판도 인식을 하는 것이었으나 주행 중인 차량에서 표지판내의 글자 인식은 해결하지 못했다.

'Project > Bus Traffic Light Detection' 카테고리의 다른 글

Presentation(3)  (0) 2020.01.09
Presentation(2)  (0) 2020.01.09
19/05/27 진행상황  (0) 2020.01.09
Presentation(1)  (0) 2019.05.20
19/04/15 진행 상황  (0) 2019.04.16

'Project > Bus Traffic Light Detection' 카테고리의 다른 글

최종 보고서  (2) 2020.01.09
Presentation(2)  (0) 2020.01.09
19/05/27 진행상황  (0) 2020.01.09
Presentation(1)  (0) 2019.05.20
19/04/15 진행 상황  (0) 2019.04.16

+ Recent posts