21

I'm trying to learn opencv using python and came across this code below:

import cv2
import numpy as np
from matplotlib import pyplot as plt

BLUE = [255,0,0]

img1 = cv2.imread('opencv_logo.png')
replicate = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_WRAP)
constant= cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_CONSTANT,value=BLUE)

plt.subplot(231),plt.imshow(img1,'gray'),plt.title('ORIGINAL')
plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('REPLICATE')
plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('REFLECT')

plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('REFLECT_101')
plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP')
plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')

plt.show()

source : http://docs.opencv.org/master/doc/py_tutorials/py_core/py_basic_ops/py_basic_ops.html#exercises

What does plt.imshow(img1, 'gray') do? I tried searching Google and all I could understand was that the 'gray' argument was a Color map. But my image (pic is there on the site. see link) is not displayed in grayscale. I tried removing the second argument. So the code was like plt.imshow(img1). It executes. The image remains same as before. Then what does the second argument 'gray' do? Can someone explain all this to me? Any help appreciated. Thanks.

PS. I'm totally new to Matplotlib

Clive
  • 1,137
  • 7
  • 19
  • 28

1 Answers1

33

When img1 has shape (M,N,3) or (M,N,4), the values in img1 are interpreted as RGB or RGBA values. In this case the cmap is ignored. Per the help(plt.imshow) docstring:

cmap : ~matplotlib.colors.Colormap, optional, default: None

If None, default to rc image.cmap value. cmap is ignored when X has RGB(A) information

However, if img were an array of shape (M,N), then the cmap controls the colormap used to display the values.


import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.axes_grid1 as axes_grid1
np.random.seed(1)

data = np.random.randn(10, 10)

fig = plt.figure()
grid = axes_grid1.AxesGrid(
    fig, 111, nrows_ncols=(1, 2), axes_pad = 0.5, cbar_location = "right",
    cbar_mode="each", cbar_size="15%", cbar_pad="5%",)

im0 = grid[0].imshow(data, cmap='gray', interpolation='nearest')
grid.cbar_axes[0].colorbar(im0)

im1 = grid[1].imshow(data, cmap='jet', interpolation='nearest')
grid.cbar_axes[1].colorbar(im1)
plt.savefig('/tmp/test.png', bbox_inches='tight', pad_inches=0.0, dpi=200,)

enter image description here

unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • 1
    Thanks. Could you explain what cmap is used for? Why do we use color maps? – Clive Sep 02 '14 at 14:51
  • 5
    The colormap is a dictionary which maps numbers to colors. Matplotlib provides many [built-in colormaps](http://wiki.scipy.org/Cookbook/Matplotlib/Show_colormaps). When you have a 2D array, such as `data` above, the values at each grid point is a float between 0 and 1. The `gray` colormap maps 0 to black and 1 to white. The `jet` colormap maps 0 to blue and 1 to red. See the link for a visual display of the colors in between. – unutbu Sep 02 '14 at 14:56
  • 1
    Correction: The `data` array used above has values which are normally distributed; by default the colormap adjusts the colors to the data's range. – unutbu Sep 02 '14 at 16:14
  • @ubuntu: I understood your first comment, then got confused after the last one, what exactly does it mean? a previously color image, was represented in floats (2d, 1 channel), and now, we want to get that back to rgb ? – Hossein Nov 06 '16 at 07:08
  • @Hossein: Since `data = np.random.randn(10, 10)`, the minimum and maximum values of `data` could be different from 0 and 1. The `imshow` function normalizes `data` so that `min(data)` gets mapped to 0 and `max(data)` gets mapped to 1. Then the colormap is applied. The purpose of the [second comment](http://stackoverflow.com/questions/25625952/matplotlib-what-is-the-function-of-cmap-in-imshow/25626042?noredirect=1#comment40039776_25626042) was merely to stress the existence of that normalization step. – unutbu Nov 06 '16 at 11:00
  • Thanks.I have seen people using cmap=gray, on color images, and it works, but I cant do it ([here](https://render.githubusercontent.com/view/ipynb?commit=22fc6dd82cbbb929965f3ce5248eaac422cd8560&enc_url=68747470733a2f2f7261772e67697468756275736572636f6e74656e742e636f6d2f706b6d6974616c2f4341444c2f323266633664643832636262623932393936356633636535323438656161633432326364383536302f73657373696f6e2d302f73657373696f6e2d302e6970796e62&nwo=pkmital%2FCADL&path=session-0%2Fsession-0.ipynb&repository_id=62756493#resizing-images) why is that? – Hossein Nov 07 '16 at 06:44
  • The [imshow function](http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.imshow) can accept a data array of shape `(n,m)`, `(n,m,3)` or `(n,m,4)`. When you specify a colormap, the data array must be of shape `(n,m)`. Per the docs, "cmap is ignored when X has RGB(A) information". – unutbu Nov 07 '16 at 13:09