Imaging¶

11/14/2023¶

print view

notebook

In [1]:
%%html
<script src="https://bits.csb.pitt.edu/preamble.js"></script>
In [3]:
# Digital images
from matplotlib import pyplot as plt
img = plt.imread('digitalImage.png')
plt.figure(figsize=(15,10))
plt.imshow(img)
plt.show()

Grayscale vs color image¶

In a grayscale image the pixel contains a single intensity quantized to a certain bit depth

In a color image a pixel is (usually) a triple (red,green,blue) of color values where each color intensity usually ranges from 0-255 (24-bit color).

In [54]:
%%html
<div id="imcol" style="width: 500px"></div>
<script>

    var divid = '#imcol';
	jQuery(divid).asker({
	    id: divid,
	    question: "Which contains the most information?",
        answers: ['Gray','Color'],
		extra: ['A grayscale image where values range from 0 to 4095', 'A color image where pixel values range from 0 to 255'],
        server: "https://bits.csb.pitt.edu/asker.js/example/asker.cgi",
		charter: chartmaker})
    
$(".jp-InputArea .o:contains(html)").closest('.jp-InputArea').hide();


</script>

A slightly irrelevant aside¶

Or, how to count with 16 fingers¶

It is very common for RGB color values to be represented in hexadecimal (e.g., HTML).

Hexadecimal number are usually indicated with a 0x or # prefix.

In hexadecimal, each digit can take one of 16 values (as opposed to 10). This means that each color can be represented with two digits (16*16 = 256)

https://www.youtube.com/watch?v=ffB0Je-xjKg

HexDec
A10
B11
C12
D13
E14
F15
In [3]:
%%html
<div id="hex1" style="width: 500px"></div>
<script>

    var divid = '#hex1';
	jQuery(divid).asker({
	    id: divid,
	    question: "What is the decimal value of 0x1F?",
		answers: ['11','16','17','31','32'],
        server: "https://bits.csb.pitt.edu/asker.js/example/asker.cgi",
		charter: chartmaker})
    
$(".jp-InputArea .o:contains(html)").closest('.jp-InputArea').hide();


</script>
In [4]:
%%html
<div id="hex2" style="width: 500px"></div>
<script>

    var divid = '#hex2';
	jQuery(divid).asker({
	    id: divid,
	    question: "What is the decimal value of 0xfe?",
		answers: ['15','32','127','254','255'],
        server: "https://bits.csb.pitt.edu/asker.js/example/asker.cgi",
		charter: chartmaker})
    
$(".jp-InputArea .o:contains(html)").closest('.jp-InputArea').hide();


</script>
In [5]:
%%html
<div id="hex3" style="width: 500px"></div>
<script>

    var divid = '#hex3';
	jQuery(divid).asker({
	    id: divid,
	    question: "What color is #ff00ff?",
		answers: ['green','cyan','yellow','magenta','I failed art'],
        server: "https://bits.csb.pitt.edu/asker.js/example/asker.cgi",
		charter: chartmaker})
    
$(".jp-InputArea .o:contains(html)").closest('.jp-InputArea').hide();


</script>

Answers¶

In [6]:
print(0x1f, 0xfe)
31 254

<div style="color: #ff00ff">Hello</div>

Hello

PIL - The Python Image Library¶

documentation

The Python Imaging Library provides the ability to read, write an manipulate images in all the common formats. Some key modules:

  • PIL.Image - primary Image object
  • PIL.ImageChops - channel operations, for blending two images
  • PIL.ImageEnhance - enhance your photos (sharpness, contrast, ...)
  • PIL.ImageFilter - filters (blur, smooth, sharpen, ...)
  • PIL.ImageOps - assorted operations (resizing, equalize, autocontrast, ...)
  • PIL.ImageStat - statistics on image (min, max, ...)

History¶

Despite being a popular package, PIL development stopped in 2011 with no new releases since 2009.

Pillow is a fork of PIL that is fully backwards compatible and updated (and is what you are actually using rather than the original PIL).

https://python-pillow.org

Setup...¶

In [3]:
!wget http://bits.csb.pitt.edu/images/image1.tif
--2023-11-11 17:51:01--  http://bits.csb.pitt.edu/images/image1.tif
Resolving bits.csb.pitt.edu (bits.csb.pitt.edu)... 136.142.4.139
Connecting to bits.csb.pitt.edu (bits.csb.pitt.edu)|136.142.4.139|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 921814 (900K) [image/tiff]
Saving to: ‘image1.tif’

image1.tif          100%[===================>] 900.21K  1.11MB/s    in 0.8s    

2023-11-11 17:51:02 (1.11 MB/s) - ‘image1.tif’ saved [921814/921814]

In [11]:
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
%matplotlib inline
In [34]:
from PIL import Image
im = Image.open('image1.tif')
im
Out[34]:

Actin HSP27 DAPI

Image Methods¶

PIL refers to the different color channels as bands.

