Homework 3: How Animation Works
Animation is a medium in which successive still images are rapidly presented in order to give viewers the impression of smooth movements. To understand how this process works, imagine being presented with a still photograph of an object in motion. Then, a short while later, imagine you were shown another image of the same motion in progress (and then another, and another). As the delay between seeing the photographs decreases, the depicted motion would begin to appear smoother—it would be as if you were watching the original motion itself rather than a series of snapshots. The point at which a viewer perceives smooth motion from successively presented still images is known as the flicker-fusion threshold. It occurs for most humans when these images (known as frames) are presented at a rate of about 10–15 still images per second.
In traditional animation, frames may be drawn directly onto celluloid (“cel” animation), photographed (as in plasticine or clay animation), or drawn (i.e., rendered) with computers. Typical frame rates range from around 10 frames per second (fps) for Claymation-style animation to 24 fps or higher for computer animation.
Your Task
In this step you will complete the methods needed to draw the individual frames of your ASCII animation by implementing the generateMovie and addFrame member functions of the Asciimation class.
generateMovie
The generateMovie member function is in charge of creating a VideoWriter object, updating the position of the sprite_ data member, and calling addFrame the right number of times.
To create a VideoWriter, we will need to be ready to tell opencv how big we want our video to be. This size information gets passed to the VideoWriter as a Size object.
-
Create a
Sizeobject calledmovieSizewith the total width of the movie and the total height of the movie. Note that the width and height need to be passed in as the number of pixels, so you will need to calculate those values from theAsciimationobject’s private data members. The parameterized constructor for theSizeclass takes the width first, then the height; for example,Size(totalWidth, totalHeight). -
Create an
intvariable calledcodecwhose value isVideoWriter::fourcc('m','p','4','v'), which we will use to tellopencvhow to encode the video we create. -
Create and use a
VideoWriterobject,vw, using theVideoWriterclass’s default constructor. -
Call
vw’sopenmember function, which takes four parameters,- The name of the file to write to (which is one of the arguments to
generateMovie) - The codec to use to encode the video
- The frame rate to use in generating the video (which is the other argument to
generateMovie) - The
Sizeof the movie
- The name of the file to write to (which is one of the arguments to
-
Write code to repeatedly
- Call
addFramewith yourVideoWriterobject - Move the sprite one column right by updating the appropriate data member
- (Your loop should start with the sprite completely off of the screen to the left and end when the sprite has gone completely off of the screen to the right).
- Call
-
Close the
VideoWriterby calling itsrelease()member function
addFrame
The addFrame member function is in charge of creating a single frame of the animation video, then adding it to the VideoWriter object supplied as an argument. To implement this function,
- Create some variables that will be helpful later:
const Scalar BACKGROUND_COLOR = Scalar(0,0,0);
const Scalar TEXT_COLOR = Scalar(255,255,255);
const float TEXT_SCALING = 1.0;
The two colors are in BGR format: the first number represents the amount of blue, from 0 to 255. The second number gives the amount of green, and the third number gives the amount of red. The colors set in the example above will create a black background (0,0,0) with white text (255,255,255).
The textScaling variable says how much we want to change the text font from opencv’s default size. With a scaling factor of 1.0, we won’t change the font size at all.
-
Create a new blank image using a
Matobject. The name of the type for an image inopencvisMat, which is short for matrix, as images are represented by (possibly multidimensional) matrices in opencv. TheMatconstructor takes four arguments:- height,
- width,
- an integer that tells
opencvhow colors are being represented, - the background color
Important:
- Just like in the
VideoWriterconfiguration, you will want to be sure that you give theheightandwidthin pixels, not in number of characters. - Be sure you specify the height first. (Elsewhere it's X then Y, but here it's Y then X!)
- The integer you need for the color representation is provided for you in the
COLORTYPEconstant, which is declared in theAsciimationclass—so just pass inCOLORTYPEas the third argument.
-
Go through each of the characters in the
sprite_data member. For each, you’ll need to- Get the character’s value from the
Spriteobject. - Calculate the right place in the frame to put the character.
- Create a
Pointobject that holds the position on the screen in pixels.Pointis anotheropencvclass that has a parameterized constructor:Point(xPosition, yPosition). - Call the
opencvfunctionputText.putTexttakes six arguments: aMatobject; a string; aPoint; a font; a text-scaling value; and a color. TheMatobject will be the one you created above. The string will be one character long (see hint below), and should hold the appropriate character from yourSpriteobject. ThePointwill be the position on the screen you calculated above. The font is stored as a static data member of theAsciimationclass. The text scaling and color values are as you defined them above.
- Get the character’s value from the
-
Add the frame to the
VideoWriterobject by calling itswritemember function.writetakes one argument, aMatobject.
Helpful Hints
Making a String from a Character
Here’s an example of making a string out of a char:
char c = 's';
string cStr = string(1, c);
You Can Save Individual Frames
The individual frames we are generating are images in opencv just like the ones you created in Homework 1. If you’re running into problems with your animation, consider saving out individual frames as images so that you can see what is happening in them.
(When logged in, completion status appears here.)