안녕하세요. 김대욱입니다. 이번시간에 소개해 드릴내용은 OCR(Optical Character Recognition), 흔이들 문자인식이라고 부르는 기능을 MODI(Microsoft Office Document Image) Libarry를 이용해서 구현하는 방법입니다. 이전에 Tablet SDK를 이용하여 필기인식 방법에대해 소개해 드린바 있었는데요, 이번 시간에는 필기가 아닌 이미지에 포함된 문자를 인식 하는 내용이 되겠습니다. 아래는 시연 동영상 되겠습니다~
먼저 MODI를 사용하기 위해서는 Office 2003 이상의 버전이 설치 되어있어야 하는데요, Office를 설치하실때 아래 그림과 같이 Microsoft Office Document Image를 함께 설치 해주셔야 합니다. (만약 설치 되지 않으셨다면 기능추가/제거 기능을 이용해서 설치 하실 수 있습니다.)
MODI를 사용하시기 위해서는 프로젝트 참조추가에서 아래 그림과 같이 COM 탭에서 Microsoft Office Document Imaging 를 선택하시면 되겠습니다. 저같은경우 Offfice 2007을 설치 했기 때문에 12.0으로 표시 되지만, 2003을 사용하시는 분들은 아마 11.0으로 표시될 것입니다.
실제 MODI를 사용하여 OCR을 구현하기 위해서는 아래와 같이 사용하시면 됩니다. 아래는 샘플 프로젝트에 사용된 인식 관련 함수입니다. 주석이 거의 대부분이고 실체코드는 10줄도 안되니 이해하시는데 무리는 없을것 같습니다 ^^
지금까지 몇몇 이미지로 테스트를 해보았지만, 인식결과는 이미지 상태에 따라 천차 만별인것 같습니다. 5~10도 각도로 회전된 문자에 대해서는 대부분 완벽하게 인식을 수행 하지만, 그이상 혹은 잡음이 많이 포함되어있는 이미지에서는 인식률이 다소 떨어지는것 같습니다.아래는 전체 소스코드입니다.
안녕하세요. 김대욱입니다. 이번시간에는 전시간에 이어 MetaWeblogAPI를 사용해서 간단하게 블로그에 포스팅하는 방법에 대해 알아보도록 하겠습니다. 그리고 이전시간에 구현해놓은 내용을 바탕으로 아래그림과 같이 탐색기에서 마우스 오른쪽 버튼을 눌렀을경우 나타나는 컨텍스트 메뉴에 "블로그에 올리기"라는 메뉴를 추가하는 방법을 소개합니다.
Shell Context Menu(탐색기에서 오른쪽 버튼을 눌렀을때 나타나는 컨텍스트 메뉴)라고 불리는 녀석에 자신이 원하는 새로운 메뉴를 추가하고자 하는 COM을 이용을 하거나, 간단히 레지스트리만 변경하여 간단하게 구현 할 수 있습니다. 이번시간에 소개할 내용은 간단한 레지스트리 조작만으로 메뉴를 추가하는 방법에 대해 소개합니다.
ShellContextMenu는 레지스트리의 아래와 같은형식으로 레지스트리를 수정함으로서 추가가 가능합니다.
SimpleBlogPosting.exe 뒤에 붙어있는 %1은 파라미터를 지정하는 값으로 %1을 붙이면 선택한 파일의 이름이 입력되게 됩니다. 위와 같은 내용을 C#으로 작성하게 되면 아래와 같이 구현하실 수 있습니다. (Registry관련 Class는 Microsoft.Win32에 정의되어 있습니다.)
이번 예제의 경우 아래와 같이 폼의 생성자에서 레지스트리에 작성하는 코드를 추가해서 최초 1회 프로그램이 실행되면 자동으로 Shell ContextMenu에 메뉴가 추가되도록 구현했습니다.
위와 같은 방법을 사용해서 아래 그림과 같은 내용의 프로그램을 구현해 보았습니다.
파일에서 마우스 오른족 버튼을 누르고 네이버 블로그에 사진 올리기를 클릭하게되면 자동으로 블로그에 사진을 올려주는 어플리케이션이 되겠습니다. 이전시간에 말씀드렸다싶이 저희 어머니를 위해 제작된 프로그램이라 아주 단순하면서 기본적인 기능만 수행 가능한 형태로 구현됬습니다만, 응용해서 더 다양한 결과를 만들어 내실 수 있을것이라고 생각됩니다.
이상으로 MetaWeblogAPI + ShellCotextMenu를 이용한 블로그 포스팅내용을 마치도록 하겠습니다.
아래는 이번시간에 사용된 전체소스코드입니다.
안녕하세요. 김대욱입니다. 이번시간에는 MetaWeblogAPI를 사용해서 MetaWeblogAPI를 사용하는 블로그에 원격으로 포스팅하는 방법에대해 소개해 드리려고합니다. 티스토리나 네이버 다음등의 경우 MetaWeblogAPI를 지원하고 있기때문에 이번시간에 소개해 드릴 내용을 활용하시면 간단하게 원격 포스팅 프로그램을 구현하실수 있습니다.
사실 이번 포스팅을 하게된 계기는 저희 어머니께서 예전부터 디카로 찍은 사진을 블로그에 올리고 싶은데 너무 어렵고 힘들다고 해서 어떻게 하면 간단하게 사진을 올릴 수 있도록 할까.. 고민하다가 간단한 프로그램을 제작해서 선물(?)로 드리고자 구현하면서 내용을 그냥 버리기엔아까워서 포스팅하게 되었습니다 !! ㅎㅎ 아직 완전히 구현된게 아니기 때문에 이번 시간에는 스크린샷은 없지만 완성이 되는대로 스샷과 함께 2번째 포스팅을 하도록 하겠습니다 ㅎ
MetaWeblogAPI는 간단하게 말하면 외부 프로그램을 사용해 블로그에 글을 쓰거나, 수정, 삭제 등을 가능케하는 API라고 할 수 있으며 위키페디아 사전에는 아래와 같이 설명되어 있습니다.
The MetaWeblog API is an application programming interface created by software developer Dave Winer that enables weblog entries to be written, edited, and deleted using web services.
그럼 본격적으로 어떻게 하면 C#을 이용해서 MetaWeblogAPI를 사용할 수 있는가에 대해서 살펴보도록 하겠습니다.
MetaWeblogAPI 는 Application과 Server 간의 통신을 위해 XML-RPC 프로토콜을 사용합니다. XML-PRC 프로토콜을 사용하기 위해서 http://www.xml-rpc.net/에서 제공하는 .Net Framework용 라이브러리를 사용했으며, MSDN에도 이를 사용하는 방법에대해 명시되어 있습니다.(http://msdn.microsoft.com/ko-kr/library/bb259697.aspx)
(MSDN에 기본적인 사용방법은 잘 설명이 되어 있기 때문에 저는 이를 사용한 예제 코드 위주로 설명하겠습니다.)
제가 MetaWeblogAPI를 이용해서 구현하고자하는 목표는 단순하게 "블로그에 사진을 올리자!" 이기때문에 새로운 글을작성하는 newpost메서드와 파일을 블로그 서버에 업로드 하는 newMediaObject 메서드를 아래와 같이 구현했습니다. 이외에 서버로 포스팅내용과 첨부파일을 전송하기 위하여 MetaWeblogAPI에 맞춰 Post Class와 MediaObject Class를 구현했습니다. 아래는 제가 사용한 클래스의 전체 소스코드입니다.
XmlRpcClientProtocol를 상속받아 구현한 MetaWeblogAPI클래스에 XmlRpcUrl Attribute를 사용해 BlogAPI의 주소를 입력합니다. 그리고 그리고 MetaWeblog API 에 따라 newpost, newMediaObject메서드를 구현했습니다. XmlRpcClientProtocol의 Invoke메서드를 호출하게 되면 입력한 내용에 따라 기능을 수행하는데, 이때 XmlRpcClientProtocol에서 메서드 명과 파라미터 구조등을 기반으로 통신하게될 XML Data를 구성하기 때문에 대소문자등에 주의 하시기 바랍니다.
그리고 아래 CreateMediaObject는 파일을 업로드 하기 위한 MediaObject객체를 생성하기 위한 메서드입니다. 해당 파일의 내용을 읽고 Content Type을 지정해주는 역할을 합니다. Content Type을 지정하기 위해서 레지스트리에 등록된 Content Type을 검색하도록 구현했으며 없을경우 Appliation/[확장자] 형태로 입력되도록 했습니다.
실제로 사용할 때에는 아래와 같이 사용하시면 되겠습니다.
newPost를 호출할때나, newMediaObject를 호출할때 ID를 두번 입력하는것을 확인 할 수 있는데, 이는 Naver의경우 BlogID가 UserID와 동일하기 때문입니다. (티스토리등에서는 제공하는 Blog ID를 입력하시면되겠습니다.)
이제 PostTest 메서드를 호출하게 되면 아래와 같이 글과 함께 첨부한그림이 정상적으로 출력되는것을 확인하실 수 있습니다.
이것으로 이번 포스팅은 마치며 다음포스팅에서는 실제 UI와 함께 동작하는 과정을 보면서 설명드리도록하겠습니다.(작성하고 보니까 글이 굉장히 많아서인지 상당히 지루해보이네요..)
아래는 이번시간에 사용된 전체 소스코드 입니다. 테스트시 아이디 비밀번호 입력 부분을 본인의 아이디와 비밀번호를 입력하시기 바랍니다. 저희 어머니께서 사용하시는 블로그가 네이버블로그라서 내용이 기준으로 작성되어 있습니다. 테스트를 하시기 위해서는 네이버에서 블로그를 이용해 테스트 하시거나 MetaWeblogAPI의 XmlRpcUrl을 테스트하고자하는 블로그 API주소로 변경하시기바랍니다.
안녕하세요. 이번시간에는 Windows Mobile과 Motion Sensor가 탑제된 단말기에서 Sensor Data를 취득하기 위한 Library의 구현에 대해 알아보도록 하겠습니다. 테스트는 얼마전에 구입한 옴니아로 진행했으며 정상적으로 동작되는것을 확인 했습니다. 제가 특별히 동영상 촬영 장비가 없기때문에 이번 시간 구현 결과물은 영상으로 준비는 못했습니다요 ㅜㅜ 직접 실행 하시게 되면 아래와 같은 동작 화면을 확인 하실 수 있습니다. (이번시간 내용은 특별하게 UI를 고려하지 않아서 매우 심플합니다...... ㅎㅎ)
아직까지는 .Net CF를 사용하여 Windows Mobile을 개발하는 사람이 많질 않아서(최근에 점점 늘어나고 있다고합니다.) 그런지 당현이 있을 거라 생각했던 C#으로 구현된 Motion Sensor관련 코드가가 없는거 같아서 (대부분 C++로 구현되어 있더라구요..) 새로 구현하게 되었습니다. C#으로 구현했다고해서 기존 방식과 전혀 다른 방식으로 구현했다는 뜻은 아니며 기존의 C++로 구현된 내용을 C#으로 포팅 한것정도로 생각하시면 되겠습니다.
포팅시에 참고한 코드는 예전에 옴니아 소프트웨어공모전에서 삼성전자에서 배포한 MotionSensor관련 코드를 거의 그대로 포팅하고 몇가지 편리 기능정도만 추가 및 간단한 최적화 정도만 진행 한거라 잠재되어 있는 버그가 존재 할 수 있습니다.
간단하게 구조를 살펴보면 MotionSensorData, MotionSensorDataType, MotionSensor로 구성되어 있습니다. 각각의 항목에 대해 설명하면 아래와 같습니다.
- MotionSensorData : Motion Sensor로부터 수신한 XYZ축의 SensorData를 포함할수 있는 Structure입니다.
- MotionSensorDataType : MotionSensor와 통신할때 요청할 데이터 Type에 대한 Enum입니다.
- MotionSensor: 실제 Motion Sensor와 통신하는데 사용하는 Class입니다.
MotionSensor Class의 소스코드는 아래와 같으며 설명은 주석에 포함시켰습니다.
※ 포인터를 사용하여 디바이스와 통신을 수행하기 때문에 unsafe 키워드를 사용했습니다.
그리고 아래는 실제 코드에서 MotionSensor객체를 사용하는 방법에 대해 설명입니다.
간단하게 MotionSensor객체를 생성하고 GetMotionSensorData()를 호출하거나 X,Y,Z Property를 바로 사용하시면 되겠습니다.
단, X,Y,Z Property를 사용하실때에는 해당 Property를 요청할때마다 데이터를 다시 수신하게 되므로 하나의 루틴에서는 해당 Property가 리턴한 값을 복사하여 사용하시면 되겠습니다.
이상으로 오늘 포스팅을 마치며 기타 궁금하신 점이나 다른 문의는 이메일 또는 리플로 남겨주시기 바랍니다.
아래는 이번시간에 구현한 소스코드입니다.
안녕하세요? Wiimote Library v1.7분석 그 두번째 시간입니다. 이번시간부터는 지난 시간에 살펴본 구조와 흐름을 바탕으로 라이브러리의 실제 코드에서는 어떻게 구현이 되어있는지에 대해서 살펴보도록 하겠습니다. 처음 총 3번의 포스팅으로 시스템에 연결된 Wiimote Controller를 검색하고, 통신하는 방법에 대해 소개하려고했었는데 생각보다 분량이 많아 엄청난 스크롤의 압박이 예상되기 때문에 원래 2회정도로 나누어 포스팅을 하도록 하겠습니다. (총 5회가 되겟네요.)
#시스템에 연결된 Wiimote Controller를 검색해보자!
라이브러리를 설치하면 테스트용 샘플 코드를 확인 하실 수 있습니다. Wiimote를 컴퓨터에 연결된 Bluetooth와 연결한 뒤 샘플 코드를 실행하면 아래그림과 같은 결과 화면을 확인 하실 수 있습니다.
저같은 경우에는 Wii Controller로 Wii Fit을 연결했기 때문에 오른쪽 상단에 Balance Board의 데이터가 상황에 따라 변화되는것을 확인 할 수 있습니다. 그리고 화면 중앙에 잔여 배터리양도 표시가 되네요. 만약 Wiimote를 연결했다면 왼쪽 상단에 Wiimote의 데이터가 움직이게 됩니다. (만약 한번에 2개 이상의 Wii Controller를 연결했다면 새로운 탭이 추가되어 각각의 탭에서 장치에 대한 정보를 살펴 볼 수 있습니다.)
그럼 본격적인 코드를 살펴보도록 하겠습니다. 아래는 샘플코드를 실행했을때 바로 실행되는 MultipleWiimoteForm가 로드될때 발생하는 Load 이벤트의 코드 일부입니다. 소스코드에 대한 설명은 주석에 대체 했으며, 코드 설명에 불필요한 부분 (예를들어 MessageBox등..)은 분량을 줄이기 위해서 임의로 삭제 했으니, 착오없으시길바랍니다.
이번 분석에서의 주요 중점인 HID장치로 인식되는 Wiimote Controller와 통신에 대한 부분은 FindAllWiimotes()을 호출 하는 부분 부터 시작된다고 할 수 있습니다. 중간 부분에 검색된 Wiimote 장치들에 맞는 WiimoteInfo Control 생성부분은 사용자가 라이브러리를 개발할때 필요한 방식대로 적절하게 변경하여 사용하면 되는 부분이기 때문에 이번 분석의 범위에서 벗어나므로 추가 설명은 생략하도록 하겠습니다.
FindAllWiimotes() 메서드가 정의된 WiimoteCollection Class로 이동하면 아래와 같이 썰렁한 한줄짜리와 두줄짜리 메서드를 확인 할 수 있습니다. 첫번째 FindAllWiimotes()는 우리가 찾아온 메서드로 시스템에 연결된 모든 Wiimote Controller를 찾는 메서드고, 두번째 WiimoteFound메서드는 Wiimote Controller를 찾았을때 호출되는 메서드입니다.
FindAllWiimotes 메서드의 코드를 살펴 보면 Wiimote Class에 Static 메서드로 정의된 FindWiimote 메서드를 호출하는것을 알 수 있습니다. Wiimote Class의 FindWiimote메서드는 파라미터로 Wiimote Controller를 찾았을때 호출할 Delegate를 입력받고, Wiimote Controller가 검색되면 해당대리자를 호출 해주게됩니다. Delegate는 파라미터로 검색된 Deivce의 DevicePath를 입력받고 처리 여부를 bool형태로 반환하는 형식으로 WiimoteCollection에 정의된 WiimoteFound와 동일합니다.
따라서 WiimoteCollection에 정의된 FindWiimote를 호출하면 Wiimote Class의 FindWiimote를 호출하면서 대리자로 WiimoteCollection에 정의된 WiimoteFound 메서드를 전달하게 되고, WiimoteFound 메서드는 파라미터로 입력받은 DevicePath를 통해 Wiimote객체를 생성한뒤 Collection에 추가하게 됩니다.
자그럼 본격적인 Controller를 검색하는 부분입니다. Wiimote Class의 Findow Window메서드에 대해서 살펴보겠습니다.
위 코드를 보면 HID 관련 API를 사용하여 시스템에 연결된 HID를 순차적으로 검색한 뒤 Product ID와 Vender ID를 검사하여 Wiimote Controller인지 여부를 판단하는걸 알 수 있습니다. 그리고 파라미터로 전달받은 Delegate를 호출할때 Delegate에서 False를 리턴하면 검색을 중지 함으로서 하나의 Wiimote를 검색하는데 활용할 수 있다는것을 알 수 있습니다.
이렇게 해서 오늘은 시스템에 연결된 wiimote Controller 장치를 검색하고 Wiimote 객체를 생성하는 부분까지 알아보았습니다. 다음시간에는 이렇게 생성한 객를 가지고 실제 wiimote와 통신하는 부분에 대해서 살펴보도록 하겠습니다. 오늘 설명한 내용중에 궁금하신 점이나 질문은 이메일이나 리플로 남겨주시면 답변드리도록 하겠습니다.
여자친구와 함께 홈플러스에 갔다가 충동적으로 구입하게된 Nintento Wii.. 처음 사고나서 몇주정도는 함께샀던 Wii Fit과 마리오파티 8을 주구장창하다가 이제는 질려버렸습니다.. -_-;; 슬슬질려가던 차에 여자친구가 베이징 올림픽을 사줬는데 다시 Wii를 TV와 연결하는게 귀찮아 서랍속에 봉인되어있네요..
거금 40만원(타이틀 값포함) 정도를 투자해서 구입한 Wii.. 이대로 썩히긴 아깝다 싶어서 게임이 아니라면 다른방법으로라도 사용해야겠다 싶어. 요즘 한창 인기있는 Wiimote(+ 기타 Wii Control)를 사용한 Application 개발에 나섰습니다. 대부분의 Wii Control은 Blutooth 방식으로 동작하기 때문에 간단히 처음에는 간단하게 장치 찾아서 시리얼 포트로 통신하면 뚝딱! 이겠구나 싶었는데 Wii Control은 별도의 시리얼통신 서비스를 제공하고 있지않아 .. 멤버십에 Wiimote를 사용하는 프로젝트를 진행중인 분께 여쭤봤더니 Wiimote를 제어 할 수 있는 오픈소스가 있다고 하네요..
냉큼 달려가 다운로드를 받아봤더니 단순히 Wiimote뿐만 아니라 Wiifit이나 Guitar와 같은 다른 Wii Controller 들도 지원을 하고 있었습니다. 이런 훌륭한 것이.. 소스를 살펴보니 주석뿐만 아니라 개발 문서까지 제공하기때문에 단순히 라이브러리를 사용하고자 하는 사람들은 별다른 코드 수정없이 샘플 프로그램을 조금만 변경해서 사용할 수 있을것 같습니다..
하지만, 저같이 이런 물건(?)은 꼭 파해쳐 보고싶어하는 악독한 심보의 사람들을 위해서, 이번시간부터 총 3번에 걸쳐서 라이브러리를 분석해보도록 하겠습니다. 분석에서는 라이브러리 자체의 사용법보다는(개발문서에서 너무 자세히 설명되어있기 때문에 굳이 설명하지 않아도 될것같습니다.) 라이브러리의 구조나, 동작방식에 촞점을 맞춰 설명할 계획입니다.
WiimoteCollection.cs : 다수의 Wiimote를 관리하기 위한 Collection 객체입니다.
파일은 딱 5개인데 소스코드는 2500라인 정도 되는것 같네요 -_-;;; (소스코드를 열어보면 엄청난 스크롤의 압박에 시달립니다.)
Wii Controller가 PC의 Bluetooth에 접속되면 아래 그림과 같이 HID(Human Interface Device)로 추가 되게 됩니다.
Wiimote Library는 Win32 API를 래핑한 Class인 HIDImports를 사용하여 시스템에 연결된 HID장치 목록을 검사하여 VenderID로 Nintendo 사의 제품인지를 판별하고 ProductID를 통해 Wiimote를 판별한뒤 Device Path를 통해 파일을 열고 읽고/쓰는 작업을 통해 Controller와 통신하게 됩니다.
말로만 하면 이렇게 간단한 작업을 통해 가능하지만 Device Driver를 직접 제어하는 기능을 구현해야 하므로 상당히 까다로운 작업이 요구되게 됩니다. 다음시간에는 실제 소스코드를 살펴보면서 어떻게 HID에 접근하고 이를 활용하는지에 대해서 살펴보도록 하겠습니다. 그럼 오늘은 여기까지 하겠습니다! 질문은 리플 & 이메일로 남겨주세요!
연이은 Image Processing과 관련된 포스팅입니다.. (카테고리를 하나 만들어야하나..) 이번시간에 소개해 드릴 내용은 이전 시간과 마찬가지로 기술이라기 보다는 평소 C#을 사용해서 이미지 프로세싱을 할때 이미지로부터 메모리로 접근하기 위해서 자주 만들어 사용하던 클래스를 소개하는 시간이 되겠습니다. C#에서는 이미지를 제어하기 위해서 Image라는 클래스를 제공합니다. 그리고 사용자가 임의로 이미지 자체의 메모리를 조작 할 수 있도록 하는 메서드가 포함된 Bitmap이라는 Class를 제공합니다.
Image Processing을 하는데 있어서 직접 Binary Data를 읽어들여서 처리하는 방법도 있지만, RAW나 BMP형식이 아니라 JPG나 PNG라면.. 직접 디코딩하는 작업을 생각만해도 끔찍합니다.. ㅎㅎ 이럴때 Bitmap Class를 사용하면 매우 쉽고 유용하게 사용할 수있습니다. 기본적으로 Bitmap Class에서는 기본적으로 BMP,JPG, GIF, PNG, TIF등의 이미지를 지원하는 인코더와 디코더가 달려있어서 FromFile메서드를 통해 쉽게 불러오고 Save메서드를 사용해 반대로 저장할수 있는 기능을 제공합니다. (Win32 Bitmap Handle도 지원합니다.)
이렇게 불러들인 이미지 파일을 처리 하기 위해서는 이미지가 저장된 메모리로의 접근이 필수적인데요, 간단 몇 픽셀 정도는 GetPixel 또는 SetPixel메서드를 통해 쉽게 픽셀 데이터를 처리 할 수 있지만, 이미지 전체를 처리하기에는 터무니 없는 속도때문에 적합하지 않습니다.
그렇다면 이미지 전체를 처리하기위해서는 어떻게 해야할가요.. Bitmap Class에서는 LockBits와 UnLockBits메서드를 사용해 메모리에 접근 할 수 있습니다. 사용법은 아래와 같습니다.
간단하지만, 뭔가 어려워 보이는 코드입니다. (위 코드가 손에 익숙해지면 큰 부담은 없겠지만.. 손에 익기 전까지는 꾀나 번거러운 작업이 됩니다..) 그래서 이와 같은 코드를 좀더 쉽게 사용하기 위해서 아래와 같은 클래스를 만들어 보았습니다.
위 코드에서는 Bitmap Class에 몇가지 확장메서드를 추가하여 손쉽게 이미지로부터 메모리를 가져오고 반환하는 작업이 가능합니다. 아래는 사용 예입니다.
어떠신가요? 처음 코드보다는 한결 간단해진것을 확인 하실 수 있으실것입니다. 기본적으로 LockMemory를 호출하게되면 이미지 전체 영역에 대한 메모리를 반환하지만, 영역을 지정할 경우 해당영역에서만 사용가능한 메모리를 리턴합니다. (부분적인 처리가 필요하다면 유용하겠죠..) 그리고 이미지 자체의 메모리를 Byte배열에 복사를 하고자 한다면 CopyMemory를 호출하여 쉽게 복사 할 수 도 있습니다.
질문이나 기타 궁금하신 사항은 리플이나 이메일로 남겨주세요~
(확장 메서드에 대해서 질문 하셨던 분이 있어서 다음 포스팅에서는 확장메서드에 대해서 다루도록 하겠습니다.)
이번시간에는 AForge .Net 라이브러리를 사용하여 간단하게 Video Source로부터 Frame을 추출해 낼 수 있는 방법에 대해서 소개하려고합니다. 이전 시간에 증강현실과 관련된 내용을 소개하면서 실시간으로 Camera로 부터 얻어오는 내용에 대한 언급이 전혀 없어서 요청하시는 분이 있을것 같아 올려봅니다.
아래 소스는 제가 평소에 간단한 영상처리 프로젝트를 구현할때 사용하는 소스로 AForge .Net 라이브러리를 사용하여 파일 또는 웹캠에서 영상데이터를 수집 할 수 있는 내용을 담고있습니다. 먼저 클래스의 구조입니다.
먼저 클래스의 이름은 Camera이고, 간단하게 입력받은 영상에 대한 정보를 조회 할 수 있는 몇가지 Property와 WebCam을 Device를 가져오거나 동영상 파일로부터 VideoSource를 생성하는 기능을 포함하고 있습니다. 그리고 가장 기본적인 WebCam 또는 Video Source에서 Frame이 갱신되었을 경우 NewFrame이라는 이벤트를 통해 Frame Image를 전달합니다.
가능하면 Property와 Method 이름을 풀어서 작성하였기 때문에 각 항목에 대한 설명은 생략하도록 하겠습니다.
(궁금하신 점은 말씀해주시면 자세히 설명해드리겠습니다.)
아래는 소스코드입니다.
소스코드 열기
이번에도 역시 코드가 상당히 기네요.. 위 코드는 이해하기 힘들다 싶으시면 그냥 붙여넣기 하여 사용하셔도 되구요.. 간단하게 몇가지 사례별로 적용할 수 있는 사용법에 대해 설명해 드리겠습니다.
이해가 잘 되시나요? 이렇게 여러분의 상황에 맞게 적절히 세팅을 해주신 뒤 NewFrame이벤트가 발생하면 Camera 객체의 LastFrame Property를 통해 해당 Frame의 이미지를 가져 오실 수 있습니다. 사용하시다가 발생하는 문제나 궁금하신 점은 리플이나 이메일로 연락주시면 답변해드리도록 하겠습니다.
PS. 위 코드는 AForege .NET 라이브러리를 사용했기 때문에 실행전 반드시 해당 라이브러리가 설치되어 있어야 합니다.
AForge .Net 라이브러리에 대한 자세한 정보는 http://code.google.com/p/aforge/ 에서 확인 하실 수 있습니다.
이번시간에는 지금까지 제 블로그에서 한번도 다루어 지지 않았던 새로운 주제인 증강현실에 대해 간략히 소개하고 증강현실에서 필요한 요소중의 하나인 Marker Detection에 대해서 살펴보고자 합니다. 먼저 증강현실이 무엇인가에 대해서 살펴봐야겟죠, 증강현실의 사전적 의미를 살펴보면, "사용자가 눈으로 보는 현실세계와 부가정보를 갖는 가상세계를 합쳐 하나의 영상으로 보여주는 가상현실" 이라고 정의되어 있습니다.
간단하게 말하면 증강현실은 현실과 컴퓨터 환경을 혼합하여 보여주는 기술이라 할 수 있겠습니다. 일반적으로 증강현실은 위 그림과 같이 현실세계에 컴퓨터가 인지할 수 있는 Marker를 두고 사람이 바라보는 시점에 따라 Marker에 정보를 표현 해 주는 방식으로 구현을 합니다.
증강현실과 관련된 라이브러리로는 대표적으로 ARToolKit(http://www.hitl.washington.edu/artoolkit/)이 있습니다. ARToolKit은 증강현실을 초보자도 쉽게 구현하도록 하기 위해 제공되는 라이브러리로, 하나의 Marker를 인식하는데 최적화된 라이브러리 입니다. 컴퓨터와 연결된 카메라를 가지고 Marker를 비추게 되면 마커를 인식하여 마커위에 정보를 표현 할 수 있습니다.
이번시간에는 증강현실 라이브러리를 사용하지 않고 카메라에서 입력받은 영상을 처리하여 Marker를 추출해 내는 방법에 대해서 소개합니다. 아래는 구현완료 동영상입니다.
동영상에는 하나의 Marker를 사용하여 촬영했지만, 실제로는 2가지 이상의 Marker도 추출이 가능합니다. 간단하게 구현하는 방법을 소개하기 위해 카메라에서 영상을 받아오고, 영상을 라벨링 하는 알고리즘은 .Net Framework를 기반으로 오픈소스 이미지 프로세싱 라이브러리인 Aforge.Net(http://code.google.com/p/aforge/)을 사용하여 구현했습니다.
먼저 영상에서 마커영역을 추출하기 위해서는 아래와 같은 과정을 거치게 됩니다.
간단하게 설명하면 영상을 입력받고 적정 임계치를 적용하여 영상을 이진화 한뒤 라벨링 알고리즘을 수행하여 영역을 분리 합니다. 그리고 분리된 영역중 정사각형인 영역을 분리하여 마커를 인식하게 됩니다. 아래는 Marker Detection 소스 코드입니다. 소스코드가 긴 관계로 추가적인 설명은 생략하고 주석으로 대체하겠습니다.
코드 열기
붙여넣고 보니 코드가 엄청나게 길군요;; 살펴보시다가 이해가 가지 않으시는 부분이나 기타 궁금하신 사항은 리플이나 이메일 주시면 답변드리도록 하겠습니다.
----------------------------------
1월 13일 화요일 오후 9시 19분 추가
----------------------------------
위 코드 이후에 작업에 대해서 언급을 하지 않았었네요;; 위 코드는 단순하게 영상에서 Marker를 추출하는 코드고, 실제 사용하기 위해서는 추출될 Marker를 Template Matching을 하여 Marker ID를 취득한 뒤 ID에 맞는 정보를 보여주면 됩니다.
PS. 포스팅하고 나서 확인한건데.. 전체 프로젝트 코드를 안올렸더군요.. (이미 지워버렸는데......ㅠㅠㅠㅠㅠㅠ)
혹시 필요하신 분들은 요청해주세요. 이미 삭제해서 프로젝트 파일은 드릴수는 없지만.. 기타 설명은 더 해드리겠습니다.
이번시간에는 이전시간에 말씀드렸던대로 Image를 PDF로 변환하는 방법에 대해서 소개합니다. PDF Binary를 직접 제어하는것은 아니고 얼마전에 인터넷을 돌아다니다가 발견한 PdfSharp라는 Library를 사용한 방법입니다. 오픈소스 라이브러리 임에도 불구하고 엄청게 다양한 기능을 제공하고 있습니다. 심지어 WPF도 지원하는것 같았습니다. (소스코드를 열어보면 입이 떠억~ 벌어집니다.) PdfSharp은 http://pdfsharp.com/에서 다운로드 받으실 수 있습니다.
이번에도 마찬가지로 소스코드에 대한 설명은 주석으로 대체하겠습니다.
첫번째 파라미터로는 GDI+ Image객체를 입력하고 두번째 파라미터로는 PDF 파일이 저장될 Path를 입력하면됩니다. 위 함수를 사용하여 아래와 같이 응용할 수도 있습니다.
이렇게 하면 간단하게 이미지 파일의 주소를 입력하거나 웹페이지의 URL를 입력하면 자동으로 PDF로 변환하는 기능을 구현할수도 있습니다. 궁금하신점은 이메일이나 리플달아주세요~아래는 전체소스코드 및 프로젝트 파일입니다.