In [10]:
im.getbands()
Out[10]:
('R', 'G', 'B')

You can split a color image into it's separate bands.

In [11]:
(r,g,b) = im.split()
r
Out[11]:

Green¶

In [12]:
g
Out[12]:

Blue¶

In [13]:
b
Out[13]:

Image analysis in this example should done per channel ... Why?

In [6]:
im2 = Image.open('Retina.jpg')
im2
Out[6]:
In [7]:
im2.getbands()
Out[7]:
('R', 'G', 'B')
In [8]:
r2,g2,b2 = im2.split()
In [9]:
fig, ax = plt.subplots(1,3, figsize=(15,45))
ax[0].imshow(r2,cmap='gray');
ax[1].imshow(g2,cmap='gray')
ax[2].imshow(b2,cmap='gray')
Out[9]:
<matplotlib.image.AxesImage at 0x1cc6d3d6e80>

Converting Image Types¶

We can convert to grayscale ('L' - luminance)

In [45]:
grey = im.convert('L')
grey
Out[45]:

Converting Color Spaces¶

We can convert RGB to HSV space

In [46]:
tmp = im.convert(mode='HSV')
[h,s,v] = tmp.split();
fig, ax = plt.subplots(1,3, figsize=(15,45))
ax[0].imshow(h,cmap='gray');
ax[1].imshow(s,cmap='gray')
ax[2].imshow(v,cmap='gray')
Out[46]:
<matplotlib.image.AxesImage at 0x1cc6c8573d0>

Getting Pixels¶

In [27]:
import numpy as np
In [55]:
im.getpixel((320,240))
Out[55]:
(159, 3, 18)

Setting Pixels¶

To get/set pixels directly, first load the pixel map of an image.

In [17]:
cp = im.copy()
pixels = cp.load()

for i in range(cp.size[0]):
    for j in range(120,130):
        pixels[i,j] = (255,0,255)

cp
Out[17]:

Getting all the pixels¶

Can convert to numpy array - first dimension (rows) will be y-axis

In [18]:
np.array(im).shape
Out[18]:
(480, 640, 3)
In [19]:
np.array(im)[240,320]
Out[19]:
array([159,   3,  18], dtype=uint8)

Can get all the pixels in a flat list

