Lovelyredsky

Archive
StudyNote

Intel에서 최근에 Perceptual Computing 이라는 motion & face tracking toolkit의 SDK를 발표했습니다. 찾아보면 이런저런 동영상들이 많이 나오는군요. 직접 비교해보진 않았지만 Kinect, Leap Motion 등 기타 다른 기술들 보다 다양한 방법으로 안정적이고 정확하게 동작하는 것 같습니다.

Creative와 합작으로 전용 카메라를 개발하였고, 카메라는 Kinect의 반 이하 크기인 듯 하고 RGB카메라와 IR Depth카메라가 장착되어 있습니다. 카메라 스펙은 다음과 같습니다. 인식 범위를 보면 RGB카메라는 7미터까지, IR Depth카메라는 1미터까지입니다.

RGB Camera
Native Resolution: 720p (1280×720 pixels)
Frame Rate: 30fps
FOV: 73 degrees diagonal
Range: 0-23 feet (0m-7.01m)
RGB + Depth frame sync

IR Depth Sensor (3D depth mapping)
Native Resolution: QVGA (320×240 pixels)
Frame Rate: 30fps
FOV: 73 degrees diagonal
Range: 6 inches to 3.25 feet (15 cm to 100 cm)
Ranging Technology: Time-of-flight

Audio
Dual-array microphones

Recommended System Configuration
PC with 2nd or 3rd generation Intel® Core™ processor
Windows* 7 with Service Pack 1 or higher / Windows 8 Desktop UI
4GB system mem

>Perceptual Human Interface Guideline을 읽어보면 어떤 스펙으로 어떤 것들을 할 수 있는지 좀 더 자세하게 파악할 수 있습니다. 내용을 보면 손가락 하나하나를 카운트 할 수 있고, 손으로 하는 포즈 – V나 하이파이브 등 -와 동작으로 하는 다양한 액션 – circle, grab & release, move, pan, zoom, wave, swipe 등 – 이 미리 정의되어 있어서 따로 분석할 필요 없이 즉시 확인할 수 있는 것 같습니다. 그리고 depth를 체크해서 손과 얼굴이 함께 인식되면 어느 것이 앞에 있는지도 인식해서 처리해주고 있습니다.
그리고 동작 인식 뿐만 아니라  Voice recognition과 Face tracking도 제공하고 있기 때문에 다양한 방법으로 interaction을 할 수 있을 것 같군요. 여기까지만 살펴봐도 상당히 유용할 것 같습니다. 아직 Javascript, Flash 등과 직접적으로 연결되지 않는 것은 조금 아쉽지만, C#가 있으니 조금 수고하면 가능하겠죠.

아직은 윈도우 기반에서만 동작하고, C#/Unity3D/Processing과 연동할 수 있습니다.

>공식사이트

>Interview

>Overview

홍보를 위해서인지 >Perceptual Challenge라는 경진대회도 하는군요.

Read More

Phillips Hue가 드디어 >SDK를 발표했습니다. 계속 업데이트를 해나갈 것 같고, 지금은 기본적인 것들 – 온/오프, 칼라, 밝기 등 – 위주로 동작하는 것 같습니다. Phillips가 제공하는 bridge를 통해서 제어할 수도 있고, 각각의 전구에 직접 access하려면 Zigbee 프로그램에 등록해야 한다고 하는군요.

아직은 몇 가지 제한 사항들도 있습니다.
- bridge가 한번의 스캔에서 1분간 최대 15개 정도까지만 인식이 가능하다고 하네요. 처음 부팅할 때 귀찮겠네요.
- 동시에 명령을 내릴 수 있는 전구는 초당 10개 정도 인 것 같습니다. 그룹 – 전구들의 묶음 – 의 경우에는 초당 1회 정도가 최대라고 합니다. 이 부분은 빠른 반응을 필요로 할 경우 좀 걸림돌이 될 수도 있을 것 같습니다.

KickStarter에 보면 다른 종류의 >connected bulb 들도 있는데, 그 중엔 >spark socket처럼 어떤 종류의 전구도 쓸수 있는 것도 있더군요. 아직 SDK까지 발표된 건 없는 것 같은데, 어느 것이든 유용하게 쓸 수 있는게 나오면 여러 곳에 재밌게 쓸 수 있을 것 같네요.

Read More

Facebook Like 버튼을 설치하는 방법을 간단히 정리해본다.

1. http://developers.facebook.com/docs/reference/plugins/like/에서 간단히 설정값을 입력하면 코드를 얻을 수 있다. Step1과 Step2를 모두 거쳐야 한다. Step1의 첫번째 url 항목에서는 원하는 url을 입력하거나, form의 url을 기준으로 하도록 빈 칸으로 남겨둘 수도 있다. 그런데 open graph tag에는 og:description도 있어야 하는데 현재 이 페이지에서 주는 코드에는 빠져있으므로 수동으로 추가해서 넣어야 한다. Open graph protocol에 대해서는 >http://ogp.me/ 에서 찾아볼 수 있다.

2. og:image는 여러개를 입력할 수 있으며, image외에 동영상과 같은 다른 미디어도 가능한 듯 하다. 시도해보지는 않았음.

3. 코드를 모두 원하는 곳에 삽입한 후에는 >http://developers.facebook.com/tools/debug에서 체크를 해야만 open graph tag가 정상적으로 등록이 이루어지고 동작을 시작한다. 그 전에는 verified가 되지 않아서인지 정상적으로 동작하지 않는다.

하나의 페이지에 여러 개의 like버튼을 넣는 문제나, 동적으로 생성되는 페이지의 경우 동적으로 open graph tag를 업데이트해주면서 like 버튼에 반영하는 등의 문제는 추가로 체크가 필요하다.

