이야...

 

내가 이런거 하는날도 있구나...

 

암튼 이틀간의 삽질의 결과가 너무 아까워서 이렇게 공개합니다

 

현재 이야기 하는건 윈도우 XP (32bit) + VS 2008 에서 입니다.

FTGL을 사용하게 위해서는 Freetype 라이브러리가 필요합니다. 각각의 링크를 따라 들어가서 라이브러리를 받습니다.

Freetype의 압축을 풀고 폴더를 확인 합니다. 본인의 감(?)에 따라 어디로 가야 우리가 원하는게 있을지  폴더를 찍어봅니다...

 

 

 

 

그렇지요...  build 항목에 들어가면 OS 나 개발환경별 컴파일 플랫폼을 제공합니다. win32가 눈에 들어옵니다.

 

 

win32 아래에는 위와 같이 각 환경별로 제공하는 *.dsw 또는 *.sln이 있습니다.

 

많은 공개 코드를 써본건 아니자만 이것처럼 친절한 라이브러리는 처음이네요. 암튼 2008로 들어가서 생각없이 "빌드"질을 해 대시면 됩니다. 그러면 ft2312_D.lib (Debug) 와 ft2312.lib (Release)를 object/win32 아래에서 만나실 수 있습니다. 상당히 다양한 컴파일 옵션이 있습니다. 일반모드와 cpu에 따른 모드가 있는데 저는 그냥 기본적인 Debug와 Release 모드만을 사용하였습니다.

 

이제 재료가 다 준비 되었으니 라이브러리와 header들을 옮깁니다...

-hearder파일은 include 안에 있는 것을 모두 include폴더로 ...

-lib 들은 lib폴더로 ...

-2008의 경우는 program files/v_ s_ 9.0 폴더의 vc폴더 아래에도 넣어도 되지만 program files/windows SDKs/Windows/v6.0a 에도 가능... 특별이 gl 폴더는 v_ s_ 9.0 이 아닌 windows SDKs 아래에 있음...

 

이제 FTGL 컴파일을 합시다

 

FTGL 도 매우친철합니다. msvc 폴더를 유심히 봅니다. msvc ... microsoft visual studio... 그렇지요...

 

아래에 내려가면 vc 8.0  vc7.1 버젼의 환경이 있습니다.  8.0은 2005 이고 7.1은 2003 인가 그럴겁니다...

8.0을 선택하고 2008 에서 열면 무리없이 컨버젼 됩니다.  걍 컴파일 합니다.  그러면  현재위치에서 한번만 위로 올라가면 못보던 Build라는 폴더가 만들어져 있고 그곳에 다 모여 있습니다. (*.dll, *lib, 등등...)

이제 적당한 위치에 옮겨두면 OK... 사용준비 완료 입니다...

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

일거 같지요... ??

 

확실하지는 않으나 win64 bit에서는 문제가 없는데 32bit XP에서 사용하려면 문제가 발생합니다. 아마 환경에 따라서 전처리자가 결정이 안되는것 때문에  이 라이브러리로 visual studio 6.0 에서 개발하신다면 꽤나 애 먹으실 겁니다. dll에 구현되어 있는 함수가 제대로 export가 안되었을때 나오는 에러 메세지를 보게 되실겁니다. 즉,

 

error LNK2001: unresolved external symbol "public: virtual class FTBBox __thiscall FTFont::BBox(unsigned short const*,int,class FTPoint,class FTPoint)" (?BBox@FTFont@@UAE?AVFTBBox@@PBGHVFTPoint@@1@Z)

 

이와 비슷한것을 두개 더 보게 되실겁니다

 (현재까지 제 경험상 winXP에서 OpenGL이 가장 원활하게 돌아갑니다. 그리고 저는 아직도 visual studio 6.0 을 못 버리고 있구요.)

 

다시 FTGL 컴파일 하는곳으로 돌아갑니다.