In [20]:
list(im.getdata())
Out[20]:
[(243, 3, 28),
 (238, 3, 27),
 (242, 3, 26),
 (239, 3, 27),
 (226, 3, 27),
 (220, 3, 26),
 (195, 3, 27),
 (179, 3, 26),
 (171, 3, 27),
 (163, 4, 28),
 (163, 3, 27),
 (148, 3, 28),
 (145, 4, 27),
 (146, 3, 27),
 (137, 4, 27),
 (136, 4, 27),
 (136, 3, 28),
 (124, 4, 28),
 (125, 4, 28),
 (121, 3, 27),
 (116, 4, 28),
 (113, 4, 26),
 (107, 3, 28),
 (107, 4, 27),
 (103, 3, 29),
 (96, 3, 28),
 (93, 3, 30),
 (95, 3, 27),
 (87, 3, 28),
 (94, 3, 28),
 (91, 3, 27),
 (94, 3, 28),
 (87, 3, 27),
 (93, 3, 28),
 (82, 3, 27),
 (79, 3, 28),
 (78, 4, 27),
 (84, 4, 28),
 (79, 4, 29),
 (85, 4, 28),
 (82, 4, 29),
 (83, 3, 29),
 (81, 3, 30),
 (70, 4, 30),
 (79, 4, 28),
 (78, 4, 29),
 (77, 4, 28),
 (81, 4, 29),
 (80, 4, 30),
 (72, 3, 30),
 (76, 4, 30),
 (77, 4, 30),
 (84, 4, 29),
 (84, 4, 31),
 (80, 4, 30),
 (87, 4, 33),
 (88, 4, 31),
 (89, 4, 34),
 (89, 4, 32),
 (96, 4, 33),
 (89, 4, 32),
 (91, 4, 33),
 (92, 4, 32),
 (93, 4, 31),
 (96, 4, 31),
 (96, 4, 30),
 (103, 4, 31),
 (103, 4, 31),
 (93, 4, 31),
 (106, 4, 30),
 (100, 4, 31),
 (105, 4, 31),
 (108, 4, 31),
 (106, 4, 32),
 (110, 4, 32),
 (101, 4, 31),
 (105, 3, 32),
 (102, 4, 32),
 (107, 4, 33),
 (114, 3, 34),
 (111, 4, 35),
 (106, 4, 36),
 (104, 4, 35),
 (106, 4, 35),
 (112, 4, 37),
 (120, 4, 40),
 (107, 4, 39),
 (108, 4, 41),
 (110, 4, 43),
 (107, 4, 46),
 (102, 3, 47),
 (108, 4, 47),
 (109, 4, 48),
 (106, 3, 51),
 (106, 4, 49),
 (103, 4, 53),
 (99, 4, 53),
 (102, 4, 55),
 (99, 4, 58),
 (109, 4, 58),
 (104, 4, 60),
 (97, 4, 59),
 (101, 5, 59),
 (91, 4, 60),
 (96, 3, 58),
 (92, 4, 60),
 (97, 4, 62),
 (96, 4, 65),
 (92, 4, 66),
 (95, 4, 69),
 (92, 4, 70),
 (91, 4, 69),
 (91, 3, 68),
 (93, 3, 66),
 (96, 4, 66),
 (92, 3, 65),
 (98, 3, 64),
 (86, 3, 62),
 (88, 4, 64),
 (95, 3, 64),
 (97, 3, 63),
 (81, 3, 64),
 (82, 4, 64),
 (88, 3, 63),
 (84, 3, 65),
 (75, 3, 66),
 (79, 4, 69),
 (84, 3, 68),
 (86, 3, 68),
 (83, 3, 66),
 (84, 3, 65),
 (81, 3, 64),
 (81, 3, 65),
 (87, 3, 66),
 (78, 3, 64),
 (86, 3, 64),
 (83, 3, 65),
 (82, 3, 62),
 (82, 3, 64),
 (83, 3, 64),
 (90, 3, 65),
 (82, 3, 64),
 (88, 3, 62),
 (83, 3, 64),
 (83, 4, 64),
 (91, 3, 62),
 (87, 3, 58),
 (81, 3, 58),
 (87, 3, 57),
 (80, 3, 56),
 (88, 3, 52),
 (84, 3, 49),
 (86, 3, 47),
 (86, 3, 48),
 (81, 3, 44),
 (81, 3, 41),
 (80, 2, 40),
 (88, 3, 39),
 (87, 3, 38),
 (82, 3, 38),
 (89, 2, 36),
 (83, 3, 37),
 (83, 3, 35),
 (88, 2, 34),
 (84, 3, 34),
 (83, 3, 33),
 (83, 3, 33),
 (84, 2, 33),
 (89, 3, 33),
 (85, 3, 32),
 (84, 3, 31),
 (88, 3, 31),
 (86, 3, 31),
 (89, 3, 32),
 (88, 2, 31),
 (90, 3, 31),
 (91, 3, 31),
 (88, 3, 31),
 (90, 2, 30),
 (96, 3, 31),
 (96, 2, 32),
 (103, 3, 30),
 (106, 3, 28),
 (106, 2, 28),
 (113, 2, 29),
 (110, 2, 29),
 (104, 2, 30),
 (110, 2, 29),
 (101, 2, 29),
 (103, 2, 29),
 (107, 2, 28),
 (107, 3, 29),
 (108, 3, 28),
 (102, 2, 28),
 (107, 2, 28),
 (104, 2, 28),
 (105, 2, 29),
 (114, 2, 29),
 (105, 3, 29),
 (109, 2, 29),
 (109, 2, 29),
 (111, 2, 30),
 (110, 2, 29),
 (106, 2, 29),
 (119, 2, 31),
 (117, 2, 30),
 (112, 2, 30),
 (114, 2, 30),
 (114, 2, 28),
 (124, 2, 30),
 (124, 2, 30),
 (119, 2, 30),
 (124, 2, 30),
 (117, 2, 32),
 (118, 2, 29),
 (126, 2, 30),
 (124, 2, 28),
 (128, 2, 31),
 (128, 3, 30),
 (130, 2, 31),
 (135, 2, 30),
 (124, 2, 30),
 (134, 2, 30),
 (132, 2, 30),
 (138, 2, 31),
 (146, 2, 31),
 (149, 2, 31),
 (141, 2, 32),
 (139, 2, 30),
 (148, 2, 32),
 (146, 2, 32),
 (151, 2, 32),
 (151, 2, 32),
 (154, 2, 34),
 (167, 2, 35),
 (158, 2, 33),
 (162, 2, 34),
 (169, 2, 35),
 (175, 2, 34),
 (179, 2, 36),
 (186, 2, 36),
 (177, 2, 36),
 (186, 1, 36),
 (186, 2, 37),
 (196, 1, 38),
 (192, 1, 38),
 (194, 2, 39),
 (195, 1, 38),
 (204, 2, 39),
 (210, 2, 40),
 (205, 1, 38),
 (205, 2, 40),
 (215, 2, 39),
 (200, 1, 42),
 (205, 1, 41),
 (212, 1, 42),
 (221, 1, 43),
 (219, 1, 42),
 (216, 1, 45),
 (215, 1, 45),
 (203, 1, 47),
 (213, 2, 46),
 (191, 1, 47),
 (206, 2, 46),
 (207, 2, 46),
 (191, 1, 48),
 (180, 1, 50),
 (162, 1, 49),
 (165, 1, 52),
 (149, 1, 52),
 (154, 1, 54),
 (142, 1, 54),
 (143, 1, 55),
 (139, 1, 56),
 (133, 1, 58),
 (135, 1, 59),
 (136, 1, 58),
 (131, 1, 60),
 (136, 1, 61),
 (136, 1, 60),
 (136, 2, 62),
 (141, 1, 62),
 (135, 1, 62),
 (137, 2, 66),
 (132, 2, 68),
 (140, 1, 68),
 (146, 1, 69),
 (153, 2, 71),
 (138, 1, 73),
 (134, 1, 72),
 (139, 1, 74),
 (138, 1, 76),
 (140, 1, 76),
 (127, 2, 80),
 (136, 1, 82),
 (139, 1, 80),
 (129, 1, 83),
 (136, 1, 83),
 (137, 1, 83),
 (133, 2, 82),
 (129, 1, 86),
 (139, 1, 84),
 (131, 1, 83),
 (138, 1, 85),
 (139, 2, 83),
 (140, 1, 84),
 (150, 1, 87),
 (146, 1, 87),
 (147, 1, 85),
 (142, 1, 86),
 (144, 1, 85),
 (146, 1, 84),
 (151, 1, 85),
 (151, 1, 87),
 (146, 1, 85),
 (141, 1, 85),
 (141, 2, 84),
 (156, 1, 84),
 (157, 1, 87),
 (153, 1, 88),
 (153, 1, 92),
 (151, 1, 96),
 (147, 1, 98),
 (151, 1, 96),
 (154, 1, 91),
 (150, 1, 87),
 (158, 1, 83),
 (151, 1, 80),
 (154, 1, 80),
 (166, 1, 78),
 (174, 1, 76),
 (175, 1, 72),
 (179, 1, 70),
 (179, 1, 68),
 (183, 1, 67),
 (182, 2, 66),
 (180, 1, 63),
 (183, 1, 62),
 (180, 1, 59),
 (184, 1, 58),
 (178, 1, 55),
 (187, 2, 55),
 (187, 1, 52),
 (176, 1, 52),
 (156, 1, 50),
 (147, 1, 51),
 (155, 1, 50),
 (138, 1, 49),
 (139, 2, 49),
 (132, 1, 47),
 (126, 1, 46),
 (116, 1, 46),
 (125, 1, 44),
 (123, 1, 45),
 (116, 1, 45),
 (118, 2, 43),
 (106, 1, 42),
 (111, 1, 43),
 (112, 2, 42),
 (99, 1, 42),
 (99, 1, 41),
 (100, 1, 39),
 (100, 2, 38),
 (99, 1, 38),
 (98, 1, 37),
 (96, 1, 36),
 (100, 1, 34),
 (98, 1, 35),
 (90, 2, 34),
 (92, 1, 33),
 (95, 1, 33),
 (95, 1, 33),
 (97, 1, 31),
 (89, 1, 30),
 (89, 1, 31),
 (102, 1, 30),
 (97, 2, 29),
 (94, 1, 29),
 (90, 1, 27),
 (91, 1, 27),
 (90, 1, 27),
 (88, 1, 25),
 (94, 1, 26),
 (96, 1, 25),
 (90, 1, 26),
 (98, 1, 25),
 (98, 1, 24),
 (103, 1, 22),
 (108, 1, 22),
 (112, 1, 22),
 (123, 1, 21),
 (125, 1, 21),
 (107, 1, 21),
 (96, 1, 20),
 (92, 1, 21),
 (83, 2, 19),
 (83, 1, 19),
 (80, 1, 20),
 (75, 1, 19),
 (75, 1, 19),
 (72, 1, 18),
 (73, 1, 19),
 (68, 1, 18),
 (70, 1, 18),
 (64, 1, 18),
 (66, 1, 18),
 (65, 1, 17),
 (57, 1, 17),
 (55, 1, 16),
 (63, 1, 17),
 (58, 1, 17),
 (58, 1, 17),
 (61, 1, 16),
 (58, 1, 16),
 (56, 1, 16),
 (64, 1, 17),
 (68, 1, 17),
 (64, 1, 16),
 (67, 1, 16),
 (58, 1, 16),
 (64, 1, 15),
 (65, 1, 15),
 (56, 1, 15),
 (61, 1, 16),
 (61, 1, 16),
 (61, 1, 15),
 (56, 1, 16),
 (55, 1, 15),
 (48, 1, 16),
 (46, 1, 15),
 (45, 1, 15),
 (49, 1, 15),
 (42, 1, 15),
 (42, 1, 15),
 (47, 1, 14),
 (39, 1, 14),
 (40, 1, 14),
 (44, 1, 14),
 (42, 1, 15),
 (43, 1, 15),
 (45, 1, 14),
 (44, 1, 14),
 (52, 1, 15),
 (40, 1, 14),
 (40, 1, 14),
 (33, 1, 14),
 (35, 1, 14),
 (37, 1, 14),
 (40, 1, 16),
 (42, 1, 15),
 (45, 1, 14),
 (44, 1, 14),
 (49, 1, 15),
 (55, 1, 15),
 (53, 1, 15),
 (49, 1, 15),
 (49, 1, 14),
 (56, 1, 15),
 (49, 1, 15),
 (49, 1, 16),
 (52, 1, 15),
 (58, 1, 15),
 (48, 1, 14),
 (56, 1, 15),
 (52, 2, 15),
 (56, 1, 15),
 (59, 2, 14),
 (59, 1, 15),
 (59, 1, 15),
 (54, 1, 14),
 (48, 1, 14),
 (44, 1, 14),
 (47, 1, 14),
 (48, 1, 14),
 (47, 1, 13),
 (42, 1, 14),
 (41, 1, 13),
 (42, 1, 12),
 (43, 1, 13),
 (45, 1, 13),
 (41, 1, 13),
 (53, 1, 13),
 (52, 1, 13),
 (49, 1, 13),
 (45, 1, 13),
 (35, 1, 13),
 (28, 1, 12),
 (32, 1, 12),
 (30, 1, 12),
 (30, 1, 12),
 (32, 1, 12),
 (27, 1, 12),
 (23, 1, 12),
 (25, 1, 12),
 (23, 1, 12),
 (23, 1, 12),
 (23, 1, 12),
 (21, 1, 12),
 (25, 1, 12),
 (21, 1, 11),
 (19, 1, 12),
 (24, 1, 12),
 (20, 1, 12),
 (21, 1, 12),
 (20, 1, 12),
 (19, 1, 12),
 (21, 1, 12),
 (19, 1, 11),
 (17, 1, 11),
 (21, 1, 12),
 (14, 1, 12),
 (15, 1, 12),
 (17, 1, 12),
 (14, 1, 12),
 (19, 1, 12),
 (12, 1, 12),
 (16, 1, 12),
 (16, 1, 12),
 (15, 1, 12),
 (11, 1, 11),
 (14, 1, 12),
 (12, 1, 12),
 (15, 1, 11),
 (11, 2, 11),
 (11, 1, 12),
 (12, 1, 11),
 (11, 1, 12),
 (12, 1, 12),
 (12, 1, 12),
 (12, 1, 12),
 (13, 1, 12),
 (15, 1, 11),
 (8, 2, 12),
 (9, 1, 11),
 (10, 1, 12),
 (10, 1, 12),
 (7, 1, 11),
 (12, 1, 12),
 (12, 1, 12),
 (10, 1, 12),
 (11, 1, 11),
 (11, 1, 11),
 (10, 1, 12),
 (10, 1, 11),
 (12, 1, 11),
 (9, 1, 11),
 (11, 1, 12),
 (12, 1, 12),
 (9, 1, 11),
 (11, 1, 12),
 (10, 1, 12),
 (13, 1, 12),
 (12, 1, 11),
 (13, 1, 11),
 (13, 1, 11),
 (14, 1, 11),
 (11, 1, 11),
 (12, 1, 10),
 (16, 1, 11),
 (14, 1, 12),
 (16, 1, 12),
 (18, 1, 11),
 (18, 1, 11),
 (19, 2, 11),
 (25, 1, 11),
 (26, 1, 12),
 (22, 1, 12),
 (29, 1, 11),
 (34, 2, 12),
 (38, 2, 11),
 (38, 1, 11),
 (50, 1, 11),
 (55, 2, 11),
 (62, 2, 11),
 (65, 2, 11),
 (78, 3, 12),
 (84, 2, 11),
 (90, 2, 11),
 (77, 2, 11),
 (66, 2, 11),
 (56, 2, 12),
 (50, 2, 11),
 (42, 2, 11),
 (39, 2, 12),
 (41, 2, 12),
 (38, 3, 11),
 (41, 2, 11),
 (32, 2, 12),
 (38, 3, 10),
 (39, 2, 11),
 (37, 2, 11),
 (35, 2, 11),
 (34, 3, 12),
 (37, 3, 12),
 (33, 3, 12),
 (34, 3, 12),
 (37, 2, 12),
 (41, 4, 12),
 (32, 3, 12),
 (37, 3, 12),
 (37, 3, 12),
 (28, 4, 12),
 (25, 4, 12),
 (23, 4, 12),
 (29, 4, 12),
 (27, 4, 11),
 (32, 4, 12),
 (30, 5, 11),
 (25, 5, 12),
 (26, 5, 12),
 (22, 6, 12),
 (27, 5, 12),
 (24, 5, 13),
 (24, 5, 12),
 (24, 5, 12),
 (19, 6, 14),
 (24, 6, 13),
 (20, 6, 13),
 (18, 6, 13),
 (24, 7, 13),
 (20, 7, 14),
 (22, 7, 13),
 (17, 6, 13),
 (16, 7, 13),
 (19, 6, 14),
 (23, 7, 14),
 (18, 8, 14),
 (27, 8, 14),
 (21, 7, 13),
 (20, 7, 14),
 (22, 7, 14),
 (23, 7, 14),
 (21, 7, 14),
 (22, 6, 14),
 (22, 6, 14),
 (18, 6, 14),
 (18, 6, 15),
 (20, 6, 14),
 (19, 6, 14),
 (18, 6, 14),
 (248, 3, 26),
 (249, 3, 27),
 (246, 3, 27),
 (237, 3, 27),
 (221, 3, 27),
 (198, 3, 26),
 (180, 4, 26),
 (167, 4, 27),
 (158, 4, 28),
 (160, 4, 26),
 (151, 3, 27),
 (147, 3, 28),
 (147, 3, 28),
 (136, 4, 28),
 (140, 4, 28),
 (141, 3, 28),
 (136, 3, 28),
 (127, 3, 28),
 (122, 3, 29),
 (120, 3, 27),
 (115, 3, 29),
 (114, 3, 27),
 (112, 3, 29),
 (107, 3, 28),
 (102, 3, 29),
 (92, 4, 28),
 (92, 4, 27),
 (94, 3, 28),
 (91, 3, 28),
 (98, 4, 28),
 (85, 3, 27),
 (88, 3, 29),
 (85, 3, 27),
 (87, 4, 28),
 (92, 3, 26),
 (84, 4, 27),
 (92, 4, 27),
 (75, 3, 29),
 (81, 4, 29),
 (84, 4, 30),
 (78, 4, 28),
 (78, 4, 30),
 (77, 4, 30),
 (85, 4, 29),
 (75, 4, 30),
 (77, 4, 30),
 (79, 4, 29),
 (75, 4, 29),
 (74, 4, 30),
 (86, 4, 30),
 (76, 4, 29),
 (83, 4, 30),
 (83, 4, 30),
 (83, 4, 30),
 (83, 5, 31),
 (83, 4, 33),
 (90, 4, 33),
 (89, 4, 35),
 (82, 4, 34),
 (91, 4, 34),
 (90, 4, 33),
 (97, 4, 31),
 (93, 4, 33),
 (92, 5, 30),
 (94, 4, 31),
 (92, 4, 31),
 (102, 4, 31),
 (100, 5, 31),
 (99, 4, 29),
 (104, 4, 31),
 (106, 4, 32),
 (99, 4, 32),
 (110, 4, 31),
 (105, 4, 31),
 (109, 4, 32),
 (112, 4, 32),
 (105, 4, 32),
 (117, 4, 33),
 (111, 4, 33),
 (107, 4, 33),
 (114, 5, 35),
 (119, 4, 36),
 (106, 5, 37),
 (108, 5, 38),
 (118, 4, 38),
 (111, 4, 39),
 (112, 4, 42),
 (108, 5, 42),
 (110, 4, 44),
 (105, 4, 46),
 (106, 4, 47),
 (107, 4, 47),
 (105, 4, 48),
 (107, 4, 51),
 (103, 4, 51),
 (101, 4, 52),
 (108, 4, 53),
 (103, 4, 56),
 (105, 4, 60),
 (100, 4, 62),
 (98, 4, 62),
 (97, 4, 64),
 (98, 4, 63),
 (95, 4, 62),
 (100, 4, 60),
 (96, 4, 61),
 (91, 4, 64),
 (94, 4, 68),
 (94, 4, 71),
 (97, 4, 72),
 (89, 4, 74),
 (91, 4, 76),
 (89, 4, 73),
 (91, 3, 69),
 (81, 3, 69),
 (90, 3, 70),
 (89, 4, 67),
 (91, 4, 68),
 (91, 4, 67),
 (81, 4, 66),
 (80, 3, 65),
 (87, 4, 66),
 (87, 3, 66),
 (88, 3, 65),
 (86, 4, 63),
 (86, 3, 67),
 (85, 3, 69),
 (82, 3, 70),
 (84, 4, 71),
 (88, 4, 69),
 (75, 3, 67),
 (83, 3, 65),
 (80, 4, 65),
 (77, 3, 65),
 (87, 3, 64),
 (87, 3, 65),
 (87, 4, 64),
 (82, 3, 64),
 (81, 3, 64),
 (82, 3, 65),
 (83, 3, 67),
 (83, 3, 66),
 (92, 3, 67),
 (82, 3, 68),
 (84, 3, 62),
 (79, 3, 61),
 (88, 2, 61),
 (87, 3, 60),
 (83, 3, 57),
 (86, 3, 56),
 (89, 3, 53),
 (86, 3, 52),
 (83, 3, 51),
 (83, 3, 49),
 (79, 3, 44),
 (92, 3, 44),
 (87, 3, 40),
 (81, 3, 37),
 (88, 3, 38),
 (83, 3, 37),
 (85, 3, 36),
 (90, 4, 36),
 (88, 3, 36),
 (87, 3, 34),
 (82, 3, 35),
 (90, 2, 35),
 (89, 2, 33),
 (81, 3, 32),
 (81, 3, 33),
 (90, 3, 32),
 (89, 2, 32),
 (90, 2, 32),
 (88, 2, 33),
 (86, 3, 32),
 (93, 3, 32),
 (88, 2, 30),
 (89, 3, 31),
 (96, 3, 30),
 (91, 3, 30),
 (95, 3, 30),
 (103, 2, 30),
 (102, 2, 29),
 (109, 2, 30),
 (109, 3, 28),
 (109, 3, 28),
 (115, 3, 29),
 (112, 3, 27),
 (107, 3, 29),
 (106, 2, 29),
 (101, 3, 28),
 (109, 2, 29),
 (103, 3, 28),
 (100, 2, 28),
 (113, 2, 29),
 (111, 2, 28),
 (104, 2, 29),
 (115, 2, 29),
 (103, 2, 29),
 (107, 2, 29),
 (111, 2, 29),
 (108, 2, 30),
 (113, 2, 29),
 (115, 2, 30),
 (118, 2, 30),
 (115, 2, 30),
 (113, 2, 30),
 (122, 2, 31),
 (120, 2, 30),
 (113, 2, 30),
 (122, 2, 30),
 (123, 2, 32),
 (123, 2, 29),
 (124, 2, 29),
 (125, 2, 30),
 (121, 2, 28),
 (123, 2, 30),
 (125, 2, 29),
 (128, 2, 30),
 (137, 2, 30),
 (130, 2, 30),
 (130, 3, 29),
 (127, 2, 31),
 (129, 2, 31),
 (137, 2, 30),
 (143, 2, 30),
 (141, 2, 31),
 (138, 2, 31),
 (140, 2, 31),
 (140, 2, 31),
 (147, 2, 31),
 (149, 2, 33),
 (149, 2, 32),
 (153, 2, 32),
 (153, 2, 34),
 (159, 2, 33),
 (160, 2, 34),
 (170, 2, 35),
 (164, 2, 34),
 (181, 2, 35),
 (179, 2, 34),
 (177, 1, 35),
 (185, 2, 36),
 (184, 2, 37),
 (186, 2, 36),
 (195, 2, 36),
 (198, 2, 37),
 (198, 1, 37),
 (200, 2, 37),
 (204, 1, 39),
 (210, 1, 39),
 (210, 2, 40),
 (213, 1, 39),
 (200, 2, 41),
 (208, 2, 44),
 (220, 2, 42),
 (224, 2, 43),
 (212, 2, 44),
 (205, 1, 43),
 (211, 2, 43),
 (210, 2, 44),
 (209, 1, 45),
 (212, 1, 45),
 (214, 1, 47),
 (216, 1, 46),
 (206, 1, 46),
 (204, 2, 47),
 (192, 2, 49),
 (183, 2, 48),
 (174, 1, 51),
 (154, 1, 50),
 (156, 2, 54),
 (147, 1, 53),
 (143, 1, 52),
 (139, 1, 55),
 (139, 1, 56),
 (145, 1, 56),
 (135, 1, 58),
 (150, 1, 58),
 (136, 1, 57),
 (134, 2, 60),
 (141, 2, 62),
 (143, 1, 62),
 (143, 2, 64),
 (145, 1, 67),
 (145, 1, 66),
 (149, 1, 68),
 (149, 2, 66),
 (148, 1, 69),
 (141, 1, 69),
 (135, 1, 69),
 (139, 1, 73),
 (138, 1, 73),
 (143, 1, 74),
 (136, 2, 78),
 (150, 2, 76),
 (145, 1, 80),
 (137, 1, 79),
 (145, 1, 82),
 (135, 1, 80),
 (136, 1, 82),
 (139, 2, 83),
 (143, 1, 83),
 (144, 1, 80),
 (140, 2, 81),
 (151, 2, 84),
 (146, 1, 81),
 (147, 1, 82),
 (148, 1, 84),
 (154, 1, 82),
 (144, 1, 82),
 (152, 1, 83),
 (150, 2, 83),
 (154, 2, 83),
 (158, 1, 83),
 (158, 1, 82),
 (153, 1, 83),
 (152, 2, 85),
 (163, 1, 87),
 (160, 1, 87),
 (159, 1, 89),
 (162, 1, 90),
 (156, 1, 94),
 (158, 1, 96),
 (158, 1, 92),
 (166, 1, 88),
 (165, 1, 84),
 (168, 1, 79),
 (160, 1, 77),
 (168, 1, 78),
 (161, 1, 75),
 (176, 1, 74),
 (160, 1, 70),
 (177, 1, 67),
 (170, 1, 65),
 (176, 1, 63),
 (184, 1, 62),
 (172, 1, 60),
 (187, 1, 60),
 (189, 1, 59),
 (181, 1, 56),
 (187, 1, 54),
 (190, 1, 52),
 (184, 1, 51),
 (166, 1, 52),
 (161, 1, 53),
 (147, 1, 50),
 (138, 1, 48),
 (140, 1, 48),
 (134, 1, 48),
 (127, 1, 48),
 (129, 1, 48),
 (118, 1, 46),
 (129, 1, 43),
 (121, 1, 43),
 (107, 1, 42),
 (109, 1, 42),
 (110, 1, 42),
 (102, 1, 43),
 (103, 1, 40),
 (103, 1, 40),
 ...]
