Cognotics Home  
Search Cognotics:
.
Home > OpenCV Resources > Seeing With OpenCV > Part 1 Pages:   Prev   1   2   3   4  
.
 
Part 1: Introduction to OpenCV (Continued)
This article originally appeared in SERVO Magazine, January 2007. Reprinted by permission of T & L Publications, Inc.
 

Color Conversions

Figure 5 shows code for converting a color image to grayscale. OpenCV has built-in support for converting to and from many useful color models, including RGB, HSV, YCrCb, and CIELAB. (For a discussion of color models, see "The World of Color," SERVO Magazine, November 2005.)

.  
Figure 5. Example program for converting a color image to grayscale. (Click to select, then copy.)

Note that the conversion function, cvCvtColor(), requires two images in its input list. The first one, pRGBImg, is the source image. The second, pGrayImg, is the destination image. It will contain the conversion result when cvCvtColor() returns.

Because this paradigm of passing source and destination images to a processing function is common in OpenCV, you'll frequently need to create a destination image. On line 25, a call to cvCreateImage() creates an image the same size as the original, with uninitialized pixel data.

How OpenCV Stores Images

OpenCV stores images as a C structure, IplImage. IPL stands for Image Processing Library, a legacy from the original OpenCV versions that required this product.

The IplImage datatype is defined in CXCORE. In addition to raw pixel data, it contains a number of descriptive fields, collectively called the Image Header. These include

   

width - image width in pixels

height - image height in pixels

depth - one of several predefined constants that indicate the number of bits per pixel per channel. For example, if depth=IPL_DEPTH_8U, data for each pixel channel are stored as eight-bit, unsigned values

nChannels - the number of data channels (from one to four). Each channel contains one type of pixel data. For example, RGB images have three channels - red, green, and blue intensities. (These are sometimes called BGR images, because pixel data are stored as blue, green, then red values.) Grayscale images contain only one channel - pixel brightness.

Accessing Pixel Values

It's possible to create many types of functionality using OpenCV without directly accessing raw pixel data. For example, the face detection, tracking, and recognition programs described later in this series never manipulate raw pixel data directly. Instead, they work with image pointers and other high-level constructs. All pixel-level calculations are performed inside OpenCV functions. However, if you write your own image-processing algorithms, you may need to access raw pixel values. Here are two ways to do that:

1. Simple Pixel Access

The easiest way to read individual pixels is with the cvGet2D() function:

  CvScalar cvGet2D(const CvArr*, int row, int col);

This function takes three parameters: a pointer to a data container (CVArr*) and array indices for row and column location. The data container can be an IplImage structure. The topmost row of pixels is row=0, and the bottommost is row=height-1.

The cvGet2D() function returns a C structure, CvScalar, defined as

  typedef struct CvScalar
  {
    double val[4];
  }
  CvScalar;

The pixel values for each channel are in val[i]. For grayscale images, val[0] contains pixel brightness. The other three values are set to 0. For a three-channel, BGR image, blue=val[0], green=val[1], and red=val[2].

The complementary function, cvSet2D() allows you to modify pixel values. It's defined as

  void cvSet2D(CvArr*, int row, int col, CvScalar);

2. Fast Pixel Access

Although cvGet2D() and cvSet2D() are easy to use, if you want to access more than a few pixel values, and performance matters, you'll want to read values directly from the raw data buffer, IplImage.imageData.

Image data in the buffer are stored as a 1D array, in row-major order. That is, all pixel values in the first row are listed first, followed by pixel values in the second row, and so on.

For performance reasons, pixel data are aligned, and padded if necessary, so that each row starts on an even four-byte multiple. A second field, IplImage.widthStep, indicates the number of bytes between the start of each row's pixel data. That is, row i starts at IplImage.imageData + i*IplImage.widthStep.

IplImage.imageData is defined as type char*, so you may need to cast the data type. For example, if your image data are unsigned bytes (the most common input type), you'd cast each value to unsigned char* before assigning, or otherwise using, it.

If you're accessing data from a grayscale (single-channel) image, and the data depth is eight bits (one byte per pixel), you'd access pixel[row][col] with

  pixel[row][col] =
    (uchar*)(pImg->imageData + row*pImg->widthStep + col);

Finally, if image depth is greater than eight bits (for example, IPL_DEPTH_32S), you'll need to either transfer multiple bytes, or cast the buffer to a multi-byte datatype. You'll also need to multiply the width step by the number of data bytes for your image depth. (For example, for IPL_DEPTH_32S, you'd cast the buffer to (int*) and multiply widthStep by four.) It's unlikely, however, that you'll encounter a situation in which you must access multi-byte pixel values directly.

Finding Help

If you have problems installing or using OpenCV, the first place to turn for help is the FAQ (faq.htm) in your OpenCV docs directory. The INSTALL file, at the root of your OpenCV directory, also contains helpful setup and troubleshooting tips. If these don't answer your question, you may want to post a query to the official Yahoo! user group.

API documentation for each module is in the docs/ref subdirectory. All reference manuals except the one for CVAUX are linked from index.htm, in the docs directory.

Next...

In Part 2, I'll show you how to detect faces with OpenCV and explain the algorithm behind the interface. Be seeing you!

.
Source Code for this Article CONTINUED   Prev   1   2   3   4
. .
.
.
 
Source Code for this Article
 
Related Resources:

Download OpenCV
Official OpenCV usergroup
OpenCV Wiki

 
 
Articles in this series:

Part 1: Introduction to OpenCV

Part 2: Finding Faces in Images

Part 3: Follow that Face!

Part 4: Face Recognition With Eigenface

Part 5: Implementing Eigenface
 
.
bottom margin
Home | OpenCV Resources | Seeing With OpenCV