Read More

HTML5에 추가된 window.history가 있습니다. hash 등을 이용해 처리하던 ajax 방식의 페이지 이동에 따라서 생기는 history와 url관리의 문제에 대응하는 것입니다.

>http://diveintohtml5.info/detect.html#history
>https://developer.mozilla.org/en-US/docs/DOM/window.history 

그런데 아직 브라우저에 따라 다른 부분도 있고, HTML5를 지원하지 못하는 오래된 브라우저들에서는 문제가 될 수 있기 때문에 호환성을 고려하는 사람들은 >History.js를 사용하고 있습니다. 그런데 이 History.js에서 >empty initial state라는 알려진 오류가 있습니다. 임의의 hash를 가진 url로 직접 이동했을 경우, 예를 들어 http://site.com/?state=1234와 같은, url이 가지고 있는 state를 처음에 제대로 복원해내지 못하는 문제인데, initial state의 data가 empty object로 체크되는 것입니다. 여러가지로 테스트를 해본 결과 다음과 같은 현상을 알아낼 수 있었습니다.

1. ?state=hello world 와 같이 data에 space와 같은 특수문자가 있는 경우, initial state에서 어떤 경우도 값을 체크해내지 못합니다.
2. ?state=1234 와 같이 data에 특수문자가 없을 경우, 현재 페이지를 reload하게 되면 initial state가 정상적으로 체크가 됩니다.
3. 어떤 경우에든 새로운 탭을 열거나 다른 브라우저에서 해당 페이지로 이동할 경우 initial state가 항상 empty로 표시됩니다.

결국 2번 경우를 제외하면, 어떻게든 정상적으로 History.js를 통해 window.History의 initial state를 체크할 수 없는 것 같습니다. 단, window.history는 잘 체크합니다. 그러나 처음에 언급한대로 브라우저 호환성을 고려하지 않을 수 없기 때문에 History.js에서 해결할 수 있는 방법을 찾아야 할 수 있습니다. 또한 가능한 url을 사람이 읽을 수 있도록 해주는 것이 더 좋다고 생각한다면 2번과 같은 스타일을 피하고 싶다면 문제가 됩니다.

이런 경우 History.js의 initial state에서 data는 비어있지만, url값을 정상적으로 표시되기 때문에 url string을 parsing해서 data값을 알아내어 수동으로 처리하는 방법이 일반적으로 사용되고 있는 것 같고, 저도 그렇게 해결을 하고 있습니다.
그런데 state의 initial data를 수동으로 찾아내더라도, History에 새로운 상태를 업데이트해야 합니다. 그렇지 않으면 기존 상태가 empty state로 잘못되어 있기 때문에, 나중에 back/forward와 같이 히스토리를 이동하는 경우 에러가 생길 수 있습니다. 그런데 역시 History.replaceState()를 이용해서 업데이트를 해줄 때에도 문제가 있을 수 있습니다.

1. ?state=hello world 와 같이 data에 특수문자가 있으면 History.replaceState() 를 호출한 후에 History.js의 statechange 이벤트가 중복 호출되면서 업데이트한 상태가 정상적으로 적용되지 않습니다.
2. ?state=1234 와 같은 형식의 경우 정상적으로 History.replaceState()를 통해서 수동으로 알아낸 상태를 적용할 수 있습니다.

가능하면 url을 직접 이해할 수 있는 형태로 만들어주는 것이 좋다고 생각하기 때문에 ?state=1234와 같은 형태를 지양하고싶지만, 위와 같은 문제를 고려해서 적절히 판단하고 대응해야 하는 상황인 것 같습니다.

Read More

Photo Gallery를 만들면서 browser detection을 위해 $.browser를 이용해서 처리하고 있었다. 그런데 알고보니 $.browser가 browser detection에서 문제가 있을 수 있어서 jQuery 1.9에서는 삭제되었다고 한다.

 $.browser: Ever since jQuery 1.4, we’ve been evangelizing that browser detection via the user agent string is a bad idea. Yet we’ve been an enabler of bad practice by continuing to offer $.browser. As of jQuery 1.9 we’ll remove it entirely and you’ll need to use the 1.9 compat plugin. If your code isn’t weaned off browser detection yet, check out Modernizr for a very thorough set of feature detections you can use instead. And of course, you’re welcome to read the tea leaves in the navigator.userAgent string directly, there’s nothing stopping you but your conscience.

한국으로 이사하면서 2~3주 정신 없는 와중에 언제 반영되었는지 모르겠지만, $.browser가 undefined로 처리되는 에러 때문에 사이트가 정상적으로 동작하지 않는 문제를 이제서야 발견하고 원인을 찾아보니 위와 같은 문제가 있었다. JQuery에서는 $.support를 이용하거나 별도의 plugin을 추천한다고 되어 있었지만, 좀 더 확실하게 처리하고자 ‘Javascript : The Definitive Guide’에서 browser detection을 처리하는 함수를 찾아서 적용하였다. 함수는 다음과 같다.

//browser detect
var browser = (function() {
    var s = navigator.userAgent.toLowerCase();
    var match = /(webkit)[ \/](\w.]+)/.exec(s) ||
                /(opera)(?:.*version)?[ \/](\w.]+)/.exec(s) ||
                /(msie) ([\w.]+)/.exec(s) ||
               !/compatible/.test(s) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec(s) ||
               [];
    return { name: match[1] || "", version: match[2] || "0" };
}());

당연히 위 함수는 사용하기 전에 선언되어야 하며 if (browser.name == ‘msie’) {…} 와 같이 사용하면 된다.

Read More