In [21]:
%%html
<div id="immax" style="width: 500px"></div>
<script>

    var divid = '#immax';
	jQuery(divid).asker({
	    id: divid,
	    question: "What is the maximum pixel value of the blue channel (band) for image1?",
		answers: ['127','192','223','255','256'],
        server: "https://bits.csb.pitt.edu/asker.js/example/asker.cgi",
		charter: chartmaker})
    
$(".jp-InputArea .o:contains(html)").closest('.jp-InputArea').hide();


</script>

Ways to answer¶

In [22]:
max(b.getdata())
Out[22]:
192
In [23]:
np.array(b).max()
Out[23]:
192
In [24]:
from PIL import ImageStat
stat = ImageStat.Stat(b)
stat.extrema
Out[24]:
[(6, 192)]
In [25]:
%%html
<div id="imcnt" style="width: 500px"></div>
<script>
    var divid = '#imcnt';
	jQuery(divid).asker({
	    id: divid,
	    question: "How many pixels of image1 have a red value of 255?",
		answers: ['0','105','1206','5178','65334'],
        server: "https://bits.csb.pitt.edu/asker.js/example/asker.cgi",
		charter: chartmaker})
    
$(".jp-InputArea .o:contains(html)").closest('.jp-InputArea').hide();


</script>

