Skip to content

Commit e58b8e2

Browse files
committed
proposed compromise for issue #78
1 parent 8030c1c commit e58b8e2

File tree

5 files changed

+46
-40
lines changed

5 files changed

+46
-40
lines changed

_extras/edge-detection.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ The skimage `skimage.feature.canny()` function performs the following steps:
8787
is applied to remove noise from the image.
8888
(So if we are doing edge detection via this function,
8989
we should not perform our own blurring step.)
90-
2. Sobel edge detection is performed on both the x and y dimensions,
90+
2. Sobel edge detection is performed on both the cx and ry dimensions,
9191
to find the intensity gradients of the edges in the image.
9292
Sobel edge detection computes
9393
the derivative of a curve fitting the gradient between light and dark areas

episodes/02-image-basics.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ keypoints:
1717
- "Digital images are represented as rectangular arrays of square pixels."
1818
- "Digital images use a left-hand coordinate system, with the origin in the
1919
upper left corner, the x-axis running to the right, and the y-axis running
20-
down."
20+
down. Some learners may prefer to think in terms of counting down rows
21+
for the y-axis and across columns for the x-axis. Thus, we will make an
22+
effort to allow for both approaches in our lesson presentation."
2123
- "Most frequently, digital images use an additive RGB model, with eight bits
2224
for the red, green, and blue channels."
2325
- "Lossless compression retains all the details in an image, but lossy
@@ -271,7 +273,11 @@ print(zero)
271273
> Until you have worked with images for a while,
272274
> the most common mistake that you will make with coordinates is to forget
273275
> that y coordinates get larger as they go down instead of up
274-
> as in a normal Cartesian coordinate system.
276+
> as in a normal Cartesian coordinate system. Consequently, it may be helpful to think
277+
> in terms of counting down rows (r) for the y-axis and across columns (c) for the x-axis. This
278+
> can be especially helpful in cases where you need to transpose image viewer data
279+
> provided in *x,y* format to *y,x* format. Thus, we will use *cx* and *ry* where appropriate
280+
> to help bridge these two approaches.
275281
{: .callout }
276282
277283
> ## Changing Pixel Values (5 min)

episodes/03-skimage-images.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ layers can cause some confusion,
4848
so we should spend a bit more time looking at that.
4949

5050
When we think of a pixel in an image,
51-
we think of its (x, y) coordinates (in a left-hand coordinate system)
51+
we think of its (cx, ry) coordinates (in a left-hand coordinate system)
5252
like (113, 45) and its colour,
5353
specified as a RGB triple like (245, 134, 29).
5454
In an skimage image, the same pixel would be specified with
55-
*(y, x)* coordinates (45, 113) and *RGB* colour (245, 134, 29).
55+
*(ry, cx)* coordinates (45, 113) and *RGB* colour (245, 134, 29).
5656

5757
Let us take a look at this idea visually.
5858
Consider this image of a chair:
@@ -76,7 +76,7 @@ blue in layer 2.
7676
> CAUTION: it is vital to remember the order of the coordinates and
7777
> colour channels when dealing with images as NumPy arrays.
7878
> *If* we are manipulating or accessing an image array directly,
79-
> we specifiy the y coordinate first, then the x.
79+
> we specifiy the ry coordinate first, then the cx.
8080
> Further, the first channel stored is the red channel,
8181
> followed by the green, and then the blue.
8282
>
@@ -234,7 +234,7 @@ In this case, the `.tif` extension causes the image to be saved as a TIFF.
234234
> Don't forget to use `fig, ax = plt.subplots()` so you don't overwrite
235235
> the first image with the second.
236236
> Images may appear the same size in jupyter,
237-
> but you can see the size difference by comparing the x and y scales for each.
237+
> but you can see the size difference by comparing the scales for each.
238238
> You can also see the differnce in file storage size on disk by
239239
> hovering your mouse cursor over the original
240240
> and the new file in the jupyter file browser, using `ls -l` in your shell,
@@ -463,7 +463,7 @@ so we can use array slicing to select rectangular areas of an image.
463463
Then, we can save the selection as a new image, change the pixels in the image,
464464
and so on.
465465
It is important to
466-
remember that coordinates are specified in *(y, x)* order and that colour values
466+
remember that coordinates are specified in *(ry, cx)* order and that colour values
467467
are specified in *(r, g, b)* order when doing these manipulations.
468468
469469
Consider this image of a whiteboard, and suppose that we want to create a
@@ -482,14 +482,14 @@ as shown in this version of the whiteboard picture:
482482
483483
![Whiteboard coordinates](../fig/board-coordinates.jpg)
484484
485-
Note that the coordinates in the preceding image are specified in *(x, y)* order.
485+
Note that the coordinates in the preceding image are specified in *(cx, ry)* order.
486486
Now if our entire whiteboard image is stored as an skimage image named `image`,
487487
we can create a new image of the selected region with a statement like this:
488488
489489
`clip = image[60:151, 135:481, :]`
490490
491-
Our array slicing specifies the range of y-coordinates first, `60:151`,
492-
and then the range of x-coordinates, `135:481`.
491+
Our array slicing specifies the range of y-coordinates or rows first, `60:151`,
492+
and then the range of x-coordinates or columns, `135:481`.
493493
Note we go one beyond the maximum value in each dimension,
494494
so that the entire desired area is selected.
495495
The third part of the slice, `:`,
@@ -537,7 +537,7 @@ plt.imshow(image)
537537
First, we sample a single pixel's colour at a particular location of the
538538
image, saving it in a variable named `color`,
539539
which creates a 1 × 1 × 3 NumPy array with the blue, green, and red colour values
540-
for the pixel located at *(y = 330, x = 90)*.
540+
for the pixel located at *(ry = 330, cx = 90)*.
541541
Then, with the `img[60:151, 135:481] = color` command,
542542
we modify the image in the specified area.
543543
From a NumPy perspective,

