Visual Media Processing Using Matlab Beginner's Guide
上QQ阅读APP看书,第一时间看更新

Accessing image pixels and changing their values

To gain a better understanding of how MATLAB treats images, we have to revisit the way it stores them in the Workspace window. In the previous chapter, we discussed the origin of MATLAB and why it is an ideal choice for processing images. So, let's start with a simple quiz to freshen your memory.

Let's start using the matrix manipulation property of MATLAB to our advantage. We have already seen how to import an image into the Workspace window, using the imread function:

>> img = imread('my_image.bmp');

Importing the image automatically generates a matrix variable in the Workspace window. Its dimensions (rows, columns, and colors) are the same as the original image and it also has the same depth (given in bits). In our example, the resulting matrix is 485 x 656 and its type is uint8, it means that the matrix has 485 rows, 656 columns, and its values are unsigned integers with a depth of 8 bits spanning from 0 (black) to 255 (white). The Workspace window also shows which are the largest and smallest pixel values in the specified image (not necessarily 0 and 255):

In order to examine the value of a certain pixel, we should type in the command line the name of the image, followed by the row and column of the pixel we want (for example, the pixel in row 45, and column 150):

>> img(45,150)

The command we just typed in will produce a visible output, since we did not use a semicolon at the end. The output following the command will be as follows:

ans =

   63

Now that we see how to examine a specific pixel, it is easy for us to alter its value. Taking into account the acceptable range of values for a uint8 matrix element [0,255], we can type in the following code to change the value of the chosen pixel to 255, thus making it white:

>> img(45,150) = 255;

Of course, the change in one pixel is hardly noticeable for the naked eyes. So how about trying to change pixel values in a wider area, for example, a window of size 20 x 20 pixels. This is where things start becoming a little more complicated, since now we have got to choose between two alternative ways to perform this task; the usual programming technique using for loops and the MATLAB technique, using indexing. We will address both ways, because very interesting conclusions can be drawn from this example.

Changing the pixel values of a square area using loops

For those readers who are already familiar with programming, this section shouldn't be too hard to understand. However, since the book aims at wider audiences, we will try to explain the logic behind using loops to accomplish changing pixel values.

In traditional programming languages, such as C, C++, or Java, the way to scan through every element of a vector (one-dimensional matrix) is through increasing the value of a variable, let's call it pos, which holds the position of an element scanned at each step, starting from the first position and ending at the last position. This variable will be used to define which element of the array we examine (or change) in each step.

For example, if we want to assign the value 255 to every element of matrix A with dimensions 1 x 5, we will write the following lines of code:

for pos = 1:5
A(pos)=255;
end
Note

If you are a more experienced programmer, you might find it odd that we use a variable (A) that seems to grow in size inside a loop. Furthermore, the variable is automatically generated at the first step of the loop. Both of these actions are feasible in MATLAB, however the former should generally be avoided for the sake of performance. For the time being, we are going to take advantage of the feasibility of these actions, to keep things simple.

In case of a two-dimensional matrix, for example, B of size 5 x 10, the value assigning procedure will require two for loops, one for the rows and one for the columns. In accordance with this, we should use the following code, using two variables, pos_r (to be used for rows) and pos_c (to be used for columns), to loop through the matrix:

for pos_r = 1:5
  for pos_c = 1:10 
    B(pos_r, pos_c)=255;
  end
end

Now, in case we want to alter the values of the elements of matrix B in a 2 x 4 area starting at the second row and second column, we should use the following code:

for pos_r = 2:2+2
  for pos_c = 2:2+4
    B(pos_r, pos_c)=255;
  end
end
Note

If you have experience with other programming languages, you must have noticed a significant difference in the way we number the positions inan array. While in C/C++, for example, numbering the elements of an N x 1 array starts with 0 and ends at N-1, MATLAB uses values from 1 to N.

Changing the pixel values of a square area using indexing

In the previous section, we saw a generic programming way to alter the values of the elements in a matrix. However, following this procedure is both cumbersome and inefficient. Many lines of code will be necessary to manipulate matrix values in predefined areas, while the use of for loops is computationally inefficient in MATLAB.

An alternative method is to use the powerful indexing method provided by MATLAB. Indexing is a flexible and expressive way for the selection of user-defined subsets of the elements of a matrix. Here, we will present the basic functionalities of indexing using the same examples we did in the previous section.

First, let's try to replace the case of setting all elements of a 1 x 5 matrix A to 255. Instead of using a for loop, we now use indexing:

A(1:5)=255;

In this example we have achieved the same result as before, using one line of code instead of three. Imagine what happens in the case of a two-dimensional matrix, for example, B. Even more lines of code are now saved:

B(1:5, 1:10) = 255;

By now, you should be starting to get an idea. Instead of using the indices we want in a for loop, we plug them in the row and column dimensions of the matrix we want to manipulate. Following this rationale, let's alter the values of the elements in the same 2 x 4 area as before:

B(2:2+2, 2:2+4) = 255;

Writing and using scripts

Even if you have understood everything so far, you might still be wondering whether we can use the command line for all the previous processes. The answer is we can do so. If you copy and paste all the pieces of code given in the previous command line, everything should work as described. You can try it for yourself.

However, not every process should be executed through the command line. You should try to write code in files, so that you may re-use it at a later point in time. This is where the Editor comes in picture. Let's say you want to save the part of code used for the two-dimensional matrix B, with both methods, printing the result on screen, so that we can check whether the results are identical (they should be, since the methods are equivalent). What we will do is, copy and paste the following fragments of code into the Editor and then save the file with the name MyFirstScript.m. The extension .m will be added by MATLAB, so don't worry about it. You just assign the name.

for pos_r = 1:5
  for pos_c = 1:10 
    B(pos_r, pos_c) = 255;
  end
end
B % To print the result from the loop method
clear B;  % Erase matrix B from the workspace
B(1:5, 1:10) = 255; 
B % To print the result from the indexing method 

Now, you can use your file in MATLAB, provided that you have saved it in your working directory (it should be visible in Current Folder). Just type the following code in the command line:

>> MyFirstScript

You should see the following result in the Command Window:

As we can see, both results are identical. To verify this, we could use the MATLAB's isequal function, which compares two matrices used as input and output. It assigns 1 if they are equal and 0 if they are not. Let's see how it works, by comparing matrix B to itself:

>> isequal(B,B)

The output of the previous code is as follows:

ans =
     1

Indeed, the result was 1. Now, let's make some holes in matrix B and see if they are the same. Suppose, we want to change the values of the elements residing in the area defined in the previous examples to 0. Switch to Editor, erase the two lines that have to do with printing the matrix B, after the two methods add the following lines at the end of your previous script and then save it as MySecondScript.m:

for pos_r = 2:2+2
  for pos_c = 2:2+4
    B(pos_r, pos_c)= 0;
  end
end
B % print the result of the loop method
clear B;% Erase matrix B from the workspace
B(1:5, 1:10) = 255;% Re-create matrix B
B(2:2+2, 2:2+4) = 0;
B % print the result of the indexing method

This time type the following code in the command line:

>> MySecondScript

You should now be able to see the following result in your Command Window:

Note

In the two previous examples, you might have noticed the way to insert comments in MATLAB is by using the % symbol before the comment. Whatever follows a % symbol in a line is not executed. Comments are usually used for providing explanations about the code.

Now that you know the basic theory, you should be able to tackle image processing tasks, such as making a rectangular area of a grayscale image equal to a value of your choice. So, let's see if this is true.