Histograms¶

In [26]:
bins=np.linspace(0,255,25)
plt.hist(r.getdata(),alpha=0.2,color='#ff0000',bins=bins)
plt.hist(g.getdata(),alpha=0.2,color='#00ff00',bins=bins)
plt.hist(b.getdata(),alpha=0.2,color='#0000ff',bins=bins)
plt.show()

More Histograms¶

In [27]:
plt.plot(r.histogram(),'r')
plt.plot(g.histogram(),'g')
plt.plot(b.histogram(),'b')
plt.ylim(ymax=24000)
Out[27]:
(-6296.6, 24000.0)

What does the red peak at 255 mean?

Equalization¶

Equalization attempts to normalizes the image histogram to create a uniform distribution of grayscale values. This makes it easier to see differences, but distorts the meaning of the intensities (the transformation is non-linear).

In [28]:
from PIL import ImageOps
beq = ImageOps.equalize(b)
f = plt.figure(figsize=(12,6)); f.add_subplot(1, 2, 1)
plt.imshow(np.array(b),cmap = cm.Greys_r); f.add_subplot(1, 2, 2)
plt.imshow(np.array(beq),cmap = cm.Greys_r); 

Equalization¶

In [29]:
plt.plot(b.histogram(),'r')
plt.plot(beq.histogram(),'k')
Out[29]:
[<matplotlib.lines.Line2D at 0x7f7d3dbf3280>]

