def samplecolours(filename, x0, y0, x1, y1, draw=False):
img = cv2.imread(filename, 1) # 1=colour image
if draw:
detect = img.copy()
lines = 200 # number of sample lines over the length of the resistor
points = 50 # number of points per sample line
# Coordinates of the endpoints of the resistor = detection line
rxy = (x0, y0, x1, y1)
# Draw thick red line over the length of the resistor
if draw:
cv2.line(detect, (x0, y0), (x1, y1), (0,0,255), 10)
# Resistor dimensions
rdx = x0 - x1 # resistor dx
rdy = y0 - y1 # resistor dy
rlen = sqrt(rdx * rdx + rdy * rdy) # resistor length
# Sample line dimensions
slen = rlen / 8 # sample line length (from centre) relative to resistor length
sang = atan2(rdy, rdx) + pi / 2 # sample line angle perpendicular to the resistor
sdx = slen * cos(sang) # sample line dx (from centre)
sdy = slen * sin(sang) # sample line dy (from centre)
# Coordinates along the resistor on the detection line
rx = np.linspace(x0, x1, num=lines)
ry = np.linspace(y0, y1, num=lines)
# BGR and HSV arrays with average colour values along the sample lines
bgr = np.zeros((lines, 3), dtype=np.float64)
hsv = np.zeros((lines, 3), dtype=np.float64)
# Sampling lines perpendicular along the resistor
for i in range(lines):
# Endpoint tuples of the sample line
sxy1 = (round(rx[i] + sdx), round(ry[i] + sdy))
sxy2 = (round(rx[i] - sdx), round(ry[i] - sdy))
# Draw thin yellow line on the sample line
if draw:
cv2.line(detect, sxy1, sxy2, (0,255,255), 1)
# Coordinates along the sample line
sx = np.linspace(sxy1[0], sxy2[0], num=points)
sy = np.linspace(sxy1[1], sxy2[1], num=points)
# Average of BGR colour values along the sample line
avg = np.zeros(3, dtype=np.float64)
# Summing points along the sample line
# and calculating the average
for j in range(points):
avg += img[round(sy[j]), round(sx[j])]
avg /= points
# Save BGR and HSV results of the sample line
# all values must be or are in range 0.0 - 1.0
bgr[i] = avg / 255
hsv[i] = rgb_to_hsv(bgr[i, 2], bgr[i, 1], bgr[i, 0])
# Hue correction modulo 1.0 for useable peaks
if i > 0 and hsv[i - 1, 0] >= 0.8 and hsv[i, 0] <= 0.2:
hsv[i, 0] += 1
if draw:
dpi = 96
w = img.shape[1]
h = img.shape[0]
plt.figure(figsize=(2 * w/dpi,h/dpi),dpi=dpi)
plt.subplot(121)
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.title("Origineel")
plt.subplot(122)
plt.imshow(cv2.cvtColor(detect, cv2.COLOR_BGR2RGB))
plt.title("Detectie & bemonstering")
plt.show()
return (bgr, hsv)
# Smoothing filter with moving average
# returns: new array with length reduced by window-1
def movingaverage(data, window=9):
return np.convolve(data, np.ones(window, dtype=np.float64), 'valid') / window
# Get indices of peaks via smoothed data
# extrema() = scipy.signal.argrelextrema()
# returns: one-dimensional Numpy array with original indices of peaks
def peaks(data, window=9):
return extrema(movingaverage(data, window), np.greater)[0] + window // 2
# Get indices of troughs via smoothed data
# extrema() = scipy.signal.argrelextrema()
# returns: one-dimensional Numpy array with original indices of troughs
def troughs(data, window=9):
return extrema(movingaverage(data, window), np.less)[0] + window // 2
def colourids(bgr, hsv, window=9):
ix = peaks(hsv[:, 0], window) # hue peaks index array
ids = np.concatenate((bgr[ix], hsv[ix]), axis=1) # array of [b,g,r,h,s,v] arrays
return (ix, ids.astype(np.float32))
# def colourids_average(bgr, hsv, window=9, average=3):
# side = average // 2 # one-sided width of averaging set
# ix = peaks(hsv[:, 0], window) # hue peaks index array
# count = len(peaks)
# ids = np.zeros((count, 6), dtype=np.float64) # array of [b,g,r,h,s,v] arrays
# for i in range(count):
# j = ix[i] - side
# k = ix[i] + side + 1
# a = np.mean(bgr[j:k], axis=0)
# b = np.mean(hsv[j:k], axis=0)
# ids[i] = np.concatenate((a, b))
# return (ix, ids)
def drawhisto(bgr, hsv):
plt.figure(figsize=(20, 20))
plt.subplot(231)
_ = plt.hist(bgr[:, 2], bins=10, range=(0.0, 1.0))
plt.title("Rood")
plt.subplot(232)
_ = plt.hist(bgr[:, 1], bins=10, range=(0.0, 1.0))
plt.title("Groen")
plt.subplot(233)
_ = plt.hist(bgr[:, 0], bins=10, range=(0.0, 1.0))
plt.title("Blauw")
plt.subplot(234)
_ = plt.hist(hsv[:,0], bins=12, range=(0.0, 1.2))
plt.title("Tint")
plt.subplot(235)
_ = plt.hist(hsv[:,1], bins=12, range=(0.0, 1.2))
plt.title("Verzadiging")
plt.subplot(236)
_ = plt.hist(hsv[:,2], bins=12, range=(0.0, 1.2))
plt.title("Intensiteit")
plt.tight_layout()
plt.show()
def drawsamples(bgr, hsv, window=9):
x = np.arange(len(bgr) - window + 1)
plt.figure(figsize=(15, 20))
plt.subplot(211)
plt.title("Geëffende gemiddelde BGR-waardes haaks op de as van de weerstand")
plt.xlabel("Monsterlijn")
plt.plot(x, movingaverage(bgr[:, 0], window))
plt.plot(x, movingaverage(bgr[:, 1], window))
plt.plot(x, movingaverage(bgr[:, 2], window))
plt.legend(("Blauw", "Rood", "Groen"))
plt.subplot(212)
plt.title("Geëffende gemiddelde HSV-waardes haaks op de as van de weerstand")
plt.plot(x, movingaverage(hsv[:, 0], window))
plt.plot(x, movingaverage(hsv[:, 1], window))
plt.plot(x, movingaverage(hsv[:, 2], window))
plt.legend(("Tint", "Verzadiging", "Intensiteit"))
plt.tight_layout()
plt.show()