Theorys of colour vision ppt for 4th year student for ophthalmology class
mkdir -p /tmp/workspace/colour-vision-ppt && ls /tmp/workspace/
~/colour-vision-ppt/build_pptx.py
from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.util import Inches, Pt
import json, subprocess, base64
from io import BytesIO
# ── Colour palette ────────────────────────────────────────────────────────────
NAVY = RGBColor(0x0A, 0x1F, 0x44) # slide background / header bar
TEAL = RGBColor(0x00, 0x8B, 0x8B) # accent / sub-headings
GOLD = RGBColor(0xF0, 0xA5, 0x00) # highlights
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
LIGHT_GREY = RGBColor(0xF5, 0xF5, 0xF5)
DARK_GREY = RGBColor(0x33, 0x33, 0x33)
RED_C = RGBColor(0xCC, 0x33, 0x33)
GREEN_C = RGBColor(0x33, 0x88, 0x44)
BLUE_C = RGBColor(0x22, 0x55, 0xCC)
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
blank = prs.slide_layouts[6] # fully blank layout
# ── Helper functions ──────────────────────────────────────────────────────────
def add_rect(slide, x, y, w, h, fill_color, alpha=None):
shape = slide.shapes.add_shape(
1, # MSO_SHAPE_TYPE.RECTANGLE
Inches(x), Inches(y), Inches(w), Inches(h)
)
shape.line.fill.background() # no border
shape.fill.solid()
shape.fill.fore_color.rgb = fill_color
return shape
def add_text(slide, text, x, y, w, h,
font_name="Calibri", size=18, bold=False, italic=False,
color=DARK_GREY, align=PP_ALIGN.LEFT, wrap=True,
v_anchor=MSO_ANCHOR.TOP):
tb = slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h))
tf = tb.text_frame
tf.word_wrap = wrap
tf.vertical_anchor = v_anchor
tf.margin_left = Pt(4)
tf.margin_right = Pt(4)
tf.margin_top = Pt(2)
tf.margin_bottom = Pt(2)
p = tf.paragraphs[0]
p.alignment = align
run = p.add_run()
run.text = text
run.font.name = font_name
run.font.size = Pt(size)
run.font.bold = bold
run.font.italic = italic
run.font.color.rgb = color
return tf
def add_bullet_box(slide, bullets, x, y, w, h,
font_name="Calibri", size=16, color=DARK_GREY,
bullet_color=TEAL):
"""Add a text box with bullet points."""
tb = slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h))
tf = tb.text_frame
tf.word_wrap = True
tf.margin_left = Pt(4)
tf.margin_right = Pt(4)
tf.margin_top = Pt(2)
tf.margin_bottom = Pt(2)
first = True
for bullet in bullets:
if first:
p = tf.paragraphs[0]
first = False
else:
p = tf.add_paragraph()
p.space_before = Pt(4)
run = p.add_run()
run.text = "• " + bullet
run.font.name = font_name
run.font.size = Pt(size)
run.font.color.rgb = color
return tf
def slide_header(slide, title, subtitle=None):
"""Add the standard navy top bar with title."""
add_rect(slide, 0, 0, 13.333, 1.1, NAVY)
add_text(slide, title,
x=0.3, y=0.05, w=12.5, h=0.75,
font_name="Calibri", size=30, bold=True, color=WHITE,
align=PP_ALIGN.LEFT, v_anchor=MSO_ANCHOR.MIDDLE)
if subtitle:
add_text(slide, subtitle,
x=0.3, y=0.78, w=12.5, h=0.35,
font_name="Calibri", size=16, color=GOLD,
align=PP_ALIGN.LEFT)
def add_footer(slide, text="Theories of Colour Vision | 4th Year Ophthalmology"):
add_rect(slide, 0, 7.2, 13.333, 0.3, NAVY)
add_text(slide, text,
x=0.2, y=7.2, w=12.9, h=0.3,
font_name="Calibri", size=10, color=WHITE,
align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 1 – Title slide
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, NAVY)
# Coloured stripe
for i, (col, xpos) in enumerate([(RED_C, 0), (GREEN_C, 4.44), (BLUE_C, 8.88)]):
add_rect(slide, xpos, 6.8, 4.44, 0.7, col)
add_text(slide, "THEORIES OF COLOUR VISION",
x=1, y=1.5, w=11.3, h=1.2,
font_name="Calibri", size=44, bold=True, color=WHITE,
align=PP_ALIGN.CENTER)
add_text(slide, "Mechanisms, Psychophysics & Clinical Relevance",
x=1, y=2.9, w=11.3, h=0.6,
font_name="Calibri", size=22, color=GOLD,
align=PP_ALIGN.CENTER)
add_text(slide, "4th Year MBBS | Ophthalmology",
x=1, y=3.55, w=11.3, h=0.45,
font_name="Calibri", size=18, color=WHITE,
align=PP_ALIGN.CENTER)
add_text(slide, "Department of Ophthalmology",
x=1, y=4.1, w=11.3, h=0.4,
font_name="Calibri", size=16, italic=True, color=LIGHT_GREY,
align=PP_ALIGN.CENTER)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 2 – Learning Objectives
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, LIGHT_GREY)
slide_header(slide, "Learning Objectives")
add_footer(slide)
objectives = [
"Describe the anatomy of the retinal photoreceptors involved in colour vision",
"Explain the Young-Helmholtz Trichromatic Theory and the role of the three cone types",
"Describe the Opponent-Process (Hering) Theory and colour-opponent channels",
"Understand the Dual Process Theory integrating both theories",
"List types of colour blindness (congenital and acquired) with genetic basis",
"Know the clinical tests for colour vision (Ishihara, Farnsworth-Munsell, HRR)",
"Recognise clinical scenarios where colour vision testing guides diagnosis",
]
add_rect(slide, 0.4, 1.3, 12.5, 5.7, WHITE)
add_bullet_box(slide, objectives, 0.7, 1.45, 12.0, 5.5, size=17)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 3 – Anatomy of photoreceptors
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, LIGHT_GREY)
slide_header(slide, "Photoreceptors & Colour Vision", subtitle="The cellular basis")
add_footer(slide)
# Left column
add_rect(slide, 0.4, 1.25, 6.2, 5.9, WHITE)
add_text(slide, "CONES – Photopic Vision",
x=0.6, y=1.35, w=5.8, h=0.45,
size=18, bold=True, color=TEAL)
cone_bullets = [
"~6 million in the human retina; concentrated at the fovea",
"Responsible for daylight (photopic) and colour vision",
"Three subtypes by opsin:",
" S-cones (blue) — peak ~430 nm",
" M-cones (green) — peak ~530 nm",
" L-cones (red) — peak ~560 nm",
"Broad spectral sensitivity with overlapping ranges",
"Color perception = RATIO of activation across three cone types",
]
add_bullet_box(slide, cone_bullets, 0.6, 1.85, 5.8, 4.8, size=15)
# Right column
add_rect(slide, 6.9, 1.25, 6.1, 5.9, WHITE)
add_text(slide, "RODS – Scotopic Vision",
x=7.1, y=1.35, w=5.7, h=0.45,
size=18, bold=True, color=NAVY)
rod_bullets = [
"~120 million; distributed in peripheral retina",
"Active at low light levels (scotopic vision)",
"Single photopigment: rhodopsin (peak ~498 nm)",
"Cannot discriminate wavelength — no colour information",
"In complete darkness, colour perception is ABSENT",
]
add_bullet_box(slide, rod_bullets, 7.1, 1.85, 5.7, 3.0, size=15)
add_text(slide, "Key Point",
x=7.1, y=5.0, w=5.7, h=0.35,
size=14, bold=True, color=GOLD)
add_text(slide, "Colour perception depends entirely on the cones and requires "
"adequate illumination (photopic conditions).",
x=7.1, y=5.35, w=5.7, h=1.0,
size=14, color=DARK_GREY, wrap=True)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 4 – Young-Helmholtz Trichromatic Theory
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, LIGHT_GREY)
slide_header(slide, "Young-Helmholtz Trichromatic Theory",
subtitle="The first theory of colour vision (1802 / 1850s)")
add_footer(slide)
add_rect(slide, 0.4, 1.25, 12.5, 5.9, WHITE)
# Proposers panel
add_rect(slide, 0.5, 1.35, 5.9, 1.4, NAVY)
add_text(slide, "Thomas Young (1802)",
x=0.6, y=1.4, w=2.8, h=0.5, size=14, bold=True, color=WHITE)
add_text(slide, "All colours can be created by mixing red, green & blue light in the correct proportions",
x=0.6, y=1.9, w=2.6, h=0.75, size=12, color=LIGHT_GREY, wrap=True)
add_text(slide, "Hermann von Helmholtz (1850s)",
x=3.5, y=1.4, w=2.8, h=0.5, size=14, bold=True, color=WHITE)
add_text(slide, "Championed & extended Young's ideas; invented the ophthalmoscope (1851)",
x=3.5, y=1.9, w=2.6, h=0.75, size=12, color=LIGHT_GREY, wrap=True)
add_text(slide, "Core Tenets",
x=0.6, y=2.9, w=5.8, h=0.4, size=16, bold=True, color=TEAL)
tenets = [
"Retina contains THREE types of cone photoreceptors",
"Each cone type has maximal sensitivity to a different wavelength range",
"Brain assigns colours based on the COMPARATIVE output of all three cone types",
"Mixing R + G + B light in equal intensity → White light perceived",
"Any colour can be matched by varying the ratio of three primaries",
]
add_bullet_box(slide, tenets, 0.6, 3.35, 5.8, 3.4, size=14)
# Right panel – cone sensitivity diagram (described as coloured boxes)
add_text(slide, "Spectral Sensitivity of Cones",
x=6.8, y=1.35, w=5.9, h=0.4, size=16, bold=True, color=TEAL)
# Simulated spectral diagram using coloured rectangles
y_base = 1.85
bar_height = 0.35
labels = [("S (Blue) ~430 nm", BLUE_C, 0.0, 2.5),
("M (Green) ~530 nm", GREEN_C, 0.5, 3.5),
("L (Red) ~560 nm", RED_C, 1.0, 4.5)]
for label, col, x_off, bar_w in labels:
add_rect(slide, 6.8 + x_off, y_base, bar_w + 1.0, bar_height, col)
add_text(slide, label,
x=6.8 + x_off + bar_w + 1.05, y=y_base, w=2.5, h=bar_height,
size=13, color=col, bold=True)
y_base += 0.55
add_text(slide, "← Short Wavelength (nm) Long →",
x=6.8, y=3.7, w=6.0, h=0.35, size=12, color=DARK_GREY)
add_text(slide, "Overlap is intentional: colour perception arises from the "
"ratio of activation, not absolute output of any single cone type.",
x=6.8, y=4.1, w=6.0, h=1.2,
size=13, color=DARK_GREY, wrap=True)
add_text(slide, "Support: Confirmed by electrophysiology — three distinct cone opsin genes "
"on chromosomes X (L & M) and 7 (S).",
x=6.8, y=5.5, w=6.0, h=1.1,
size=12, italic=True, color=NAVY, wrap=True)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 5 – Opponent Process Theory
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, LIGHT_GREY)
slide_header(slide, "Opponent-Process Theory (Hering, 1878)",
subtitle="Explains post-receptoral colour processing")
add_footer(slide)
add_rect(slide, 0.4, 1.25, 12.5, 5.9, WHITE)
add_text(slide, "Ewald Hering proposed THREE opponent colour pairs:",
x=0.6, y=1.35, w=12.0, h=0.4, size=16, bold=True, color=TEAL)
pairs = [
(RED_C, GREEN_C, "Red vs Green",
"Stimulated by red light — INHIBITED by green light (and vice versa)"),
(BLUE_C, RGBColor(0xFF, 0xD7, 0x00), "Blue vs Yellow",
"Stimulated by blue light — INHIBITED by yellow light"),
(WHITE, DARK_GREY, "White vs Black (Luminance)",
"Responds to overall luminance; not a hue channel per se"),
]
y_pos = 1.85
for col_a, col_b, label, desc in pairs:
add_rect(slide, 0.6, y_pos, 1.3, 0.55, col_a)
add_rect(slide, 1.95, y_pos, 1.3, 0.55, col_b)
add_text(slide, label,
x=3.4, y=y_pos, w=3.0, h=0.55, size=15, bold=True, color=DARK_GREY)
add_text(slide, desc,
x=6.5, y=y_pos, w=6.1, h=0.55, size=13, color=DARK_GREY, wrap=True)
y_pos += 0.7
add_text(slide, "Neural Implementation",
x=0.6, y=4.2, w=12.0, h=0.4, size=16, bold=True, color=TEAL)
neural = [
"P-type (midget) retinal ganglion cells = colour-opponent center-surround receptive fields",
"Example: R+G- cell — excited by red in centre, INHIBITED by green in surround",
"Blue-ON / Yellow-OFF cells: small bistratified ganglion cells (S-cone input)",
"Signals relayed via Parvocellular pathway → LGN → V4 (colour processing cortex)",
]
add_bullet_box(slide, neural, 0.6, 4.65, 12.0, 2.35, size=14)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 6 – Dual Process / Zone Theory
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, LIGHT_GREY)
slide_header(slide, "Dual Process (Zone) Theory",
subtitle="Integrating Trichromatic & Opponent-Process theories")
add_footer(slide)
add_rect(slide, 0.4, 1.25, 12.5, 5.9, WHITE)
add_text(slide, "Neither theory alone fully explains colour vision. The Dual Process (Zone) theory reconciles both:",
x=0.6, y=1.35, w=12.0, h=0.5, size=15, color=DARK_GREY, wrap=True)
# Zone diagram
zones = [
(RED_C, "ZONE 1 — Receptors\n(Trichromatic Stage)",
"Three types of cones (S, M, L) absorb light and generate graded receptor potentials.\n"
"Each cone responds to a broad wavelength range.\nBasis: Young-Helmholtz trichromacy."),
(TEAL, "ZONE 2 — Retinal Processing\n(Opponent Stage)",
"Bipolar cells, horizontal cells & ganglion cells reorganise signals into opponent channels:\n"
" • Red-Green channel\n • Blue-Yellow channel\n • Luminance (achromatic) channel\nBasis: Hering's opponent process."),
(NAVY, "ZONE 3 — Cortical Processing",
"Visual cortex (V1, V2, V4) recombines opponent signals.\n"
"V4 is the dedicated colour area; lesions cause cerebral achromatopsia.\n"
"Only ~10% of cortical neurons are primarily colour-selective."),
]
x_start = 0.6
box_w = 3.8
for i, (col, title, body) in enumerate(zones):
x = x_start + i * (box_w + 0.35)
add_rect(slide, x, 1.95, box_w, 0.65, col)
add_text(slide, title,
x=x+0.05, y=1.98, w=box_w-0.1, h=0.6,
size=13, bold=True, color=WHITE, align=PP_ALIGN.CENTER,
v_anchor=MSO_ANCHOR.MIDDLE)
add_rect(slide, x, 2.65, box_w, 3.8, LIGHT_GREY)
add_text(slide, body,
x=x+0.1, y=2.7, w=box_w-0.2, h=3.65,
size=12, color=DARK_GREY, wrap=True)
# Arrow between boxes
if i < 2:
ax = x + box_w + 0.05
add_text(slide, "→",
x=ax, y=2.9, w=0.3, h=0.4,
size=22, bold=True, color=TEAL)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 7 – Colour Blindness
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, LIGHT_GREY)
slide_header(slide, "Colour Vision Deficiency (CVD)",
subtitle="Types, genetics and prevalence")
add_footer(slide)
add_rect(slide, 0.4, 1.25, 12.5, 5.9, WHITE)
# Table header
cols_x = [0.5, 2.8, 5.1, 7.4, 10.1]
cols_w = [2.3, 2.3, 2.3, 2.7, 2.9]
headers = ["Type", "Missing/Abnormal", "Defect", "Prevalence (Males)", "Genetics"]
for i, (h, x, w) in enumerate(zip(headers, cols_x, cols_w)):
add_rect(slide, x, 1.35, w-0.05, 0.45, NAVY)
add_text(slide, h, x=x+0.05, y=1.35, w=w-0.1, h=0.45,
size=13, bold=True, color=WHITE, align=PP_ALIGN.CENTER,
v_anchor=MSO_ANCHOR.MIDDLE)
rows = [
("Protanopia", "L-cone absent", "Red blind", "1%", "X-linked"),
("Protanomaly", "L-cone abnormal", "Red weak", "1%", "X-linked"),
("Deuteranopia", "M-cone absent", "Green blind", "1%", "X-linked"),
("Deuteranomaly", "M-cone abnormal", "Green weak", "5%", "X-linked"),
("Tritanopia", "S-cone absent", "Blue-yellow blind","<0.01%", "Autosomal"),
("Achromatopsia", "All cones absent", "Total colour blind","<0.001%","Autosomal"),
]
row_colors = [WHITE, LIGHT_GREY] * 4
for r_idx, (row, bg) in enumerate(zip(rows, row_colors)):
y = 1.85 + r_idx * 0.6
for c_idx, (cell, x, w) in enumerate(zip(row, cols_x, cols_w)):
add_rect(slide, x, y, w-0.05, 0.55, bg)
add_text(slide, cell, x=x+0.05, y=y+0.02, w=w-0.1, h=0.5,
size=12, color=DARK_GREY, align=PP_ALIGN.CENTER,
v_anchor=MSO_ANCHOR.MIDDLE)
add_text(slide, "Prevalence: ~8% Northern European men, 0.5% women | "
"Red-green genes on X chromosome; Blue gene on Chromosome 7",
x=0.5, y=5.55, w=12.1, h=0.55,
size=12, italic=True, color=NAVY, wrap=True)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 8 – Acquired Colour Vision Defects
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, LIGHT_GREY)
slide_header(slide, "Acquired Colour Vision Defects",
subtitle="Important clinical correlations")
add_footer(slide)
add_rect(slide, 0.4, 1.25, 12.5, 5.9, WHITE)
add_text(slide, "OPTIC NERVE LESIONS",
x=0.6, y=1.35, w=5.7, h=0.4, size=16, bold=True, color=RED_C)
on_bullets = [
"Classically produce RED-GREEN colour defects",
"Due to preferential damage to P-cell (parvo) fibres",
"Dyschromatopsia may precede visual acuity loss",
"Simple screening: Ask patient to compare brightness / saturation of red target in each eye",
"Examples: Optic neuritis, compressive optic neuropathy, glaucoma",
]
add_bullet_box(slide, on_bullets, 0.6, 1.8, 5.8, 3.5, size=14)
add_text(slide, "MACULAR / RETINAL DISEASE",
x=6.8, y=1.35, w=5.7, h=0.4, size=16, bold=True, color=BLUE_C)
mac_bullets = [
"Typically produce BLUE-YELLOW (tritan) defects",
"Cone photoreceptor dysfunction at fovea",
"Examples: Age-related macular degeneration, Central serous chorioretinopathy",
"Acquired tritan defect also seen in glaucoma (early stages)",
]
add_bullet_box(slide, mac_bullets, 6.8, 1.8, 5.7, 3.0, size=14)
add_rect(slide, 0.6, 5.4, 12.0, 1.6, RGBColor(0xFF, 0xF0, 0xD0))
add_text(slide, "Clinical Pearl",
x=0.7, y=5.45, w=11.8, h=0.35, size=14, bold=True, color=GOLD)
add_text(slide, "In a patient with glaucoma, neuroimaging should be considered if there is "
"deterioration of colour vision or if the visual field defect is not consistent "
"with retinal nerve fibre layer loss. (Kanski's Clinical Ophthalmology)",
x=0.7, y=5.8, w=11.8, h=1.1,
size=13, italic=True, color=DARK_GREY, wrap=True)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 9 – Colour Vision Tests
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, LIGHT_GREY)
slide_header(slide, "Clinical Colour Vision Tests",
subtitle="Screening and diagnostic tools")
add_footer(slide)
add_rect(slide, 0.4, 1.25, 12.5, 5.9, WHITE)
tests = [
("Ishihara Plates",
"SCREEN",
GREEN_C,
["Pseudoisochromatic plates using coloured dots",
"Screens specifically for red-green (protan/deutan) defects",
"16 plates + 1 test plate; patient identifies embedded numbers",
"Cannot detect tritan (blue-yellow) or acquired defects reliably",
"If test plate not read → suspect non-organic visual loss"]),
("Hardy-Rand-Rittler (HRR)",
"SCREEN",
BLUE_C,
["Similar principle to Ishihara",
"Detects ALL THREE congenital colour defects (protan, deutan, tritan)",
"More comprehensive than Ishihara alone"]),
("City University Test",
"DIAGNOSE",
TEAL,
["10 plates; patient picks the closest colour match",
"Classifies type and severity of defect",
"Useful for monitoring acquired colour changes"]),
("Farnsworth-Munsell\n100-Hue Test",
"QUANTIFY",
NAVY,
["Sensitive but time-consuming (~30 min)",
"Patient arranges 85 coloured caps in order of hue",
"Detects and quantifies both congenital and acquired defects",
"Produces error score plotted on polar diagram"]),
]
x_pos = 0.5
for test_name, badge, col, bullets in tests:
box_w = 2.9
add_rect(slide, x_pos, 1.35, box_w, 0.55, col)
add_text(slide, test_name,
x=x_pos+0.05, y=1.35, w=box_w-0.1, h=0.55,
size=13, bold=True, color=WHITE,
align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
add_rect(slide, x_pos, 1.95, box_w, 0.3, GOLD)
add_text(slide, badge,
x=x_pos+0.05, y=1.95, w=box_w-0.1, h=0.3,
size=11, bold=True, color=NAVY,
align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
add_rect(slide, x_pos, 2.3, box_w, 4.5, LIGHT_GREY)
add_bullet_box(slide, bullets, x_pos+0.1, 2.35, box_w-0.2, 4.4, size=12)
x_pos += box_w + 0.23
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 10 – Visual Pathway & Colour Processing
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, LIGHT_GREY)
slide_header(slide, "Colour Processing in the Visual Pathway",
subtitle="From retina to cortex")
add_footer(slide)
add_rect(slide, 0.4, 1.25, 12.5, 5.9, WHITE)
stages = [
("RETINA", TEAL,
"• L, M, S cones → phototransduction\n"
"• Midget bipolar cells (one-to-one with cone in fovea)\n"
"• P-type ganglion cells → colour-opponent (R+G-, G+R-, B+Y-, Y+B-)\n"
"• M-type ganglion cells → luminance (not colour-selective)\n"
"• Small bistratified cells → Blue-ON / Yellow-OFF"),
("LATERAL GENICULATE\nNUCLEUS (LGN)", RED_C,
"• Parvocellular layers (P pathway) → carry colour & fine detail\n"
"• Magnocellular layers (M pathway) → motion & low spatial frequency\n"
"• Koniocellular layers → S-cone (blue) signals\n"
"• Colour opponency maintained and enhanced"),
("VISUAL CORTEX", NAVY,
"• V1 (striate): colour blob regions (cytochrome oxidase rich)\n"
"• V2: thin stripes → relay colour info\n"
"• V4: primary colour area; lesion → cerebral achromatopsia\n"
"• Only ~10% of V1 neurons preferentially colour-selective\n"
"• Final percept: integration of wavelength, brightness & context"),
]
x_pos = 0.6
box_w = 3.7
for i, (title, col, body) in enumerate(stages):
add_rect(slide, x_pos, 1.4, box_w, 0.65, col)
add_text(slide, title,
x=x_pos+0.05, y=1.4, w=box_w-0.1, h=0.65,
size=14, bold=True, color=WHITE,
align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
add_rect(slide, x_pos, 2.1, box_w, 4.85, LIGHT_GREY)
add_text(slide, body,
x=x_pos+0.1, y=2.15, w=box_w-0.2, h=4.7,
size=12, color=DARK_GREY, wrap=True)
if i < 2:
add_text(slide, "→",
x=x_pos + box_w + 0.05, y=2.9, w=0.3, h=0.5,
size=22, bold=True, color=TEAL)
x_pos += box_w + 0.35
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 11 – Comparison Summary Table
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, LIGHT_GREY)
slide_header(slide, "Comparing the Theories — At a Glance")
add_footer(slide)
add_rect(slide, 0.4, 1.25, 12.5, 5.9, WHITE)
col_headers = ["Feature", "Trichromatic Theory", "Opponent-Process Theory", "Dual Process Theory"]
col_xs = [0.5, 3.0, 6.1, 9.5]
col_ws = [2.45, 3.05, 3.35, 3.4]
# Header row
for h, x, w in zip(col_headers, col_xs, col_ws):
add_rect(slide, x, 1.35, w-0.05, 0.5, NAVY)
add_text(slide, h, x=x+0.05, y=1.35, w=w-0.1, h=0.5,
size=13, bold=True, color=WHITE,
align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
table_rows = [
("Proposed by", "Young (1802),\nHelmholtz (1850s)", "Hering (1878)", "Von Kries, Hurvich\n& Jameson (20th c.)"),
("Site", "Retinal cones (receptors)", "Retinal ganglion cells\n& beyond", "Both receptor &\npost-receptor"),
("Mechanism", "3 cone types with different\nspectral sensitivities", "Opponent colour pairs\n(R-G, B-Y, W-Bk)", "Combines both\nmechanisms"),
("Explains", "Colour matching,\ntrichromatism", "After-images,\nsimultaneous contrast, colour opponency", "Most colour\nphenomena"),
("Does NOT explain","After-images,\ncolour opponency", "Why 3 primary colours\nare needed for mixing", "(Most complete)"),
("Clinical use", "Basis of CVD classification\n(protan/deutan/tritan)", "Explains acquired\noptic nerve vs. macular patterns", "Framework for all\nclinical colour testing"),
]
for r_idx, row in enumerate(table_rows):
y = 1.9 + r_idx * 0.73
bg = WHITE if r_idx % 2 == 0 else LIGHT_GREY
for cell, x, w in zip(row, col_xs, col_ws):
add_rect(slide, x, y, w-0.05, 0.68, bg)
add_text(slide, cell, x=x+0.05, y=y+0.02, w=w-0.1, h=0.65,
size=11, color=DARK_GREY, wrap=True,
align=PP_ALIGN.CENTER, v_anchor=MSO_ANCHOR.MIDDLE)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 12 – Summary & Key Clinical Points
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, LIGHT_GREY)
slide_header(slide, "Summary & Key Clinical Takeaways")
add_footer(slide)
add_rect(slide, 0.4, 1.25, 12.5, 5.9, WHITE)
summary_left = [
"Young-Helmholtz Theory: Three cone types (S, M, L) at the receptor level underlie colour vision",
"Opponent-Process Theory: Colour signals reorganised into R-G and B-Y channels at ganglion cell level",
"Dual Process: Both theories are correct; they describe different stages in the visual pathway",
"Congenital CVD: X-linked recessive; ~8% males; red-green most common",
"Acquired CVD: Optic nerve → red-green defect; Macular disease → blue-yellow (tritan) defect",
]
add_text(slide, "Theory & Science",
x=0.6, y=1.35, w=5.9, h=0.4, size=15, bold=True, color=TEAL)
add_bullet_box(slide, summary_left, 0.6, 1.8, 5.9, 5.1, size=14)
summary_right = [
"Ishihara: Screens red-green only; 17/17 = normal",
"HRR: Screens all three types (protan, deutan, tritan)",
"FM 100-hue: Quantifies severity of any CVD",
"Colour vision testing is a sensitive early indicator of optic nerve dysfunction",
"Children with CVD benefit from early career counselling",
"Glaucoma: Neuroimaging warranted if colour vision worsens incongruously",
]
add_text(slide, "Clinical Practice",
x=7.0, y=1.35, w=5.5, h=0.4, size=15, bold=True, color=RED_C)
add_bullet_box(slide, summary_right, 7.0, 1.8, 5.5, 5.1, size=14)
# ─────────────────────────────────────────────────────────────────────────────
# SLIDE 13 – References
# ─────────────────────────────────────────────────────────────────────────────
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, LIGHT_GREY)
slide_header(slide, "References")
add_footer(slide)
add_rect(slide, 0.4, 1.25, 12.5, 5.9, WHITE)
refs = [
"Kanski JJ & Bowling B. Kanski's Clinical Ophthalmology: A Systematic Approach, 10th ed. Elsevier, 2020.",
"Bear MF, Connors BW, Paradiso MA. Neuroscience: Exploring the Brain, 5th ed. Wolters Kluwer, 2020.",
"Kandel ER et al. Principles of Neural Science, 6th ed. McGraw-Hill, 2021.",
"Ganong's Review of Medical Physiology, 26th ed. McGraw-Hill.",
"Hurvich LM & Jameson D. An Opponent-Process Theory of Color Vision. Psychol Rev 1957;64(6):384–404.",
"Neitz J & Neitz M. The genetics of normal and defective color vision. Vision Res 2011;51(7):633–651.",
]
add_bullet_box(slide, refs, 0.6, 1.45, 12.0, 5.6, size=14)
# ─────────────────────────────────────────────────────────────────────────────
# SAVE
# ─────────────────────────────────────────────────────────────────────────────
out_path = "/tmp/workspace/colour-vision-ppt/Theories_of_Colour_Vision_Ophthalmology.pptx"
prs.save(out_path)
print(f"Saved → {out_path}")
print(f"Slides: {len(prs.slides)}")
cd /tmp/workspace/colour-vision-ppt && python build_pptx.py 2>&1
python3 -c " from pptx import Presentation prs = Presentation('/tmp/workspace/colour-vision-ppt/Theories_of_Colour_Vision_Ophthalmology.pptx') for i, slide in enumerate(prs.slides, 1): texts = [s.text_frame.text.strip()[:60] for s in slide.shapes if s.has_text_frame and s.text_frame.text.strip()] print(f'Slide {i}: {texts[:3]}') "
Theories of Colour Vision Ophthalmology
Presentation · PPTX
| # | Slide Title |
|---|---|
| 1 | Title slide |
| 2 | Learning Objectives (7 goals) |
| 3 | Photoreceptors - Cones vs Rods, spectral peaks (430/530/560 nm) |
| 4 | Young-Helmholtz Trichromatic Theory - proposers, tenets, colour-coded spectral diagram |
| 5 | Opponent-Process Theory (Hering 1878) - 3 opponent pairs, neural implementation via P-type ganglion cells |
| 6 | Dual Process / Zone Theory - 3-zone pathway diagram integrating both theories |
| 7 | Colour Vision Deficiency table - Protan/Deutan/Tritan, prevalence, genetics |
| 8 | Acquired CVD - Optic nerve (red-green) vs Macular (blue-yellow) + Kanski clinical pearl |
| 9 | Clinical tests - Ishihara, HRR, City University, FM 100-hue (with badge: SCREEN/DIAGNOSE/QUANTIFY) |
| 10 | Colour processing pathway - Retina → LGN → V1/V4 cortex |
| 11 | Comparison table - all three theories side-by-side |
| 12 | Summary & Key Clinical Takeaways (both columns) |
| 13 | References (Kanski, Bear/Neuroscience, Kandel, Ganong, Hurvich & Jameson) |