Autocontrast¶

Maximize (normalize) image contrast. This function calculates a histogram of the input image, removes a cutoff percent of the lightest and darkest pixels from the histogram, and remaps the image so that the darkest remaining pixel becomes black (0), and the lightest becomes white (255).

In [30]:
bcon = ImageOps.autocontrast(b,0.5)
f = plt.figure(figsize=(12,6)); f.add_subplot(1, 2, 1)
plt.imshow(np.array(b),cmap = cm.Greys_r); f.add_subplot(1, 2, 2)
plt.imshow(np.array(bcon),cmap = cm.Greys_r);

Autocontrast¶

In [31]:
plt.plot(b.histogram(),'r')
plt.plot(bcon.histogram(),'k');

Thresholding¶

The point function can be used to apply a function to every pixel in the image and return the transformed image. This makes it easy to threshold images into a mask.

In [32]:
bthresh = beq.point(lambda x: x if x > 225 else 0)
f = plt.figure(figsize=(12,6)); f.add_subplot(1, 2, 1)
plt.imshow(np.array(beq),cmap = cm.Greys_r); f.add_subplot(1, 2, 2)
plt.imshow(np.array(bthresh),cmap = cm.Greys_r) ;

Looking at the thresholded image, any thoughts on how to count the number of cells?

Project¶

  • Get the other three images from http://bits.csb.pitt.edu/images
  • How much green is there in image1 (sum of values)?
  • How much green is there that is co-located with blue > 40? As a percentage? For each image?
  • What if we change the cutoff (40)?
  • Plot the percentage of green co-located with blue for different values of the blue cutoff for each image.