ftgl.dll 속성으로 들어가서 구성속성->c/c++->언어->wchar_t를 기본제공 형식으로 처리 를 예 에서 아니오로 바꾸고 다시 컴파일 하면 위의 문제는 사라집니다.

 

 

 

 

이건 제가 해결한건 아니고... 구글링 하다보니

http://objectmix.com/graphics/729918-ftgl-visual-studio.html

저와 동일한 문제를 안고 있던 분이 있더군요. 이자리를 질문하고 답변해준 분들께 감사의 말씀을...

 

FTGL을 사용하면 3D 화면상에다 글자를 2D 혹은 3D로 뿌릴 수 있고 각종폰트( 한글)도 자유자제로 쓸 수 있습니다. (OpenGL에서 글자쓰는게 만만한 일은 아닙니다. 특히 2D는... 그렇다고 DC 에다 때려 넣어서 쓰면... 3D perspective 상황에서는 글자도 안 보일겁니다.)

 

아뭏든 이렇게 하고 나면 깨끗한... 그리고 본인이 가장 좋아하는 영문폰트인 verdana를 써서

텍스트를 출력할 수 있습니다

이렇게 말이지요...

 

 

 

 

구글 검색을 통해서 FTGL에 관한 한글정보를 얻으신분들은 자료들이 상당히 오래 되었음을 발견하시게 될겁니다. 그래서 해보려면 상당히 많이 틀린것을 알 수있고 특히 FTGL은 함수들이 상당히 많이 바뀌어서 이 라이브러리 쓰는게 그리 녹녹하지 않았습니다.

 

그냥 instance하게 불러서 작업하신다면 위의같은 처리 안해도 작동합니다.

그런데 가령 위의  FTGL 객체를 class member variable로 동적할당을 하려면  위의 방법으로 하셔야 되지 않을까 합니다.


2차 출처 : http://blog.daum.net/piewani/16768994  

 


http://seunghan.tistory.com/329
http://dorigom.springnote.com/pages/1519772

1. 조건
  - 랜카드에서 Wake-on-LAN 기능 지원
  - Wake-on-LAN 기능을 지원하는 인터넷공유기

2. 바이오스 설정
  - Award BIOS
     .PCI configuration > Onboard LAN Boot ROM : Enable
     .Power > Power Up Control > Power Up On PCI Card :Enable
  - Phoenix BIOS
     .Wake On Lan : Enable

3. 랜카드 설정
  - Realtek 칩셋
     .전원을 절약하기 위해 컴퓨터가 이 장치를 끌 수 있음 : 사용
     .이 장치로 컴퓨터를 대기상태에서 빠져나오게함 : 사용
     .관리 스테이션에서만 대기 모드 상태의 컴퓨터를 해제 시킬 수 있음 : 사용
  - Intel 칩셋
     .전원을 절약하기 위해 컴퓨터가 이 장치를 끌 수 있음 : 사용
     .이 장치로 컴퓨터를 대기상태에서 빠져나오게함 : 사용



4. 시스템 켜기
  - 매직패킷 보내는 유틸 , 사이트
     .WakeOnLanGui 또는 www.depicus.com/wake-on-lan/woli.aspx
       주소 , IP , 서브넷 , 포트 입력후 전송
  - WAKE ON LAN 매직 패킷 프로그램 (첨부파일 다운로드)
    

     .LAN 상에서의 내부 IP 사용한 부팅
       맥 어드레스, LAN IP(내부 IP), 서브넷 255.255.255.0, Local Subnet 선택, 원격포트번호X
     .WAN 상에서의 IP 사용한 부팅
       맥 어드레스, WAN IP(외부 IP), 서브넷 255.255.255.255, internet 선택


WOL(Wake on Lan)편집하기 http://kldp.org/Translations/html/WakeOnLan-KLDP/index.html

What?
특별히 설계된 네트웍 패킷을 사용하여 원격의 컴퓨터를 기동하는 것이다. 이 기능은 네트웍 카드와 마더보드가 Wake on Lan을 지원해야만 제대로 동작한다.

