After some research, this is what I came up with. You can use the Python Imaging Library - specifically the Pillow fork: https://python-pillow.imtqy.com/
Install the package, then you can use the Image.open method from the Image class to open the image. If there is a color map in your image, the image will be automatically loaded as an indexed image. To make this useful, use NumPy and use the numpy.array constructor. I assume you can use NumPy because scikit-image and OpenCV use NumPy as the main basis for image manipulation:
from PIL import Image import numpy as np im = Image.open("image.png")
Finally, if you need a color map / palette that was actually used for the image, use the Image.getpalette method, which is part of the Image class. However, this will give you a list of num_colours x 3 elements. Therefore, to determine how many colors you have, simply divide the length of this list by 3. However, the color map loaded in MATLAB is normalized , while getpalette does not normalize this value and the default image type is loaded. So you will need to determine the type of image by looking at the converted version of the NumPy image, then use this to normalize your color map:
In this way:
To demonstrate that we have this correctly, here is an indexed image from a question that I helped solve a while ago :

Using MATLAB to load in this image:
[indexed, map] = imread('http://i.stack.imgur.com/OxFwB.png');
I get this when I focus on rows 280 through 290 and columns 400 through 410 in the indexed image as a double check:
>> indexed(280:290, 400:410) ans = 59 60 61 62 65 64 59 56 56 53 49 61 61 64 65 65 60 60 57 58 53 53 67 62 67 56 60 62 60 61 51 59 55 65 60 62 61 58 58 53 55 57 55 54 66 58 56 59 56 56 52 55 52 55 52 68 68 61 61 61 56 56 55 55 57 59 66 59 59 66 68 62 62 60 60 60 53 70 68 64 58 61 63 67 61 67 56 59 69 67 63 64 62 65 63 68 67 64 58 61 68 68 72 71 73 70 66 63 64 64 68 67 70 71 71 69 64 64 65 64 58
Here is what I get in Python when I run the equivalent code to get the indexed image. Please note that I physically downloaded the image to my computer and downloaded it from the disk. Note that NumPy starts indexing from 0, not 1, so I had to subtract ranges by 1. Also note that the end of the range operator is exclusive :
In [29]: indexed[279:290, 399:410] Out[29]: array([[59, 60, 61, 62, 65, 64, 59, 56, 56, 53, 49], [61, 61, 64, 65, 65, 60, 60, 57, 58, 53, 53], [67, 62, 67, 56, 60, 62, 60, 61, 51, 59, 55], [65, 60, 62, 61, 58, 58, 53, 55, 57, 55, 54], [66, 58, 56, 59, 56, 56, 52, 55, 52, 55, 52], [68, 68, 61, 61, 61, 56, 56, 55, 55, 57, 59], [66, 59, 59, 66, 68, 62, 62, 60, 60, 60, 53], [70, 68, 64, 58, 61, 63, 67, 61, 67, 56, 59], [69, 67, 63, 64, 62, 65, 63, 68, 67, 64, 58], [61, 68, 68, 72, 71, 73, 70, 66, 63, 64, 64], [68, 67, 70, 71, 71, 69, 64, 64, 65, 64, 58]], dtype=uint8)
What corresponds ... now what about color cards? Let's take a look at the first 10 lines of color maps between MATLAB and Python:
MATLAB
>> format long g; >> map(1:10,:) ans = 0 0 0 0.0156862745098039 0.00392156862745098 0.0274509803921569 0.0313725490196078 0.00784313725490196 0.0588235294117647 0.0470588235294118 0.0117647058823529 0.0901960784313725 0.0627450980392157 0.0156862745098039 0.12156862745098 0.0784313725490196 0.0196078431372549 0.152941176470588 0.0941176470588235 0.0235294117647059 0.184313725490196 0.109803921568627 0.0274509803921569 0.215686274509804 0.125490196078431 0.0313725490196078 0.247058823529412 0.141176470588235 0.0352941176470588 0.27843137254902
Python
In [30]: map[:10,:] Out[30]: array([[ 0. , 0. , 0. ], [ 0.01568627, 0.00392157, 0.02745098], [ 0.03137255, 0.00784314, 0.05882353], [ 0.04705882, 0.01176471, 0.09019608], [ 0.0627451 , 0.01568627, 0.12156863], [ 0.07843137, 0.01960784, 0.15294118], [ 0.09411765, 0.02352941, 0.18431373], [ 0.10980392, 0.02745098, 0.21568627], [ 0.1254902 , 0.03137255, 0.24705882], [ 0.14117647, 0.03529412, 0.27843137]])
... it looks like it matches!