Adobe
제품
Creative Suite
Photoshop 제품군
Acrobat 제품군
Flash Platform
Digital Marketing Suite
Digital Enterprise Platform
Digital Publishing Suite
기타 제품
솔루션
컨텐츠 저작
교육 기관
금융 서비스
공공 기관
디지털 마케팅 솔루션
기타 솔루션
학습 도움말 다운로드 회사
스토어
Adobe 스토어 - 가정 및 소호 사무실
기업용 제품 스토어 - 중견중소기업
기타 구입 방법
검색
 
정보 로그인
환영합니다, 내 장바구니 내 배송 정보 내 지원 정보
내 계정
로그아웃
로그인해야 하는 이유 로그인하면 계정을 관리하고 시험버전 다운로드, 제품 익스텐션, 커뮤니티 영역 등을 이용할 수 있습니다.
Adobe
제품 섹션   검색  
솔루션 회사
도움말 학습
로그인 환영합니다, 내 배송 정보 내 지원 정보
Qty:
Subtotal
Checkout
Adobe Developer Connection / Flash 개발자 센터 /

Webcam Motion Detection: Using the BitmapData API in Flash 8

기준 Guy Watson

Guy Watson
  • www.flashguru.co.uk

Content

  • Capturing Webcam Video
  • Video Freeze-frame
  • Monitoring the Webcam
  • Pixel Brightness
  • Difference Blend Mode
  • Changing the Color of Pixels

Created

12 September 2005

페이지 도구

페이스북으로 공유
트위터로 공유
링크드인(LinkedIn)으로 공유
책갈피
인쇄

Tags

요구 사항

필요한 사전 지식

An understanding of hexadecimal colors and ActionScript 1.0 and 2.0.

사용자 수준

중급

필요한 제품

  • Flash Professional (Download trial)

샘플 파일

  • webcam_old_new.zip (16 KB)

Some time ago I came across various processing experiments that monitored the active webcam for movement and allowed the user to interact with the program or art piece by moving around when in view. Until now Macromedia Flash Player has never been able to access the pixel data of a webcam feed; however, with the release of Macromedia Flash Player 8 comes an impressive and generous new feature—similar in many respects to Imaging Lingo in Director—that gives developers the power to create and modify bitmaps at runtime with ActionScript. This feature comes in the form of a new BitmapData ActionScript API.

One of my first experiments with Flash Player 8 was to try and re-create this webcam motion detection in an optimized fashion so that I could use this input as the basis for other webcam experiments, such as moving a ball around the screen by moving my hand around in view of the webcam.

Note: To view the example below, you need to have a webcam installed.

Flash Player가 없습니다 Flash 10이 필요하십니까? Flash 10이 필요하십니까?

I set out on my journey into the realms of pixeldom and achieved the desired result. In this article, I discuss my journey and the outcome. By the end of this article, I will have taught you a little about how to use some of the new features available in the latest release of Flash Player and you should be able to use this knowledge to write some of your own experiments with webcams.

Capturing Webcam Video

Since the release of Flash Player, you can capture the video stream from a webcam and display it inside a Flash Movie. All you need to do to accomplish this feat is place a Video symbol on the Stage and write a little ActionScript. It sounds complicated, but it is actually quite simple, follow these steps to try it for yourself:

  1. Open the Library (press Control + L).
  2. Create a new Video symbol from the Library menu in the top right-hand corner.
  3. In the Video Properties dialog box, verify that the Video (ActionScript-Controlled) option is selected and click the OK button.
  4. Go to the main Timeline and select the first frame.
  5. Drag the Video symbol from the Library onto the Stage.
  6. Select the Video symbol on the Stage then open the Property inspector (Control + F3).
  7. Enter a unique name in the Instance Name field so you can talk to the video object with ActionScript. For now, enter output_vid for the instance name.
  8. Open the Actions panel on the first frame of the main Timeline (F9) and add the following code:
/* capture the video stream from the active webcam and display it inside the video object */ output_vid.attachVideo(Camera.get());
  1. That's it! Test your movie (press Control + Enter).
  2. Flash Player asks the viewer for permission to access the webcam.
  3. If permission is granted, the Video object you put on the Stage will display the video stream from the webcam.

Video Freeze-frame

In Flash Player 8, you can use the new BitmapData class to create bitmaps at runtime with ActionScript. This class holds individual pixel data and numerous methods are available to modify the pixel data inside of a BitmapData object.

One such method can be used to take a snapshot of a movie clip's current state as a bitmap object. You can also take a snapshot of the current state of a Video object, which is good news for me, because this experiment needs to access the individual pixels of the video captured from the webcam. To take a snapshot of the current state of a Video object or movie clip at runtime using ActionScript, use the draw() method of the BitmapData class.