How?
WOL 은 다음과 같은 원리로 동작한다:

PC 를 종료할 때 NIC (네트웍 카드) 은 완전히 꺼진 것은 아닌 상태로 여전히 켜져 있으며, '매직' 패킷이 오는지 살펴보고 있다. 이 패킷은 특정한 문자열 (byte-sequence) 이 포함되어 있어야 하며, 아무 프로토콜 (이를테면 IPX, IP 따위) 에나 얹혀오면 된다. '마법의' 문자열을 만드는 코드를 참조하기 바란다.

이 프로그램은 UDP 를 사용해서 패킷을 보낸다. 이더넷 인터페이스로 전달되는 UDP 패킷의 완전한 모습은 아래와 같은 것이다:

          [ethernet header][IP header][UDP header][Magic sequence][CRCS]
          

스크립트는 단지 이 패킷을 보내는 것으로 족하다. NIC 은 수신만 할 뿐이며 무언가 응답하는 것이 없으므로, 이 패킷을 보낸 후 돌아오는 데이터 등에 대해서는 신경쓰지 않아도 좋다.

프로토콜에 대한 좀 더 상세한 설명은 AMD 백서를 참고하라.



http://www.chocomug.com/tt/chocomug/292

http://www.remotewakeup.com/

http://en.wikipedia.org/wiki/Wake-on-LAN



예제소스
Wake-On-Lan
It’s so sweety to maintain all workstations automatically in, say, 3am at night :) But this requires to turn it all on, and switch off after maintenance. Shutdowning is not a problem, but turning on… Turning on is not a problem too, but <=> your workstations support Wake-On-Lan technology.

Here a small C example how to invoke Wake-On-Lan.

Algo is simple - broadcast UDP magic-packet.

Magic packet consists of:

Six 0xFF bytes
Target MAC address repeated sixteen times.
If, say, target MAC is 32:00:00:23:11:13. Magic packet is

          FF FF FF FF FF FF 32 00 00 23 11 13 32 00 00 23 11 13 32 00 00 23 11 13
          32 00 00 23 11 13 32 00 00 23 11 13 32 00 00 23 11 13 32 00 00 23 11 13
          32 00 00 23 11 13 32 00 00 23 11 13 32 00 00 23 11 13 32 00 00 23 11 13
          32 00 00 23 11 13 32 00 00 23 11 13 32 00 00 23 11 13 32 00 00 23 11 13
          32 00 00 23 11 13
          Ok, ive stop bugging you and here is the code:

          /**
           * wol.c - Wake-On-Lan example.
           *
           * 2008, Michelle Beloshitsky (itanko@li.ru)
           *
           **/
          
          #include "winsock2.h"
          #include "stdio.h"
          
          #define MYPORT 2050
          
          #define MAGIC_PACKET_SIZE 6*17
          
          /**
           * Creates magic packet
           **/
          char* do_magic(char* mac)
          {
              int i; int j;
          
              char * res = malloc(MAGIC_PACKET_SIZE);
              memset(res, 0xFF, MAGIC_PACKET_SIZE);
          
              for(i=1;i<17;i++)
              {
                  for(j=0;j<6;j++)
                  {
                     res[i*6+j] = mac[j]; // expected to be at least 6 chars
                  }
              }
              return res;
          }
          
          int main()
          {
              unsigned char test_mac[6] = {0x00, 0x29, 0xED, 0x46, 0xE2, 0x06};
          
              WSADATA wsadata;
              if ( WSAStartup(MAKEWORD(2,2), &wsadata) != 0 )
              {
              printf("WSAStartup() error %i\n", WSAGetLastError());
                  return 1;
              }
          
              SOCKET sock;
              sock = socket(AF_INET,SOCK_DGRAM,0);
              if (sock == INVALID_SOCKET)
              {
                  printf("socket() error %i\n", WSAGetLastError());
                  return 1;
              }
          
              char bc = '1'; // broadcast
          
              if(setsockopt(sock,SOL_SOCKET,SO_BROADCAST,&bc,sizeof(bc)) < 0)
              {
                  printf("setsockopt() error %i\n", WSAGetLastError());
                  closesocket(sock);
                  return 1;
              }
          
              struct sockaddr_in Sender_addr;
          
              Sender_addr.sin_family       = AF_INET;
              Sender_addr.sin_port         = htons(MYPORT);
              Sender_addr.sin_addr.s_addr  = INADDR_BROADCAST;
          
              int res = sendto(sock,
                               do_magic(test_mac),
                               MAGIC_PACKET_SIZE,
                               0,
                               (struct sockaddr_in *)&Sender_addr,
                               sizeof(Sender_addr));
          
              if(res != MAGIC_PACKET_SIZE)
              {
                  printf("sendto() error %i\n", WSAGetLastError());
                  closesocket(sock);
                  return 1;
              }
          
              closesocket(sock);
              WSACleanup();
          }


