“This is the second day of my participation in the First Challenge 2022.

Coordinate systems in OpenCV

To better demonstrate the coordinate system in OpenCV and how to access each pixel, let’s first look at the following low-resolution images:

The size of the image is 32×41 pixels, which means the image has 1312 pixels. To further illustrate, we can add a pixel count on each axis, as shown below:

Now, let’s look at the pixel index of the form (x,y)(x, y). Note that the pixel index starts at zero, which means that the top left corner is at (0,0)(0, 0)(0,0), not (1,1)(1, 1)(1,1). In the following image, four individual pixels are indexed, and the upper left corner of the image is the coordinates of the origin:

Information about individual pixels can be extracted from the image in the same way that individual elements of arrays are referenced in Python.

Channel order in OpenCV

In OpenCV use, the color channel order is BGR color format instead of RGB format. You can see the order of the three channels in the figure below:

The pixel structure of the BGR image is shown below. As a demonstration, the diagram details how to access the Pixel (y=n, x=1) :

Tips: The original developers of OpenCV chose the BGR color format (rather than RGB) because the BGR color format was very popular with software vendors and camera manufacturers at the time, so BGR was chosen for historical reasons.

In addition, there are other Python packages that use RGB color format (for example, The RGB color format is used by Matplotlib, the most popular 2D Python drawing library that offers a variety of drawing methods, See the Python-Matplotlib visualization for more details). Therefore, we need to know how to convert images from one format to another. Once we’ve mastered how to convert an image from one format to another, we can choose to use OpenCV for image processing and use the functions provided by the Matplotlib package to display the image. Next, let’s look at how to handle the different color formats used by the two libraries. First, we load the image using the cv2.imread() function:

import cv2
img_OpenCV = cv2.imread('sigonghuiye.jpeg')
Copy the code

The image is stored in the img_OpenCV variable because the cv2.imread() function loads the image in BGR order. We then use the cv2.split() function to split the loaded image into three channels (b, G, r). The argument to this function is the image we want to split:

b, g, r = cv2.split(img_OpenCV)
Copy the code

The next step is to merge the channels (to build a new image based on the information provided by the channels), but in a different order than the original image. We change the order of the B and R channels to follow the RGB format, which is the Matplotlib format we need:

img_matplotlib = cv2.merge([r, g, b])
Copy the code

At this point, we have two images (img_OpenCV and img_matplotlib). Next, we will draw them using OpenCV and Matplotlib respectively so that we can compare the results. First, we’ll display the two images with Matplotlib. To display two images in the same window using Matplotlib, we will use subplot, which places multiple images in the same window. Three parameters can be used in subplot, such as subplot(m,n, P), where the subplot processes the graph in the m×nm \times nm× N grid, where MMM determines the number of rows, NNN determines the number of columns, and PPP determines where to place the graph in the grid. To display the image using Matplotlib, use the imshow function. In this case, when we display two images horizontally, m=1m =1m =1 and n=2n =2n =2. We will use p=1p =1p =1 for the first subgraph (img_OpenCV) and p=2p =2p =2 for the second subgraph (img_matplotlib) :

from matplotlib import pyplot as plt
plt.subplot(121)
plt.imshow(img_OpenCV)
plt.subplot(122)
plt.imshow(img_matplotlib)
plt.show()
Copy the code

The program output is as follows:

You can see that the first subgraph displays the image in the wrong color (BGR order), while the second subgraph displays the image in the correct color (RGB order). Next, we use cv2.imshow() to display two images:

cv2.imshow('bgr image', img_OpenCV)
cv2.imshow('rgb image', img_matplotlib)
cv2.waitKey(0)
cv2.destroyAllWindows()
Copy the code

The following screen capture shows the result of executing the above code:

As expected, in the screen capture, the first image shows the image in the correct color, while the second image shows the image in the wrong color. Also, if we want to display two images in the same window, we can build a spliced image that contains the two images, joining them horizontally. To do this, we need to use NumPy’s concatenate() method. The parameters of this method are the two images to join and on which axis to stack, here we set axis = 1 (stack them horizontally) :

import numpy as np
img_concats = np.concatenate((img_OpenCV, img_matplotlib), axis=1)
cv2.imshow('bgr image and rgb image', img_concats)
cv2.waitKey(0)
cv2.destroyAllWindows()
Copy the code

The image below shows the connected image:

One factor to consider is that cv2.split() is a time-consuming operation. If you do need to divide channels, you should first consider using NumPy indexes. For example, if you want to get a channel of an image, you can get the channel using the NumPy index:

B = img_OpenCV[:, :, 0]
G = img_OpenCV[:, :, 1]
R = img_OpenCV[:, :, 2]
Copy the code

Another thing to note is that NumPy can be used to convert an image from BGR to RGB in a single statement:

img_matplotlib = img_OpenCV[:, :, ::-1]
Copy the code

Series of links

OpenCV image processing basics