Repository: scikit-image/scikit-image

Issue:
skimage.novice not handling alpha values (or maybe something worse)
We'd like to use `skimage.novice` to teach image manipulation in Software Carpentry, but it looks like `skimage.novice` isn't handling alpha values correctly (though the problem may be deeper).

Test image is a shrunken survey map of Antarctic:

![ant](https://cloud.githubusercontent.com/assets/911566/5956124/ec8f23c4-a777-11e4-8d15-d32ffa153dbe.jpg)

Step 1: load and display using ipython 2.2.0 via conda 3.7.3 on Mac OS X 10.10.1:

```
In [1]: from skimage import novice
In [2]: p1 = novice.open('ant.jpg')
In [3]: p1.show()
```

![screen shot 2015-01-29 at 5 23 22 am](https://cloud.githubusercontent.com/assets/911566/5956100/b6e1caa6-a777-11e4-8ddc-cd4d15a7410f.png)

That's not right...

Step 2: paint the lower left green:

```
In [4]: p1.size
Out[4]: (120, 121)
In [5]: p1[0:60, 0:60] = (0, 255, 0)
In [6]: p1.show()
```

![screen shot 2015-01-29 at 5 24 02 am](https://cloud.githubusercontent.com/assets/911566/5956102/be1fda60-a777-11e4-8bcb-9a7f22ab8cb3.png)

Looks like alpha blending is going on.

Step 3: create a new blank white canvas:

```
In [7]: p2 = novice.Picture.from_size((200, 200), (255, 255, 255))
In [8]: p2.show()
```

![screen shot 2015-01-29 at 5 24 32 am](https://cloud.githubusercontent.com/assets/911566/5956106/c9872b2e-a777-11e4-8c7b-26ecb18a2c88.png)

That looks OK, but now color part of it green:

```
In [9]: p2[0:60, 0:60] = (0, 255, 0)
In [10]: p2.show()
```

![screen shot 2015-01-29 at 5 24 54 am](https://cloud.githubusercontent.com/assets/911566/5956119/e4e3828c-a777-11e4-8a53-f276d4dde3bf.png)

and the green doesn't show up at all.



Discussion:
Actually, this looks to be a bug with `io.imread`. The following gives the same results:

``` python
from skimage import io
import matplotlib.pyplot as plt

image = io.imread('ant.jpg')
plt.imshow(image)
plt.show()
```

@tonysyu is this true of master? Or just 0.10?

I'm running it on master. Using the image that @gvwilson shared, my normal image viewer shows the jet-like image, while the above code snippet shows a mostly white image.

A quick check suggests that the matplotlib backend works fine with this image, but the pil backend does not.

@tonysyu @gvwilson Well... That sucks. =P

maybe it's a PIL vs pillow issue. I don't have pillow installed right now so I can't check.

Current OSX wheels of Matplotlib and Pillow display an image like the initial image on this issue for me (round with blue background green / red interior). 

I'll take this one.

Just some notes: 
- `pyplot.imread` gives this: 
  ![figure_2](https://cloud.githubusercontent.com/assets/2096628/5983733/848d0f6a-a895-11e4-827f-f415efe4551e.png)
- `imread.imread` gives this:

![figure_1](https://cloud.githubusercontent.com/assets/2096628/5983691/1a9c4bca-a895-11e4-9f78-da1cb6e52a84.png)
- `imageio.imread` gives this:
  ![figure_3](https://cloud.githubusercontent.com/assets/2096628/5983793/0e113d56-a896-11e4-8721-a0fc9cdc2217.png)
- base image blown up:
  ![screenshot from 2015-01-30 15 41 16](https://cloud.githubusercontent.com/assets/2096628/5983853/755ab8e8-a896-11e4-8333-76898838523a.png)

cc/ @tacaswell

cc/ @almarklein 

I'd say `imageio` is the only one getting it right.

Nice work @almarklein!

it looks like mpl just exposes a slightly different interface to PIL/pillow.

Digikam is telling me that this jpeg in CMYK encoded.  If that is the case then I suspect that the internal conversion CMYK -> RGB is the source of the problems and this is an upstream/weird(?) image problem.

exif tool is a bit less sure:

```
tcaswell@eowyn:~$ exiftool so.jpeg 
ExifTool Version Number         : 9.46
File Name                       : so.jpeg
Directory                       : .
File Size                       : 13 kB
File Modification Date/Time     : 2015:01:30 17:37:11-05:00
File Access Date/Time           : 2015:01:30 17:37:27-05:00
File Inode Change Date/Time     : 2015:01:30 17:37:26-05:00
File Permissions                : rw-r-----
File Type                       : JPEG
MIME Type                       : image/jpeg
DCT Encode Version              : 100
APP14 Flags 0                   : (none)
APP14 Flags 1                   : (none)
Color Transform                 : Unknown (RGB or CMYK)
Image Width                     : 120
Image Height                    : 121
Encoding Process                : Baseline DCT, Huffman coding
Bits Per Sample                 : 8
Color Components                : 4
Image Size                      : 120x121

```

But the image created by `novice.Picture.from_size` should be OK, shouldn't it?

Right @gvwilson, there are two bugs here.

@gvwilson, I have a fix, I'd like to add a test for CMYK images.  Is that image copyrighted?


Resolving patch:
diff --git a/skimage/io/_plugins/pil_plugin.py b/skimage/io/_plugins/pil_plugin.py
--- a/skimage/io/_plugins/pil_plugin.py
+++ b/skimage/io/_plugins/pil_plugin.py
@@ -73,7 +73,7 @@ def pil_to_ndarray(im, dtype=None, img_num=None):
 
         frame = im
 
-        if not img_num is None and img_num != i:
+        if img_num is not None and img_num != i:
             im.getdata()[0]
             i += 1
             continue
@@ -93,6 +93,8 @@ def pil_to_ndarray(im, dtype=None, img_num=None):
         elif 'A' in im.mode:
             frame = im.convert('RGBA')
 
+        elif im.mode == 'CMYK':
+            frame = im.convert('RGB')
 
         if im.mode.startswith('I;16'):
             shape = im.size


Test patch:
diff --git a/skimage/io/tests/test_pil.py b/skimage/io/tests/test_pil.py
--- a/skimage/io/tests/test_pil.py
+++ b/skimage/io/tests/test_pil.py
@@ -6,18 +6,19 @@
 
 from tempfile import NamedTemporaryFile
 
-from skimage import data_dir
-from skimage.io import (imread, imsave, use_plugin, reset_plugins,
+from ... import data_dir
+from .. import (imread, imsave, use_plugin, reset_plugins,
                         Image as ioImage)
-from skimage._shared.testing import mono_check, color_check
-from skimage._shared._warnings import expected_warnings
+from ..._shared.testing import mono_check, color_check
+from ..._shared._warnings import expected_warnings
 
 from six import BytesIO
 
 from PIL import Image
-from skimage.io._plugins.pil_plugin import (
+from .._plugins.pil_plugin import (
     pil_to_ndarray, ndarray_to_pil, _palette_is_grayscale)
-
+from ...measure import structural_similarity as ssim
+from ...color import rgb2lab
 
 
 def setup():
@@ -183,6 +184,31 @@ def test_multi_page_gif():
     assert img2.shape == (280, 500, 3)
     assert_allclose(img[5], img2)
 
+
+def test_cmyk():
+    ref = imread(os.path.join(data_dir, 'color.png'))
+
+    img = Image.open(os.path.join(data_dir, 'color.png'))
+    img = img.convert('CMYK')
+
+    f = NamedTemporaryFile(suffix='.jpg')
+    fname = f.name
+    f.close()
+    img.save(fname)
+    img.close()
+
+    new = imread(fname)
+
+    ref_lab = rgb2lab(ref)
+    new_lab = rgb2lab(new)
+
+    for i in range(3):
+        newi = np.ascontiguousarray(new_lab[:, :, i])
+        refi = np.ascontiguousarray(ref_lab[:, :, i])
+        sim = ssim(refi, newi, dynamic_range=refi.max() - refi.min())
+        assert sim > 0.99
+
+
 class TestSaveTIF:
     def roundtrip(self, dtype, x):
         f = NamedTemporaryFile(suffix='.tif')
@@ -205,4 +231,4 @@ def test_imsave_roundtrip(self):
                 yield self.roundtrip, dtype, x
 
 if __name__ == "__main__":
-    run_module_suite()
+    run_module_suite()
\ No newline at end of file