Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
OpenCV Computer Vision Application Programming Cookbook Second Edition

You're reading from  OpenCV Computer Vision Application Programming Cookbook Second Edition

Product type Book
Published in Aug 2014
Publisher Packt
ISBN-13 9781782161486
Pages 374 pages
Edition 1st Edition
Languages
Author (1):
Robert Laganiere Robert Laganiere
Profile icon Robert Laganiere

Table of Contents (18) Chapters

OpenCV Computer Vision Application Programming Cookbook Second Edition
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Playing with Images Manipulating Pixels Processing Color Images with Classes Counting the Pixels with Histograms Transforming Images with Morphological Operations Filtering the Images Extracting Lines, Contours, and Components Detecting Interest Points Describing and Matching Interest Points Estimating Projective Relations in Images Processing Video Sequences Index

Chapter 2. Manipulating Pixels

In this chapter, we will cover the following recipes:

  • Accessing pixel values

  • Scanning an image with pointers

  • Scanning an image with iterators

  • Writing efficient image-scanning loops

  • Scanning an image with neighbor access

  • Performing simple image arithmetic

  • Remapping an image

Introduction


In order to build computer vision applications, you need to be able to access the image content and eventually modify or create images. This chapter will teach you how to manipulate the picture elements (also known as pixels). You will learn how to scan an image and process each of its pixels. You will also learn how to do this efficiently, since even images of modest dimensions can contain hundreds of thousands of pixels.

Fundamentally, an image is a matrix of numerical values. This is why, as we learned in Chapter 1, Playing with Images, OpenCV 2 manipulates them using the cv::Mat data structure. Each element of the matrix represents one pixel. For a gray-level image (a black-and-white image), pixels are unsigned 8-bit values where 0 corresponds to black and 255 corresponds to white. In the case of color images, three primary color values are required in order to reproduce the different visible colors. This is a consequence of the fact that our human visual system is trichromatic...

Accessing pixel values


In order to access each individual element of a matrix, you just need to specify its row and column numbers. The corresponding element, which can be a single numerical value or a vector of values in the case of a multi-channel image, will be returned.

Getting ready

To illustrate the direct access to pixel values, we will create a simple function that adds salt-and-pepper noise to an image. As the name suggests, salt-and-pepper noise is a particular type of noise in which some randomly selected pixels are replaced by a white or a black pixel. This type of noise can occur in faulty communications when the value of some pixels is lost during the transmission. In our case, we will simply randomly select a few pixels and assign them a white color.

How to do it...

We create a function that receives an input image. This is the image that will be modified by our function. The second parameter is the number of pixels on which we want to overwrite white values:

void salt(cv::Mat...

Scanning an image with pointers


In most image-processing tasks, you need to scan all pixels of the image in order to perform a computation. Considering the large number of pixels that will need to be visited, it is essential that you perform this task in an efficient way. This recipe, and the next one, will show you different ways of implementing efficient scanning loops. This recipe uses the pointer arithmetic.

Getting ready

We will illustrate the image-scanning process by accomplishing a simple task: reducing the number of colors in an image.

Color images are composed of 3-channel pixels. Each of these channels corresponds to the intensity value of one of the three primary colors, red, green, and blue. Since each of these values is an 8-bit unsigned character, the total number of colors is 256x256x256, which is more than 16 million colors. Consequently, to reduce the complexity of an analysis, it is sometimes useful to reduce the number of colors in an image. One way to achieve this goal...

Scanning an image with iterators


In object-oriented programming, looping over a data collection is usually done using iterators. Iterators are specialized classes that are built to go over each element of a collection, hiding how the iteration over each element is specifically done for a given collection. This application of the information-hiding principle makes scanning a collection easier and safer. In addition, it makes it similar in form no matter what type of collection is used. The Standard Template Library (STL) has an iterator class associated with each of its collection classes. OpenCV then offers a cv::Mat iterator class that is compatible with the standard iterators found in the C++ STL.

Getting ready

In this recipe, we again use the color reduction example described in the previous recipe.

How to do it...

An iterator object for a cv::Mat instance can be obtained by first creating a cv::MatIterator_ object. As is the case with cv::Mat_, the underscore indicates that this is a template...

Writing efficient image-scanning loops


In the previous recipes of this chapter, we presented different ways of scanning an image in order to process its pixels. In this recipe, we will compare the efficiency of these different approaches.

When you write an image-processing function, efficiency is often a concern. When you design your function, you will frequently need to check the computational efficiency of your code in order to detect any bottleneck in your processing that might slow down your program.

However, it is important to note that unless necessary, optimization should not be done at the price of reducing the program clarity. Simple code is indeed always easier to debug and maintain. Only code portions that are critical to a program's efficiency should be heavily optimized.

How to do it...

In order to measure the execution time of a function or a portion of code, there exists a very convenient OpenCV function called cv::getTickCount(). This function gives you the number of clock cycles...

Scanning an image with neighbor access


In image processing, it is common to have a processing function that computes a value at each pixel location based on the value of the neighboring pixels. When this neighborhood includes pixels of the previous and next lines, you then need to simultaneously scan several lines of the image. This recipe shows you how to do it.

Getting ready

To illustrate this recipe, we will apply a processing function that sharpens an image. It is based on the Laplacian operator (which will be discussed in Chapter 6, Filtering the Images). It is indeed a well-known result in image processing that if you subtract the Laplacian from an image, the image edges are amplified, thereby giving a sharper image.

This sharpened value is computed as follows:

sharpened_pixel= 5*current-left-right-up-down;

Here, left is the pixel that is immediately on the left-hand side of the current one, up is the corresponding one on the previous line, and so on.

How to do it...

This time, the processing...

Performing simple image arithmetic


Images can be combined in different ways. Since they are regular matrices, they can be added, subtracted, multiplied, or divided. OpenCV offers various image arithmetic operators, and their use is discussed in this recipe.

Getting ready

Let's work with a second image that we will combine to our input image using an arithmetic operator. The following represents this second image:

How to do it...

Here, we add two images. This is useful when we want to create some special effects or to overlay information over an image. We do this by calling the cv::add function, or more precisely here, the cv::addWeighted function, since we want a weighted sum as follows:

   cv::addWeighted(image1,0.7,image2,0.9,0.,result);

The operation results in a new image, as seen in the following screenshot:

How it works...

All binary arithmetic functions work the same way. Two inputs are provided and a third parameter specifies the output. In some cases, weights that are used as scalar multipliers...

Remapping an image


In the recipes of this chapter, you learned how to read and modify the pixel values of an image. The last recipe will teach you how to modify the appearance of an image by moving its pixels. The pixel values are not changed by this process; it is rather the position of each pixel that is remapped to a new location. This is useful in order to create special effects on an image or to correct image distortions caused, for example, by a lens.

How to do it...

In order to use the OpenCV remap function, you simply have to first define the map to be used in the remapping process. Second, you have to apply this map on an input image. Obviously, it is the way you define your map that will determine the effect that will be produced. In our example, we define a transformation function that will create a wavy effect on the image:

// remapping an image by creating wave effects
void wave(const cv::Mat &image, cv::Mat &result) {

  // the map functions
  cv::Mat srcX(image.rows,image...
lock icon The rest of the chapter is locked
You have been reading a chapter from
OpenCV Computer Vision Application Programming Cookbook Second Edition
Published in: Aug 2014 Publisher: Packt ISBN-13: 9781782161486
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime}