Vision · University · about 35 min
Segmentation by threshold, what the threshold is really measuring, and where it fails.
[1 mark]Why does the test r > 150 fail to find a red ball on the nearly white mat, even in a simulator with no lighting model?
[1 mark]Four pixels: white mat, a red ball, the same ball in shadow, and a pale pink wall. What does this print?
pixels = [(230, 225, 220), (200, 40, 30), (120, 30, 25), (240, 200, 180)] bright = sum(1 for (r, g, b) in pixels if r > 150) dominant = sum(1 for (r, g, b) in pixels if r - max(g, b) > 60) chroma = sum(1 for (r, g, b) in pixels if r / (r + g + b + 1) > 0.5) print(bright, dominant, chroma)
3 2 2
The brightness test passes the mat, the ball and the wall but misses the shadowed ball. Both colour tests pass exactly the two ball pixels, lit and shadowed.
[1 mark]In a 64 pixel wide picture from the 320 pixel camera, the red pixels' centroid is at column 40. What is the bearing in degrees to 1 decimal place, using f = 92.4?
[1 mark]In pixel = illumination x reflectance x sensor response, which factor is a property of the object?
[1 mark]Which of these break a colour threshold that worked in the lab?
Tick every answer that is true.
[1 mark]Why is a specular highlight worse for a chromaticity test than a shadow?
A red ball is ahead of the robot. Take a 64 by 48 picture with camera_image(64, 48) and print three things: naive:, the percentage of the picture that passes a plain r > 150 test; red:, how many pixels pass a test that looks at colour rather than brightness; and bearing:, the bearing in degrees of the centroid of those pixels.
from bugbot import * import math connect() F = 92.4 W, H = 64, 48 img = camera_image(W, H)
The hint students can ask for: Take a 64 by 48 picture and count, twice. First with the test a beginner writes, red above some level, and express the answer as a percentage of the whole picture, because the number itself is the lesson. Then with a test that asks whether red dominates the other two channels rather than whether the pixel is bright. Average the columns of the pixels that survive the second test, scale that column back up to the camera's own 320 wide frame, and turn it into a bearing the way you did in U11.1.
from bugbot import *
import math
connect()
F = 92.4
W, H = 64, 48
img = camera_image(W, H)
bright = 0
cols = []
for row in img:
for u in range(W):
r, g, b = row[u]
if r > 150:
bright += 1 # the beginner's test: bright, not red
if r - max(g, b) > 60:
cols.append(u) # red dominates the other two channels
print("naive:", round(100.0 * bright / (W * H), 1))
print("red:", len(cols))
u = sum(cols) / len(cols)
x = (u + 0.5) * 320.0 / W # back to the camera's own 320 wide frame
print("bearing:", round(math.degrees(math.atan((x - 160) / F)), 2))
Any program that meets the task's checks is marked correct in the simulator; this is one way, not the only way.