Accessing and manipulating pixels in OpenCV with BGR images

Now, we are going to see how we can work with BGR images in OpenCV. OpenCV loads the color images so that the blue channel is the first, the green channel is the second, and the red channel is the third. Please see the Accessing and manipulating pixels in OpenCV with grayscale images section to fully understand this concept.

First, read the image to work with using the cv2.imread() function. The image should be in the working directory, or a full path to the image should be provided. In this case, we are going to read the logo.png image and store it in the img variable:

# The function cv2.imread() is used to read an image from the the working directory
# Alternatively, you should provide a full path of the image:
# Load OpenCV logo image (in this case from the working directoy):
img = cv2.imread('logo.png')

After the image has been loaded in img, we will gain access to some properties of the image. The first property we are going to extract from the loaded image is shape, which will tell us the number of rows, columns, and channels (if the image is in color). We will store this information in the dimensions variable for future use:

# To get the dimensions of the image use img.shape
# img.shape returns a tuple of number of rows, columns and channels (if a colour image)
# If image is grayscale, img.shape returns a tuple of number of rows and columns.
# So,it can be used to check if loaded image is grayscale or color image.
# Get the shape of the image:
dimensions = img.shape

Another property is the size of the image (img.size is equal to the multiplication of height × width × channels):

# Total number of elements is obtained by img.size:
total_number_of_elements= img.size

The property image datatype is obtained by img.dtype. In this case, the image datatype is uint8 (unsigned char), because values are in the [0 - 255] range:

# Image datatype is obtained by img.dtype.
# img.dtype is very important because a large number of errors is caused by invalid datatype.
# Get the image datatype:
image_dtype = img.dtype

To display an image, we will use the cv2.imshow() function to show an image in a window. The window automatically fits to the image size. The first argument to this function is the window name and the second one is the image to be displayed. In this case, since the loaded image has been stored in the img variable, we will use this variable as the second argument:

# The function cv2.imshow() is used to display an image in a window
# The first argument of this function is the window name
# The second argument of this function is the image to be shown.
# Each created window should have different window names.
# Show original image:
cv2.imshow("original image", img)

After the image is displayed, the cv2.waitKey() function, which is a keyboard binding function, will wait for a specified number of milliseconds for any keyboard event. The argument is the time in milliseconds. If any key is pressed at that time, the program will continue. If the number of milliseconds is 0 (cv2.waitKey(0)), it will wait indefinitely for a keystroke. Therefore, this function will allow us to see the displayed window waiting for a keystroke:

# The function cv2.waitKey(), which is a keyboard binding function, waits for any keyboard event.
# This function waits the value indicated by the argument (in milliseconds).
# If any keyboard event is produced in this period of time, the program continues its execution
# If the value of the argument is 0, the program waits indefinitely until a keyboard event is produced:
cv2.waitKey(0)

To access (read) a pixel value, we need to provide the row and column of the desired pixel to the img variable, which contains the loaded image. For example, to get the value of the pixel (x=40, y=6), we would use the following code:

# A pixel value can be accessed by row and column coordinates.
# In case of BGR image, it returns an array of (Blue, Green, Red) values.
# Get the value of the pixel (x=40, y=6):
(b, g, r) = img[6, 40]

We have loaded the three pixel values in three variables, (b,g,r). You can see here that OpenCV uses the BGR format for color images. Additionally, we can access one channel at a time. In this case, we will use row, column, and the index of the desired channel for indexing. For example, to get only the blue value of the pixel (x=40, y=6), we would use the following code:

# We can only  access one channel at a time.
# In this case, we will use row, column and the index of the desired channel for indexing.
# Get only blue value of the pixel (x=40, y=6):
b = img[6, 40, 0]

The pixel values can be also modified in the same way. Remember that it is the (b, g, r) format. For example, to set the pixel (x=40, y=6) to red, perform the following:

# The pixel values can be also modified in the same way - (b, g, r) format:
img[6, 40] = (0, 0, 255)

Sometimes, you will have to deal with a certain region rather than one pixel. In this case, the ranges of the values should be provided instead of the individual values. For example, to get to the top-left corner of the image, enter the following:

# In this case, we get the top left corner of the image:
top_left_corner = img[0:50, 0:50]

The top_left_corner variable is another image (smaller than img), but we can play with it in the same way.