//(From previous page) /* capture the video stream from the active webcam and display it inside the video object */ output_vid.attachVideo(Camera.get()); import flash.display.BitmapData import flash.geom.Matrix /* create a new bitmap object that is the same size as the Video object to store the pixel data */ var snapshot:BitmapData=new BitmapData(output_vid._width,output_vid._height); /* create a function that takes a snapshot of the Video object whenever it is called */ function takeSnapshot() { //draw the current state of the Video object into //the bitmap object with no transformations applied snapshot.draw(output_vid,new Matrix()); }

You can then display a BitmapData object inside of a movie clip using the new attachBitmap() method:

//create a movie clip to hold the bitmap when we attach it this.createEmptyMovieClip("bitmap_mc",this.getNextHighestDepth()); //display the specified bitmap object inside the movie clip bitmap_mc.attachBitmap(snapshot,1);

You can then call your snapshot function, for example, when a button is pressed to display a freeze frame of the video object:

snap_btn.addEventListener("click",mx.utils.Delegate.create(this,takeSnapshot));

Note: Ensure that you do not have the video object at the upper left corner of the Stage, or the bitmap_mc instance will overlap your video.

Monitoring the Webcam

To monitor changes in the video stream captured from the webcam, you need to take regular snapshots of the video object. I use setInterval to call a snapshot function every x milliseconds. Then, to actually determine whether there has been movement, at any moment in time two bitmaps have to be in memory—the bitmap created last time a snapshot was taken ("before") and a bitmap containing the current state of the video ("now"). Using the BitmapData class you can then compare the two bitmaps:

import flash.geom.Matrix import flash.display.BitmapData setInterval(this,"snapshot",100); now=new BitmapData(output_vid.width,output_vid.height); m=new Matrix(); function snapshot() { now.draw(output_vid,m); //…… code that check's difference between 'now' and 'before' before=now.clone(); }

Pixel Brightness

In my first attempt at this experiment I actually wrote some code that looped through every pixel in the current snapshot ("now") and checked for changes in the brightness of the pixel since the last snapshot ("before"). If the change in brightness of that pixel was greater than a constant tolerance value, then you can assume that there was movement in that pixel. The tolerance value is determined by trial and error, a value around 10 worked best in my experiments:

//accuracy tolerance=10; //color of the current pixel in the current snapshot nc=now.getPixel(x,y); //red channel nr=nc>>16&0xff; //green channel ng=nc>>8&0xff; //blue channel nb=nc&0xff; //brightness nl=Math.sqrt(nr*nr + ng*ng + nb*nb) //color of the same pixel in the previous snapshot bc=before.getPixel(x,y); //red channel br=bc>>16&0xff; //green channel bg=bc>>8&0xff; //blue channel bb=bc&0xff; //brightness bl=Math.sqrt(br*br + bg*bg + bb*bb); //difference in brightness between now and before d=Math.round(Math.abs(bl-nl)); if(d>tolerance) { //there was a change in this pixel }

The results were satisfactory and it did actually work to some extent (see the old-webcam SWF file below), although speed was a big problem—the larger the dimensions of the video stream the more pixels I had to check. Even a small Video object (100 pixels wide, 100 pixels high) resulted in a large ActionScript loop that looped 10,000 times to check every pixel at a regular interval. Script timeout errors were common and the program appeared to lag.

Flash Player가 없습니다 Flash 10이 필요하십니까? Flash 10이 필요하십니까?

So, my algorithm added size restrictions to the video feed from the webcam because I had to reduce the size of the ActionScript loop; 10,000 iterations is slow and unacceptable, so back to the drawing board I go. I decided that maybe I can speed up the loop if I only check the brightness of every ten pixels in the bitmap, and it worked. However, the effect lost accuracy and didn't detect all movement in the webcam. It was time for another solution that didn't involve checking the brightness of pixels.

Difference Blend Mode

This solution came about when a friend suggested that I should take a look at the difference blend mode, one of 11 blend modes available in Flash Player 8. There are nine blend modes in Flash Player 8 and two special blend modes that require extra steps for them to function correctly. A blend mode can be used to create a composite bitmap formed by blending together the color data from two or more bitmaps with different calculations. Each different calculation is a different blend mode. I was interested in the difference blend mode, because it creates a negative effect based upon the difference in brightness of the pixels.

You can apply a blend mode to a BitmapData object with ActionScript by specifying the name of the blend mode as a string for the fourth parameter of the draw() method:

//draw the previous snapshot onto the current snapshot //using the difference blend mode now.draw(before, new Matrix(), null, "difference");

The resulting bitmap contained a negative effect; any pixels that were the same color in both the previous snapshot ("before") and the current snapshot ("now") were black. Finally, a good result; I was almost there, but I still had an ugly negative image. The next point of call was to change all the pixels that were not black to a different color. In this case, I chose green, which resulted in a bitmap that showed only the movement detected in the webcam as a green outline.

Changing the Color of Pixels

You can change the color of any specific pixel in a BitmapData object using the setPixel() method. I could have used this method to check every pixel to see whether it is black (0xFF000000), and if it isn't, then I can change the color of the pixel to green (0xFF00FF00), as follows:

w=now.width; h=now.height; for(x=0;x<w;++x) { for(y=0;y<h;++h) { if(now.getPixel(x,y) != 0xFF000000) { now.setPixel(x,y,0xFF00FF00); } } }

However, the larger the image, the more times this code will have to run. This could potentially slow down the Flash Player due to excessive loop iterations. Luckily there is another method of the BitmapData class called threshold() that you can use to isolate and replace ranges of colors in a bitmap. Because it is a native method, it is written in C code and thus it is lightning fast compared to the above code:

now.threshold(now,now.rectangle,now.rectangle.topLeft,">",0xFF111111,0xFF00FF00,0x00FFFFFF,false);

The above snippet of code basically instructs Flash Player to copy the pixels from the bitmap called now into the bitmap called now (itself), changing any pixels that have a color value that is greater than almost black (0xFF111111) to green (0xFF00FF00).

Where to Go from Here

Download the full source code and look at how everything works together in context to achieve the desired effect. I've commented the code to help you understand it. Visit Set Pixel and Flight404 for some inspirational webcam experiments—they should inspire you to develop some ideas of your own. Try and take this experiment to the next level, by using the motion detection to actually move things around the screen or to create interactive special effects. If you create something cool, send me an e-mail—I'd love to see it!

More Like This

  • RealEyes OSMF Player Sample – Part 3: Skinning and control bar system
  • RealEyes OSMF Player Sample – Part 2: Building and configuration
  • Pixel Bender basics for Flash
  • Flash glossary: Gradient Transform tool
  • Flash glossary: Embedded video
  • Flash video template: Video presentation with navigation
  • Flash CS4 Missing Manual excerpts: Video, testing and debugging, optimization, and sound
  • Flash glossary: Gradient
  • Flash glossary: Filters
  • Flash glossary: Free Transform tool

제품

  • Creative Suite
  • Photoshop 제품군
  • Acrobat 제품군
  • Flash Platform
  • Digital Marketing Suite
  • Digital Enterprise Suite
  • Digital Publishing Suite
  • 모바일 앱

솔루션

  • 고객 경험 관리
  • 컨텐츠 저작
  • 디지털 마케팅

업계

  • 교육
  • 금융 서비스
  • 공공 기관

도움말

  • 제품 도움말 센터
  • 주문 및 반품
  • 다운로드 및 설치
  • 내 Adobe 정보

학습

  • Adobe Developer Connection
  • Adobe TV
  • 트레이닝 및 인증
  • 포럼
  • 디자인 센터

구입 방법

  • Adobe 스토어
  • 중견중소기업
  • 대기업

다운로드

  • Adobe Reader
  • Adobe Flash Player
  • Adobe AIR
  • Adobe Shockwave Player

회사

  • 보도 자료실
  • 파트너 프로그램
  • 기업의 사회적 책임
  • 채용 정보
  • IR
  • 이벤트
  • 법률
  • Adobe 연락처
지역 선택 한국 (변경)
지역 선택 닫기

North America

Europe, Middle East and Africa

Asia Pacific

  • Canada - English
  • Canada - Français
  • Latinoamérica
  • México
  • United States

South America

  • Brasil
  • Africa - English
  • Belgium - English
  • Belgique - Français
  • België - Nederlands
  • България
  • Česká republika
  • Danmark
  • Eastern Europe - English
  • Eesti
  • España
  • France
  • Deutschland
  • Hrvatska
  • Ireland
  • Israel - English
  • Italia
  • Latvija
  • Lietuva
  • Luxembourg - Deutsch
  • Luxembourg - English
  • Luxembourg - Français
  • Magyarország
  • Middle East and North Africa - English
  • Moyen-Orient et Afrique du Nord - Français
  • Nederland
  • Norge
  • Österreich - Deutsch
  • Polska
  • Portugal
  • România
  • Россия
  • Schweiz - Deutsch
  • Suisse - Français
  • Svizzera - Italiano
  • Slovenija
  • Slovensko
  • Srbija
  • Suomi
  • Sverige
  • Türkiye
  • Україна
  • United Kingdom
  • Australia
  • 中国
  • 中國香港特別行政區
  • Hong Kong S.A.R. of China
  • India - English
  • 日本
  • 한국
  • New Zealand
  • Pacific - English
  • 台灣

Southeast Asia

  • Includes Indonesia, Malaysia, Philippines, Singapore, Thailand, and Vietnam - English

Copyright © 2012 Adobe Systems Incorporated. All rights reserved.

이 웹 사이트의 사용은 사용 약관 및 온라인 개인 정보 보호 정책(업데이트일: 2009년 7월 14일)에 동의함을 의미합니다.