1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
#!/usr/bin/python2
import logging
import cv
import numpy as np
#import time
# Bool to define wether to capture the cam or not
capture = True
# Bool to define wether to show the capture stream or not
showStream = True
white_threshold = 30.0
checked = np.zeros((1, 1), dtype=np.int)
mat = np.zeros((1, 1))
clusters = []
def capture(camNumber, showStream):
# Open stream for that camera
logging.info('Capture from camera #%d', camNumber)
cam = cv.CaptureFromCAM(int(camNumber))
# Stream to output window as long as it is active
return cam
while capture:
stream = cv.QueryFrame(cam)
if showStream:
cv.ShowImage("Americium 241", stream)
def set_capture(onOrOff):
if onOrOff == bool:
global capture
capture = onOrOff
def frame_to_mat(img):
cv.Smooth(img, img, cv.CV_GAUSSIAN, 3, 0)
mat = cv.GetMat(img)
frame_values = np.asarray(mat)
return frame_values
# Convert a bgr matrix to grayscale
def bgr2gray(mat):
b, g, r = mat[:, :, 0], mat[:, :, 1], mat[:, :, 2]
gray = 0.1140 * b + 0.5870 * g + 0.2989 * r
return gray
# Find a white dot in the black input matrix
def find_dot(mat_input):
global mat
global checked
global clusters
mat = mat_input.copy()
if np.ndim(mat) >= 2:
# Create array to hold the already checked pixels
checked = np.zeros((len(mat), len(mat[0])), dtype=np.int)
# Traverse the grayscale values in search of a bright pixel
for i in range(0, len(mat) - 1):
for j in range(0, len(mat[0]) - 1):
# Check if it hasn't been checked yet
if (checked[i][j] != 1):
# Find clusters, if the pixel is above threshold
if (mat[i][j] >= white_threshold):
#print "Hit above white threshold"
# Add a new cluster to the list of clusters
cluster = []
clusters.append(cluster)
# Find the rest of the cluster
find_cluster(i, j)
#print "Number at: %dx%dpx : %s" % (j, i, mat[i][j])
checked[i][j] = 1
# If there's one or more clusters, calculate its or their balance point
if len(clusters) > 0:
balance_point = cluster_to_balance_point()
logging.info('%s, %s', balance_point[1], balance_point[0])
#print balance_point
# Empty the global clusters variable again
del clusters[:]
return balance_point
else:
logging.error('Input matrix has wrong dimension!')
# Find cluster around a non-black pixel
def find_cluster(x, y):
global checked
global mat
global clusters
# Append the current white dot to the last cluster
dot = np.array([x, y, mat[x][y]])
clusters[len(clusters) - 1].append(dot)
# Search for surrounding white dots now
# Search one pixel further right
if (len(mat) - 1 >= (x + 1)) and (mat[x + 1][y] >= white_threshold) \
and (checked[x + 1][y] != 1):
find_cluster(x + 1, y)
# Search one pixel further right and down
if (len(mat) - 1 >= (x + 1)) and (len(mat[0]) - 1 >= y + 1) and \
(mat[x + 1][y + 1] >= white_threshold) \
and (checked[x + 1][y] != 1):
find_cluster(x + 1, y + 1)
# Search one pixel further down
if (len(mat[0]) - 1 >= y + 1) and \
(mat[x][y + 1] >= white_threshold) and (checked[x][y + 1] != 1):
find_cluster(x, y + 1)
# Search one pixel further down and further left
if (len(mat[0]) - 1 >= y + 1) and x - 1 >= 0 \
and (mat[x - 1][y + 1] >= white_threshold) \
and (checked[x - 1][y + 1] != 1):
find_cluster(x - 1, y + 1)
# Add this pixel to the list of checked pixels
checked[x][y] = 1
# Create balance point from cluster
# TODO: Make possible to choose only most significant cluster
def cluster_to_balance_point():
global clusters
cluster_balances = []
x_balance = 0.0
y_balance = 0.0
for cluster in clusters:
mean_x = 0.0
mean_y = 0.0
sum_total = 0.0
for dot in cluster:
# Calculate X balance (x * intensity)
mean_x = mean_x + dot[0] * dot[2]
# Calculate Y balance (y * intensity)
mean_y = mean_y + dot[1] * dot[2]
# Calculate Y total (all intensity summed up)
sum_total = sum_total + dot[2]
# Add up the balances and put them into a list
cluster_x_balance = mean_x / sum_total
cluster_y_balance = mean_y / sum_total
cluster_balances.append([cluster_x_balance, cluster_y_balance])
# If it's more than one cluster, balance between them
if len(cluster_balances) > 1:
logging.info('Balancing between a couple of clusters.')
total_cluster_x_balance = 0.0
total_cluster_y_balance = 0.0
for balance in cluster_balances:
total_cluster_x_balance = total_cluster_x_balance + balance[0]
total_cluster_y_balance = total_cluster_y_balance + balance[1]
x_balance = total_cluster_x_balance / float(len(cluster_balances))
y_balance = total_cluster_y_balance / float(len(cluster_balances))
else:
logging.info('Balancing between one cluster.')
x_balance = cluster_x_balance
y_balance = cluster_y_balance
return [x_balance, y_balance]
# TODO: Function to add up balances
# TODO: Function to calculate forced balance
|