GeoAI를 이용한 항공사진에서 건물과 비닐하우스 자동 검출

딥러닝을 활용하여 항공사진이나 드론영상에서 건물과 비닐하우스를 자동으로 검출하는 기능에 대한 글입니다. 사각형 영역의 검출(Detection)이 아닌 건물이나 비닐하우스의 형상을 검출(Segmentation)하는 방식입니다. CNN을 활용한 다양한 모델 중 Mask R-CNN 신경망을 커스터마이징하여 이용 했습니다. 신경망 학습을 위해 구축한 건물과 비닐하우스의 개수는 아래와 같습니다.

“사람”에 대한 검출을 위해 구축된 ImageNet 등의 데이터 갯수가 수천만개라는 것과 비교 했을때, 위의 구축 건수는 상대적으로 극히 적습니다.

딥러닝 프레임워크를 활용하여 24 Epoch만큼 학습하고 몇가지 영상 이미지를 학습된 신경망에 입력해 건물과 비닐하우스를 검출하는 테스트 결과는 아래의 동영상과 같습니다.

테스트를 웹에서 바로 수행할 수 있어, 추후 다양한 서비스에 쉽게 접목할 수 있도록 하였습니다. 결과를 보시면 몇개의 건물과 비닐하우스를 검출하지 못하지만, 대체적으로 건물과 비닐하우스를 잘 검출하는 것을 볼 수 있습니다. 보다 정확한 검출 위해서는 더 많은 학습 데이터를 구축하고, 좀더 효율적인 신경망과 다양한 학습방법을 시도함으로써 얻을 수 있습니다.

학습 DB의 구축은 자체적으로 개발한 GeoAI Labeling Tool을 사용였으며 자세한 소개는 아래와 같습니다.

GeoAI Labeling Tool 소개

GeoAI 레이블링 툴은 항공영상이나 드론영상에 대해 Detection과 Segmentation을 위한 데이터를 빠르게 구축하고 신경망 학습을 위한 데이터셋을 바로 제작할 수 있는 툴입니다.

끝으로, GeoAI를 이용해 영상으로부터 건물이나 비닐하우스 등과 같은 객체 검출의 용도를 생각해 보면.. 동일한 위치의 서로 다른 시간대에 촬영된 영상을 통해 새로운 건축물이 생겨 난 것을 빠르게 검출하고, 이러한 시계열적 건축물의 변화 탐지 통해 허가받지 않은 건축물을 파악하는 업무에 활용할 수 있을 것입니다.

Tibero의 JDBC 연결에 대한 예제

티베로에 대한 JDBC 연결 및 쿼리 예제입니다. 티베로의 JDBC 드라이브에 대한 jar는 티베로가 설치된 디렉토리 client/lib/jar에 tibero6-jdbc.jar 파일 하나입니다.

아래의 코드는 예제 코드입니다. 대부분의 DBMS에 대한 JDBC에 대한 예제 코드가 비슷한 패턴이므로 설명은 생략합니다.

package tstTibero;

import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.ResultSet; 
import java.sql.ResultSetMetaData; 
import java.sql.SQLException; 
import java.sql.Statement;

public class MainEntry {
    private String ip = "192.168.0.254";
    private int port = 8629;
    private String database = "tibero";
    private String user = "sys";
    private String password = "tibero";
	
    private final String DRIVER_NAME = "com.tmax.tibero.jdbc.TbDriver";
    private final String TIBERO_JDBC_URL = "jdbc:tibero:thin:@" + ip + ":" + port + ":" + database;
	
    private Connection conn = null;

    private void connect() {
        try {
	    Class.forName(DRIVER_NAME);
            conn = DriverManager.getConnection(TIBERO_JDBC_URL, user, password);
        } catch(ClassNotFoundException e) {
            System.err.println(e);
        } catch(SQLException e) {
            System.err.println(e);
        }
    }
	
    private void executeQuery() {
        String sql = "select ST_AsText(GEOM) from tstGIS";
        try {
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(sql);
			
            while(rs.next()) {
                System.out.println(rs.getString(1));
            }
        } catch(SQLException e) {
            System.err.println(e);
        }
    }
	
    private void disconnect() {
        if(conn != null) {
            try {
                conn.close();
            } catch(SQLException e) {
                System.err.println(e);
            }
        }
    }
	
    public static void main(String[] args) {
        MainEntry tibero = new MainEntry();
		
        tibero.connect();
        tibero.executeQuery();
        tibero.disconnect();
    }
}

CentOS7에 Tibero6 설치

티베로(Tibero)는 티맥스소프트의 자회사인 티맥스데이터에서 개발한 DBMS이다. 2003년에 처음 배포되었고, 현재 버전 6이 제공되고 있다. 이 글은 CentOS7에서 Tibero6을 설치하는 과정을 정리한 글이다.

