I. Issues
When using OpenCV in Python, it is usually done by reading in the image and then displaying the image, but recently when learning OpenCV the results of doing so were quite different from the expected results. After searching for information, I realized that there are some differences in the use of imshow() and imshow() in OpenCV, which can easily lead to strange results if you don't pay attention.
The following sample code and runtime results show this difference:
import cv2 import as plt # Read in images in grayscale mode messi=('',0) # Use imshow to display images (messi),('messi_plt') ([]),([]) #Hide the axes () # Use opencv's imshow to display images ('messi_cv',messi) (0) ()
The results are as follows.
On the left is the original image, in the center is the display result, and on the right is the display result. It's obvious to see that the result is more like a color image when it's clearly read in grayscale, which is obviously problematic.
II. Analysis and solutions
In order to compare and analyze the differences between imshow() and imshow() in OpenCV, the following two scenarios are illustrated for displaying a color map and displaying a grayscale map, respectively.
color chart
For color images, they are generally composed of R, G, and B channels. However, it should be noted that color images are loaded in BGR order in OpenCV and in RGB order in Matplotlib. So, naturally, when we read in the image and use it for display, there is no problem, but if we use it for display, there will be a problem, as shown in the result below.
Here omit the sample code (and the above almost the same, just do not set the parameter "0" in the can be), the results are as follows:
On the left is the original image, in the center is the result of the display, and on the right is the result of the display. Obviously, something is wrong with the results.
In order to solve this problem, the method is very simple, that is, the content of the channel R and channel B switched, and then use the display will be normal. The sample code for this method is given below:
import cv2 import as plt #Read color images messi=('',1) # Use imshow to display images (messi),('messi_plt') ([]),([]) #Hide the axes () ## Swap r and b channels to generate rgb-ordered images and display them b,g,r=(messi) #Channel splitting messi_rgb=((r,g,b)) #Convergence of channels (messi_rgb),('messi_rgb_plt') ([]),([]) () # Use opencv's imshow to display images ('messi_cv',messi) (0) ()
grayscale image
Grayscale images are single-channel images, and by definition don't have the same kind of problems as the color image above, and the results should be the same whether you use display or display. However, this is not the case (as shown in the example at the very beginning). I struggled for quite a while not knowing what the cause was, at first I thought it was a mismatch between the versions of opencv and matplotlib, but it turned out that after updating the versions I still had the problem. Then, I went to find the matplotlib API documentation and realized what was going on.
In the function, one of the arguments is cmap, the description given in the API documentation is:
cmap : str or Colormap, optional
The Colormap instance or registered colormap name used to map scalar data to colors. This parameter is ignored for RGB(A) data. Defaults to rcParams[“”] = ‘viridis'.
Roughly speaking, cmap gives how scalar values are mapped to color space, and is ignored for RGB(A) images; the default parameters can be viewed atrcParams[“”]
The document that the link goes to is the matplotlib example configuration file matplotlibrc. The document that the link goes to is matplotlib's example configuration document, matplotlibrc, which defines the default values of the various variables (this is why some of the parameters that we call functions in matplotlib work fine even if we don't give them values). As you can see here, the default value for cmap is viridis, which explains the problem when using display grayscale maps.
Therefore, in order to solve the problem, so that the normal display of grayscale map, the method is also very simple, is to modify the value of cmap to 'gray'. The sample code is as follows:
import cv2 import as plt #Read color images messi=('',0) # Use opencv's imshow to display images ('messi_cv',messi) (0) () # Use imshow to display images #cmap uses default values (messi),('messi_camp_default') ([]),([]) #Hide the axes () # Use imshow to display images #cmap set to 'gray' (messi,cmap='gray'),('messi_camp_gray') ([]),([]) #Hide the axes ()
The results of the run are:
On the left are the display results, and in the center and on the right are the display results.
In addition, the value of cmap can take the default parameter and 'gray', there are many other values for us to choose, the detailed description in thehere are. In fact, it's fine to know about these things, and when you actually use them, consult them and try them out. Just choose the right one according to the need.
Notes:
1. The imshow function in matplotlib is described in more detail inhere are。
2. A more detailed description of the documentation is in thehere are。
3. If you want to view or edit the matplotlibrc file on your computer, you can use this command matplotlib.matplotlib_fname() to get the path.
III. Summary
Due to some differences between imshow in OpenCV and imshow in Matplotlib, there are two main things to keep in mind when using it:
1. When displaying a color map, switch the b and r channels.
2. Remember to set the value of cmap to 'gray' when displaying a grayscale image.
This is the whole content of this article.