Rich
Rich

Reputation: 1163

Can't display a normal image in matplotlib, it keeps displaying with the jet colormap

I have code that displays the MISER regions of an image:

import numpy as np
import cv2
import sys
import matplotlib.pyplot as plt

imp1 = sys.argv[1]
img1 = cv2.imread(imp1)

mser = cv2.MSER()
gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
vis = img1.copy()

regions = mser.detect(gray, None)
hulls = [cv2.convexHull(p.reshape(-1, 1, 2)) for p in regions]
cv2.polylines(vis, hulls, 1, (0, 255, 0))

def plot_stuff(img1, img1_name, img2, img2_name):
    fig,axes = plt.subplots(1,2,figsize=(15,6))


    axes[0].imshow(img1, cmap='Greys_r')
    axes[0].set_title(img1_name)


    axes[1].imshow(img2)
    axes[1].set_title(img2_name)

    fig.suptitle("All Images")
    plt.show()

plot_stuff(img1, 'Original', vis, 'MISER Regions')

And it works fine, except it's blue:

enter image description here And that's where I got stuck. Because no matter what I do, I can't get it to show the Image as gray, and the MISER lines as green. It keeps returning jet:

enter image description here

Even when I show just the image, it still returns jet. Why isn't there an RGB colormap? Better yet, why does there have to be a colormap at all, why can't it just show the normal image?

Upvotes: 3

Views: 1059

Answers (2)

Ed Smith
Ed Smith

Reputation: 13206

You data is stored as 64 bit numpy arrays, from the docs,

For RGB and RGBA images, matplotlib supports float32 and uint8 data types

You either need it in this format or need to specify a colormap. It seems the other issue is that 'cv2.polylines' returns an images, which means you cannot set the colours of the lines and the background separately. A solution to this is to use a blank transparent image of the same size to draw the mser (MISER!?) curves and then plot them both on the same axis,

import numpy as np
import cv2
import sys
import matplotlib.pyplot as plt

imp1 = sys.argv[1]
img1 = cv2.imread(imp1)

mser = cv2.MSER()
gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
vis = np.zeros([img1.shape[0],img1.shape[1],4]) 

regions = mser.detect(gray, None)
hulls = [cv2.convexHull(p.reshape(-1, 1, 2)) for p in regions]
cv2.polylines(vis, hulls, 1, (0, 255, 0))
vis = np.array(vis, dtype=np.uint8)

#Copy green channel data to (alpha) transparent channel
vis[:,:,3] = vis[:,:,1]

def plot_stuff(img1, img1_name, img2, img2_name):
    fig,axes = plt.subplots(1,2,figsize=(15,6))

    print(img1.shape)
    axes[0].imshow(np.sum(img1,2), cmap='Greys_r')
    axes[0].set_title(img1_name)

    axes[1].imshow(np.sum(img1,2), cmap='Greys_r')
    axes[1].imshow(img2)
    axes[1].set_title(img2_name)

    fig.suptitle("All Images")
    plt.show()

plot_stuff(img1, 'Original', vis, 'MISER Regions')

which for me returns, enter image description here

using matplotlib.version 1.4.3' and cv2.version'$Rev: 4557 $'

Upvotes: 1

Aguy
Aguy

Reputation: 8059

The imshow docs says that cmap is ignored when image has RGB information.

You can consider creating a gray level image

newimg = numpy.sum(img, 2)

Then

ax.imshow(newimg, cmap='gray')

Upvotes: 0

Related Questions