다운로드 페이지에서 Tibero6을 Linux 64bits 용으로 다운로드 받는다. 실제 다운로드와 라이선스 발급을 위해 회원 가입이 필요하며 메일 인증을 통해 가입 처리가 이루어진다. 현재 이 글을 작성하는 시점을 기준으로 다운로드 받은 파일명은 tibero6-bin-FS07_CS_1912-linux64-174424-opt.tar.gz 이며, 이 파일을 설치하고자 하는 위치에 이동시킨 후 압축을 푼다. (필자의 경우 /etc/tibero 디렉토리로 하였고 압축을 풀면 tibero6이라는 하위 폴더가 생성되고 이 하위 폴더 안에 압축이 풀림)

tar -zxvf tibero6-bin-FS07_CS_1912-linux64-174424-opt.tar.gz

발급 받은 라이선스 파일은 설치된 디렉토리인 /etc/tibero의 하위 디렉토리인 /etc/tibero/tibero6/license에 복사한다. 참고로 라이선스 파일을 발급받기 위해서는 실치할 서버의 Host Name을 입력해야 하는데 리눅스의 경우 hostname 명령어를 입력해 쉽게 확인이 가능하다.

설치를 위한 좀 더 편리한 방법이 있을지도 모르겠으나, 티베로는 프로그램의 설치를 단순히 압축을 푸는 방식에서 시작해, 환경설정을 직접 콘솔에서 입력해 수행해 줘야 한다. 먼저 /etc/sysctl.conf의 파일에 다음의 내용을 추가한다.

kernel.shmmni = 4096
kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernel.sem = 10000 32000 10000 10000

fs.file-max = 6815744

net.ipv4.ip_local_port_range = 1024 65500

/etc/security/limits.conf 파일에도 다음의 내용을 추가한다.

tibero           soft    nproc           2047
tibero           hard    nproc           16384
tibero           soft    nofile          1024
tibero           hard    nofile          65536

/etc/sysyemd/logind.conf 파일의 내용 중 RemoveIPC=no의 주석을 제거한다.

환경병수를 설정하기 위해 다음을 입력한다.

export TB_HOME=/etc/tibero/tibero6 
export TB_SID=tibero 
export LD_LIBRARY_PATH=$TB_HOME/lib:$TB_HOME/client/lib 
export PATH=$PATH:$TB_HOME/bin:$TB_HOME/client/bin

이제 티베로를 위해 이미 작성된 쉘을 실행한다.

$TB_HOME/config/gen_tip.sh

여기까지가 티베로 서버를 실해하기 위한 준비과정이며, 먼저 티베로 서버를 NOMOUNT 모드로 실행한다.

tbboot nomount

tbsql 프로그램을 통해 티베로 서버에 접속할 수 있으며, 아래처럼 sys 계정으로 초기 암호(tibero)를 지정해 접속한다.

tbsql sys/tibero

SQL> 프롬프트가 뜨면 성공한 것이고, 새로운 ‘tibero'(원한다면 다른 이름도 가능함)라는 이름의 데이터베이스를 생성한다.

create database "tibero" 
  user sys identified by tibero 
  maxinstances 8 
  maxdatafiles 100 character set MSWIN949 
  national character set UTF16 
  logfile 
    group 1 'log001.log' size 100M, 
    group 2 'log002.log' size 100M, 
    group 3 'log003.log' size 100M 
  maxloggroups 255 
  maxlogmembers 8 
  noarchivelog 
    datafile 'system001.dtf' size 100M autoextend on next 100M maxsize unlimited 
    default temporary tablespace TEMP 
      tempfile 'temp001.dtf' size 100M autoextend on next 100M maxsize unlimited 
      extent management local autoallocate 
    undo tablespace UNDO 
      datafile 'undo001.dtf' size 100M autoextend on next 100M maxsize unlimited 
      extent management local autoallocate;

데이터베이스 생성에는 다소 시간이 소요되며, 완료되면 quit를 입력해 tbsql을 종료하고, 티베로 서버를 NORMAL 모드로 실행한다.

tbboot

마지막으로 $TB_HOME/scripts의 system.sh를 실행한다. 실행과정 중 sys와 syscat의 암호를 입력해야 하는데, 각각 tibero와 syscat이다. 또한 중간 중간에 실행할 작업 수행 여부를 묻는데, 특별한 경우가 아닌한 y를 입력해 작업을 수행한다.

이제 티베로 서버가 정상적으로 수행되는지, 확인하기 위해 다음처럼 입력한다.

ps -ef | grep tbsvr

그 결과는 다음과 같다.

티베로 서버의 종료는 tbdown이며, 기본 Listener Port는 8629이다. 그리고 실제 데이터가 저장되는 데이터베이스의 위치는 설치된 티베로의 디렉토리를 기준으로 /etc/tibero/tibero6/database/{데이터베이스명}이다.

PHP 환경설정

/var/log/php-fpm에 로그 파일이 존재함

[로그파일 예시]
[11-Apr-2022 12:27:11] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 16 children, there are 3 idle, and 44 total children
[11-Apr-2022 12:27:12] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 2 idle, and 46 total children
[11-Apr-2022 12:27:15] WARNING: [pool www] server reached pm.max_children setting (50), consider raising it

/etc/php-fpm.d 디렉토리의 www.conf 파일에 pm.max_children 설정값 등이 지정되어 있음