출처 : 하창호닷컴
http://www.hachangho.com/homev30/bbs/zboard.php?id=tech&page=1&sn1=&divpage=1&category=4&sn=off&ss=on&sc=on&select_arrange=headnum&desc=asc&no=501&PHPSESSID=177452459b75a95fd021a8224ce5a2f5

http://cafe.naver.com/javacircle.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=42875

CFindFile 클래스는

폴더및 하위폴더내의 특정 확장자를 가진 모든파일을의 목록을 만든다든지,,

그 외 작업을 할때에 자주 애용합니당.

//-------------------------------------------------------------

bool MyApp::FindFile( CString path, CString findname )
{
 CFileFind finder;
 bool working = finder.FindFile( path + "\\*.*" );
 while ( working )
 {
  working = finder.FindNextFile();


  if ( finder.IsDots() ) continue;

  if ( finder.IsDirectory() )
  {

    /// 하위폴더를 뒤져본다.

    if ( FindFile( finder.GetFilePath() , findname ) ) return true;   

  }
  else
  {
    CString curfile = finder.GetFileName();
    if ( curfine == findfile )

    {

      // 발견.

      return true;

    }

 

  return false;

}

//-------------------------------------------------------------

 

그리고

FindFile( "C:\\", "test.txt" );

또는

FileFind( ".\\Data", "test.txt" );

이렇게 해주면 파일을 찾겠죵.. -.-

[출처] CFindFile을 이용해서 폴더를 검색|작성자 난뽀다



///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//사용법
  char szFile[MAX_PATH];
  char szDir[MAX_PATH];
  
  strcpy(szFile, "adb.exe");
  strcpy(szDir,  "c:\\temp");
  
  SetCurrentDirectory(szDir);

  if(SearchDirectory(szFile)) {
    //파일 검색성공
  }


/**
* 현재 폴더(하위폴더 포함) 파일을 검색한다.
*
* @param [in] 검색파일
* @param [in] 하위폴더
*
* @return 검색에 성공시 TRUE 반환
*/

BOOL SearchDirectory( const char* szFile, const char *szPath=_T(""))
{
  CString szSearchPath = szPath;
  char pFileName[MAX_PATH];
  int nSearchPathLen;
  BOOL bSearch = FALSE;

  WIN32_FIND_DATA info;

  // 현재 경로의 모든 파일과 디렉토리를 찾는다.
  HANDLE searchHandle = FindFirstFile(szSearchPath + "*.*"&info);
  if(INVALID_HANDLE_VALUE != searchHandle) {
    do{
      if(FILE_ATTRIBUTE_DIRECTORY & info.dwFileAttributes)
      {
        // 폴더의 경우
        // 현재 폴더(.)와 이전폴더("..")는 검색에서 제외
        if(info.cFileName[ 0 ] != '.')
        {
          // 하위 디렉토리를 계속 검색
          bSearch = SearchDirectory(szFile, szSearchPath + info.cFileName + CString("\\"));
          if(bSearch)
            break;
        }
      } 
      else 
      {        
        nSearchPathLen = strlen( szSearchPath );
        strcpy_s( pFileName, nSearchPathLen + 1, szSearchPath );
        strcpy_s( pFileName + nSearchPathLen, strlen( info.cFileName ) + 1, info.cFileName );

        TRACE("File> %s \n", pFileName);
        //찾는 문자열인지 체크
        if(strcmp(info.cFileName, szFile) == 0) {
          bSearch = TRUE;
          break;
        }
      }
    } while(FindNextFile(searchHandle, &info));
    FindClose(searchHandle);
  }

  return bSearch;
}


다이알로그 Enter, ESC 키입력에 대한 종료 막기

매우 많은 방법이 있지만..

1. Enter 키에 대한 종료 막기

다이알로그가 Enter키를 입력받게 되면 OnOK() 함수가 실행되게 되는데
그 부분에 다이알로그를 종료하는 코드가 있다.
새로 만든 다이알로그에서 OnOK() 함수를 오버라이딩 하면 된다.
void CXDialog::OnOK() {}

2. ESC 키에 대한 종료 막기

ESC 키를 입력 받으면 OnCancel() 함수가 실행되어 다이알로그가 종료한다.
역시 OnCancel() 함수를 오버라이딩 하면 되지만,
이렇게 하면 시스템메뉴의 종료또한 동작을 멈추게 된다.
키 입력 메시지가 오면 OnCancel() 이 동작하기 전에 가로 챈다.
BOOL CXDialog::PreTranslateMessage(MSG* pMsg) 
{
// ESC 키 입력에 대한 종료 막기
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
return TRUE;

return CDialog::PreTranslateMessage(pMsg);
}
JPEG, MPEG 표준의 영상처리 기법으로 보통 DCT를 많이씁니다.
신경망 중에서도 classification, feature extracting, pattern recognition 등의 분야에서 DCT를 이용한 영상데이터를 자주 접하지요.
관련 레퍼런스를 정리하는중 DCT, wavelet 등에서 왜 8x8의 블록기반 변환을 사용하는지에 대한 내용이 상당히 부실하게, 또는 전혀 언급되지 않은 자료들이 대부분이란걸 발견하고 매우 놀랐습니다.

뭐.. 이렇게 말하면 제가 영상처리는 기본 베이스로 완벽마스터라도 한것처럼 들리겠네요;;
저도 뭐 아직 공부하는 입장에서 알고있는 사실을 간략하게나마 기술해서, 새로이 공부하는 후학분들의 가려운곳을 살짝 긁어드릴까하고 쓰는 포스팅입니다.

그럼 다시 원론으로 넘어가서.. 왜 8x8의 블록처리인가..

십수년을 거슬러 올라가 때는 바야흐로 1992년..
ISO, CCITT에 의해 JPEG 국제 표준 부호화가 권고되었습니다. 그 내용은 이미지 압축/처리에 대한 방식의 표준화로 이미지의 픽셀들을 가로 세로 8픽셀의 윈도우로 묶어 DCT를 한 후, 그 결과로 나온 DC 및 AC 성분들을 좌측 위에서부터 지그재그 스캐닝하여 8x8 행렬의 2차원 데이터를 64x1 행렬의 1차원 데이터로 변환하자는 표준안이었습니다.

왜 블록으로 묶느냐 하면.. 실제로 256x256 사이즈의 이미지를 한방에 DCT 하자면 연산량의 방대함은 이루말할수도없고 어지간한 컴파일러는 DCT 도중 메모리부족 경고가 뜨며 튕겨버립니다.(..라고 누가 그러던데 전 애초에 256x256을 한방에 DCT해보려는 무모한 시도는 하지도 않았습니다;;)

반면 이미지를 8x8 사이즈의 블록으로 나누어 각기 계산하면 계산량은 물론이거니와 사용하는 메모리의 양, 연산 속도면에서 월등하지요.
실로 체감속도면에선 거의 1/1000 정도 빠르다는게 256x256 과 8x8을 비교해본 사람들의 공통된 주장입니다.

그럼 8x8 B-DCT후 지그재그 스캐닝을 왜 하느냐.

DCT 자체가 이미지(B-DCT같은경우엔 블록)을 코사인함수의 시리즈로 나타내는 방법이며, DCT 후 패턴을 보면 가장 중요한 정보를 담고있는 DC가 최상단 왼쪽구석에 붙고, 우측하단으로 갈수록 쓰잘데기없는 AC성분이 배열됩니다.
AC성분은 보통 Quantization을 통해 0으로 날려버리는 노이즈이지요.
굳이 필요없는 AC는 버리고, 중요한 DC와 DC주변의 계수를 앞으로 배치시키기 위한게 지그재그 스캐닝입니다.

256x256의 이미지를 DCT한다면 지그재그 스캐닝만 해도 엄청난 시간이 들어가겠네요;;

뭐 잡설도 많이붙고, 글이 산으로 가는것같으므로 줄이겠습니다.

국제표준보후화에대한 권고사항에 의해 대부분의 JPEG, MPEG 포맷 영상은 8x8 B-DCT(Block-Discrete Cosine Transform)을 기본으로 하며, 신호 또는 영상을 통째로 DCT할때보다 cost가 싸기때문에 8x8의 B-DCT를 행한다는게 이번 포스팅의 주요내용이었습니다.

2009-09-09
- CNN 이란?
Centroid Neural Network 의 약자로 널리 사용되고있는 신경망 알고리즘 중의 하나이다.
공학박사이자 한국통신학회 신경망학회장인 박동철 교수님께서 고안해내셨고, 그 산하 ICRL 연구실에서 연구에 연구를 거듭하며 계속적으로 개량, 발전시켜 나가고있다. 신경망이란 인간의 두뇌신경과 유사한 매커니즘으로 경험을 통해 학습해 나가는 지능형 컴퓨팅 분야이다.

예를들어 색깔과 그 명칭에 대하여 개념이 잡히지 않은 영유아에게 흰색과 검은색을 반복적으로 보여주고 학습시키면, 어느정도 학습 후 스스로 검은색과 흰색을 구분해 낼 수 있게 되는것가 유사한 것이다. 더욱이 밝은 회색과 어두운 회색을 보여주어도 스스로의 기준으로 어느것이 흰색에 가까운지, 또 어느것이 검은색에 더 가까운지 분류해낼 수 있게 되는 것으로 신경망을 설명할 수 있다.


- CNN의 장점
CNN은 무감독 경쟁 알고리즘으로, 알고리즘을 학습시킴에 있어 사용자가 임의의 기준을 처음부터 제시할 필요가 없다.
CNN은 주어진 데이터를 반복적으로 학습할 뿐이고, 학습중에 데이터들을 분류해 낼 수 있는 스스로의 기준을 잡아간다.
또한 경쟁을 통한 각 승자뉴런과 패배뉴런이 명확히 구분되어, 학습 완료시 어떠한 데이터를 테스트할 경우 애매모호한 분류결과를 내지않는다.


- CNN의 현황
CNN은 고안된지 매우 오래된 알고리즘으로, 다양한 형태의 개량형이 존재한다.
데이터와 centroid간의 가중치를 적용시킨 WCNN 이나, Divergence measure, Mercer kernel을 접목하는 등의 노력을 해왔습니다.
CNN은 현재 영상, 음성 및 다양한 데이터의 clustering에 사용되어지고 있으며 앞으로도 끈임없는 연구로 더 높은 Accuracy와 빠른 속도를 갈구해 나갈것입니다.