episodes/04-drawing.md

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ Here is what our constructed mask looks like:
127127

128128
The parameters of the `rectangle()` function `(357, 44)` and `(740, 720)`,
129129
are the coordinates of the upper-left (`start`) and lower-right (`end`) corners
130-
of a rectangle in *(y, x)* order.
130+
of a rectangle in *(ry, cx)* order.
131131
The function returns the rectangle as row (`rr`) and column (`cc`) coordinate arrays.
132132

133133
> ## Check the documentation!
@@ -169,16 +169,16 @@ The function returns the rectangle as row (`rr`) and column (`cc`) coordinate ar
169169
>
170170
> Circles can be drawn with the `skimage.draw.disk()` function,
171171
> which takes two parameters:
172-
> the (y, x) point of the centre of the circle,
172+
> the (ry, cx) point of the centre of the circle,
173173
> and the radius of the circle.
174174
> There is an optional `shape` parameter that can be supplied to this function.
175175
> It will limit the output coordinates for cases where the circle
176176
> dimensions exceed the ones of the image.
177177
>
178178
> Lines can be drawn with the `skimage.draw.line()` function,
179179
> which takes four parameters:
180-
> the (y, x) coordinate of one end of the line,
181-
> and the (y, x) coordinate of the other end of the line.
180+
> the (ry, cx) coordinate of one end of the line,
181+
> and the (ry, cx) coordinate of the other end of the line.
182182
>
183183
> Other drawing functions supported by skimage can be found in
184184
> [the skimage reference pages](https://scikit-image.org/docs/dev/api/skimage.draw.html?highlight=draw#module-skimage.draw).
@@ -200,7 +200,7 @@ The function returns the rectangle as row (`rr`) and column (`cc`) coordinate ar
200200
> > Drawing a circle:
201201
> >
202202
> > ~~~
203-
> > # Draw a blue circle with centre (200, 300) in (y, x) coordinates, and radius 100
203+
> > # Draw a blue circle with centre (200, 300) in (ry, cx) coordinates, and radius 100
204204
> > rr, cc = skimage.draw.disk(center=(200, 300), radius=100, shape=image.shape[0:2])
205205
> > image[rr, cc] = (0, 0, 255)
206206
> > ~~~
@@ -209,7 +209,7 @@ The function returns the rectangle as row (`rr`) and column (`cc`) coordinate ar
209209
> > Drawing a line:
210210
> >
211211
> > ~~~
212-
> > # Draw a green line from (400, 200) to (500, 700) in (y, x) coordinates
212+
> > # Draw a green line from (400, 200) to (500, 700) in (ry, cx) coordinates
213213
> > rr, cc = skimage.draw.line(r0=400, c0=200, r1=500, c1=700)
214214
> > image[rr, cc] = (0, 255, 0)
215215
> > ~~~
@@ -438,7 +438,7 @@ The resulting masked image should look like this:
438438
> Your task is to write some code that will produce a mask that will
439439
> mask out everything except for the wells.
440440
> To help with this, you should use the text file `data/centers.txt` that contains
441-
> the (x, y) coordinates of the centre of each of the 96 wells in this image.
441+
> the (cx, ry) coordinates of the centre of each of the 96 wells in this image.
442442
> You may assume that each of the wells has a radius of 16 pixels.
443443
>
444444
> Your program should produce output that looks like this:
@@ -459,11 +459,11 @@ The resulting masked image should look like this:
459459
> > for line in center_file:
460460
> > # ... getting the coordinates of each well...
461461
> > coordinates = line.split()
462-
> > x = int(coordinates[0])
463-
> > y = int(coordinates[1])
462+
> > cx = int(coordinates[0])
463+
> > ry = int(coordinates[1])
464464
> >
465465
> > # ... and drawing a circle on the mask
466-
> > rr, cc = skimage.draw.disk(center=(y, x), radius=16, shape=image.shape[0:2])
466+
> > rr, cc = skimage.draw.disk(center=(ry, cx), radius=16, shape=image.shape[0:2])
467467
> > mask[rr, cc] = False
468468
> >
469469
> > # apply the mask
@@ -491,9 +491,9 @@ The resulting masked image should look like this:
491491
> we could produce our well plate mask without having to
492492
> read in the coordinates of the centres of each well.
493493
> Assume that the centre of the upper left well in the image is at
494-
> location x = 91 and y = 108, and that there are
495-
> 70 pixels between each centre in the x dimension and
496-
> 72 pixels between each centre in the y dimension.
494+
> location cx = 91 and ry = 108, and that there are
495+
> 70 pixels between each centre in the cx dimension and
496+
> 72 pixels between each centre in the ry dimension.
497497
> Each well still has a radius of 16 pixels.
498498
> Write a Python program that produces the same output image as in the previous challenge,
499499
> but *without* having to read in the `centers.txt` file.
@@ -512,28 +512,28 @@ The resulting masked image should look like this:
512512
> > mask = np.ones(shape=image.shape[0:2], dtype="bool")
513513
> >
514514
> > # upper left well coordinates
515-
> > x0 = 91
516-
> > y0 = 108
515+
> > cx0 = 91
516+
> > ry0 = 108
517517
> >
518518
> > # spaces between wells
519-
> > deltaX = 70
520-
> > deltaY = 72
519+
> > deltaCX = 70
520+
> > deltaRY = 72
521521
> >
522-
> > x = x0
523-
> > y = y0
522+
> > cx = cx0
523+
> > ry = ry0
524524
> >
525525
> > # iterate each row and column
526526
> > for row in range(12):
527-
> > # reset x to leftmost well in the row
528-
> > x = x0
527+
> > # reset cx to leftmost well in the row
528+
> > cx = cx0
529529
> > for col in range(8):
530530
> >
531531
> > # ... and drawing a circle on the mask
532-
> > rr, cc = skimage.draw.disk(center=(y, x), radius=16, shape=image.shape[0:2])
532+
> > rr, cc = skimage.draw.disk(center=(ry, cx), radius=16, shape=image.shape[0:2])
533533
> > mask[rr, cc] = False
534-
> > x += deltaX
534+
> > cx += deltaCX
535535
> > # after one complete row, move to next row
536-
> > y += deltaY
536+
> > ry += deltaRY
537537
> >
538538
> > # apply the mask
539539
> > image[mask] = 0

episodes/06-blurring.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ blurred = skimage.filters.gaussian(
257257
{: .language-python}
258258
259259
The first two parameters to `skimage.filters.gaussian()` are the image to blur,
260-
`image`, and a tuple defining the sigma to use in y- and x-direction,
260+
`image`, and a tuple defining the sigma to use in ry- and cx-direction,
261261
`(sigma, sigma)`.
262262
The third parameter `truncate` gives the radius of the kernel in terms of sigmas.
263263
A Gaussian function is defined from -infinity to +infinity, but our kernel
@@ -311,13 +311,13 @@ plt.show()
311311
> ## Experimenting with kernel shape (10 min - optional, not included in timing)
312312
>
313313
> Now, what is the effect of applying an asymmetric kernel to blurring an image?
314-
> Try running the code above with different sigmas in the y and x direction.
315-
> For example, a sigma of 1.0 in the y direction, and 6.0 in the x direction.
314+
> Try running the code above with different sigmas in the ry and cx direction.
315+
> For example, a sigma of 1.0 in the ry direction, and 6.0 in the cx direction.
316316
>
317317
> > ## Solution
318318
> >
319319
> > ~~~
320-
> > # apply Gaussian blur, with a sigma of 1.0 in the y direction, and 6.0 in the x direction
320+
> > # apply Gaussian blur, with a sigma of 1.0 in the ry direction, and 6.0 in the cx direction
321321
> > blurred = skimage.filters.gaussian(
322322
> > image, sigma=(1.0, 6.0), truncate=3.5, multichannel=True
323323
> > )

0 commit comments

Comments
 (0)