in services/read-gauge.py [0:0]
def calibrate_gauge(img,img_path, image_key,file_type):
try:
'''
This function should be run using a test image in order to calibrate the range available to the dial as well as the
units. It works by first finding the center point and radius of the gauge. Then it draws lines at hard coded intervals
(separation) in degrees. It then prompts the user to enter position in degrees of the lowest possible value of the gauge,
as well as the starting value (which is probably zero in most cases but it won't assume that). It will then ask for the
position in degrees of the largest possible value of the gauge. Finally, it will ask for the units. This assumes that
the gauge is linear (as most probably are).
It will return the min value with angle in degrees (as a tuple), the max value with angle in degrees (as a tuple),
and the units (as a string).
'''
print('%s%s.%s' % (img_path, image_key,file_type));
# img = cv2.imread('%s%s.%s' % (img_path, image_key,file_type))
height, width = img.shape[:2]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #convert to gray
#gray = cv2.GaussianBlur(gray, (5, 5), 0)
# gray = cv2.medianBlur(gray, 5)
#for testing, output gray image
cv2.imwrite('%s%s-bw.%s' % (img_path, image_key,file_type),gray)
#detect circles
#restricting the search from 35-48% of the possible radii gives fairly good results across different samples. Remember that
#these are pixel values which correspond to the possible radii search range.
# circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 20, np.array([]), 100, 50, int(height*0.35), int(height*0.48))
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 20, np.array([]), 100, 50, int(height*0.35), int(height*0.48))
# average found circles, found it to be more accurate than trying to tune HoughCircles parameters to get just the right one
# print(circles)
print(circles.shape)
a, b, c = circles.shape
x,y,r = avg_circles(circles, b)
#draw center and circle
cv2.circle(img, (x, y), r, (0, 0, 255), 3, cv2.LINE_AA) # draw circle
cv2.circle(img, (x, y), 2, (0, 255, 0), 3, cv2.LINE_AA) # draw center of circle
#for testing, output circles on image
cv2.imwrite('%s%s-circles.%s' % (img_path, image_key,file_type), img)
#for calibration, plot lines from center going out at every 10 degrees and add marker
#for i from 0 to 36 (every 10 deg)
'''
goes through the motion of a circle and sets x and y values based on the set separation spacing. Also adds text to each
line. These lines and text labels serve as the reference point for the user to enter
NOTE: by default this approach sets 0/360 to be the +x axis (if the image has a cartesian grid in the middle), the addition
(i+9) in the text offset rotates the labels by 90 degrees so 0/360 is at the bottom (-y in cartesian). So this assumes the
gauge is aligned in the image, but it can be adjusted by changing the value of 9 to something else.
'''
separation = 10.0 #in degrees
interval = int(360 / separation)
p1 = np.zeros((interval,2)) #set empty arrays
p2 = np.zeros((interval,2))
p_text = np.zeros((interval,2))
for i in range(0,interval):
for j in range(0,2):
if (j%2==0):
p1[i][j] = x + 0.9 * r * np.cos(separation * i * 3.14 / 180) #point for lines
else:
p1[i][j] = y + 0.9 * r * np.sin(separation * i * 3.14 / 180)
text_offset_x = 10
text_offset_y = 5
for i in range(0, interval):
for j in range(0, 2):
if (j % 2 == 0):
p2[i][j] = x + r * np.cos(separation * i * 3.14 / 180)
p_text[i][j] = x - text_offset_x + 1.2 * r * np.cos((separation) * (i+9) * 3.14 / 180) #point for text labels, i+9 rotates the labels by 90 degrees
else:
p2[i][j] = y + r * np.sin(separation * i * 3.14 / 180)
p_text[i][j] = y + text_offset_y + 1.2* r * np.sin((separation) * (i+9) * 3.14 / 180) # point for text labels, i+9 rotates the labels by 90 degrees
#add the lines and labels to the image
for i in range(0,interval):
cv2.line(img, (int(p1[i][0]), int(p1[i][1])), (int(p2[i][0]), int(p2[i][1])),(0, 255, 0), 2)
cv2.putText(img, '%s' %(int(i*separation)), (int(p_text[i][0]), int(p_text[i][1])), cv2.FONT_HERSHEY_SIMPLEX, 0.3,(0,0,0),1,cv2.LINE_AA)
cv2.imwrite('%s%s-calibration.%s' % (img_path, image_key,file_type), img)
#get user input on min, max, values, and units
# print '%s%s-calibration.%s' % (img_path, image_key,file_type)
# min_angle = raw_input('Min angle (lowest possible angle of dial) - in degrees: ') #the lowest possible angle
# max_angle = raw_input('Max angle (highest possible angle) - in degrees: ') #highest possible angle
# min_value = raw_input('Min value: ') #usually zero
# max_value = raw_input('Max value: ') #maximum reading of the gauge
# units = raw_input('Enter units: ')
#for testing purposes: hardcode and comment out raw_inputs above
# min_angle = 45
# max_angle = 320
# min_value = 0
# max_value = 200
# units = "PSI"
return x, y, r
except Exception as e:
return 0,0,0