Add consistent error and info messages, tweak image blurring. Remove penny requirement.

video
Cole Deck 4 years ago
parent 4ca4d0c3cd
commit 4eac873412

Binary file not shown.

@ -10,15 +10,21 @@ pwm = gpio.PWM(13, 100)
pwm.start(13)
verbose = True
print("Initializing Grbl...")
print("[ INFO ] Initializing Grbl...")
ser.write(b'\r\n\r\n')
time.sleep(2)
ser.write(b'$RST=#\n')
time.sleep(1)
ser.flushInput()
print("[ INFO ] Grbl is ready.")
def goToBin(bin):
print("[ INFO ] Delivering item to bin: " + str(bin))
adjustedBin = math.floor(bin / 2)
if adjustedBin > 11:
print("[ INFO ] All bins full! Using overflow bin.")
bin = 0;
adjustedBin = 0;
distance = adjustedBin * 18
delay = 0.5 + 0.93 * adjustedBin
command = 'G0 X-'
@ -26,37 +32,40 @@ def goToBin(bin):
command += '\n'
ser.write(b'$X\n')
time.sleep(1)
print(command)
print("[ INFO ] Sending command to Grbl: " + command)
ser.write(command.encode('utf-8'))
# s.write("$C\n")
while True:
grbl_out = str(ser.readline().strip()) # Wait for grbl response with carriage return
print(grbl_out.find('error'))
if int(grbl_out.find('error')) >= 0 :
print("REC:",grbl_out)
print(" Grbl reported error!")
print("[ EXIT ] Grbl reported an error.")
quit()
elif int(grbl_out.find('ok')) >= 0 :
if verbose: print('REC:',grbl_out)
if verbose: print('[ INFO ] Grbl message: ',grbl_out)
break
print("[ INFO ] Waiting for " + str(delay) + " seconds.")
time.sleep(delay)
if bin % 2 == 0: # tilt to left
print("[ INFO ] Titling motor to left side.")
pwm.ChangeDutyCycle(5)
time.sleep(1)
pwm.ChangeDutyCycle(14)
else:
print("[ INFO ] Titling motor to right side.")
pwm.ChangeDutyCycle(25)
time.sleep(1)
pwm.ChangeDutyCycle(13)
time.sleep(1)
print("[ INFO ] Sending command to Grbl: G0 X0")
ser.write(b'G0 X0\n')
while True:
grbl_out = str(ser.readline().strip()) # Wait for grbl response with carriage return
if int(grbl_out.find('error')) >= 0 :
print("REC:",grbl_out)
print(" Grbl reported error!")
print("[ EXIT ] Grbl reported an error.")
quit()
elif int(grbl_out.find('ok')) >= 0 :
if verbose: print('REC:',grbl_out)
if verbose: print('[ INFO ] Grbl message: ',grbl_out)
break
print("[ INFO ] Waiting for " + str(delay) + " seconds.")
time.sleep(delay)

@ -4,4 +4,4 @@ pixels = neopixel.NeoPixel(board.D18, 24)
def ledOff():
pixels.fill((0,0,0))
def ledOn():
pixels.fill((50,50,50))
pixels.fill((0,0,0))

@ -98,7 +98,7 @@ def detect(calibration_width, img_file, show, quick):
cv2.waitKey(0)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (7, 7), 0)
gray = cv2.GaussianBlur(gray, (7, 7), 0)
# perform edge detection, then perform a dilation + erosion to
# close gaps in between object edges
edged = cv2.Canny(gray, 50, 100)
@ -107,6 +107,8 @@ def detect(calibration_width, img_file, show, quick):
edged = cv2.dilate(edged, None, iterations=1)
edged = cv2.erode(edged, None, iterations=1)
edged = cv2.dilate(edged, None, iterations=1)
#edged = cv2.erode(edged, None, iterations=1)
#edged = cv2.dilate(edged, None, iterations=1)
if show and not quick:
cv2.imshow("Item Sorter", edged)
cv2.waitKey(0)
@ -122,6 +124,7 @@ def detect(calibration_width, img_file, show, quick):
num = 0
# Calibration loop
"""
for c in cnts:
# if the contour is not sufficiently large, ignore it
if cv2.contourArea(c) < 100:
@ -170,8 +173,8 @@ def detect(calibration_width, img_file, show, quick):
# and near(mean_val[0], 63, 40) is True and near(mean_val[1], 108, 40) is True and near(mean_val[2], 104, 40) is True:
pixelsPerMetric = smaller(dA, dB) / calibration_width
continue
#pixelsPerMetric = 25
"""
pixelsPerMetric = 25
orig = image.copy()
objtype = "Unknown"
objname = ""
@ -181,42 +184,22 @@ def detect(calibration_width, img_file, show, quick):
num += 1
# if the contour is not sufficiently large, ignore it
#pixelsPerMetric = 75
if cv2.contourArea(c) < 100 or pixelsPerMetric is None:
if cv2.contourArea(c) < 300 or pixelsPerMetric is None:
continue
# compute the rotated bounding box of the contour
box = cv2.minAreaRect(c)
box = cv2.cv.BoxPoints(box) if imutils.is_cv2() else cv2.boxPoints(box)
box = np.array(box, dtype="int")
# order the points in the contour such that they appear
# in top-left, top-right, bottom-right, and bottom-left
# order, then draw the outline of the rotated bounding
# box
#box = perspective.order_points(box)
# loop over the original points and draw them
# for (x, y) in box:
#cv2.circle(orig, (int(x), int(y)), 5, (0, 0, 255), -1)
# unpack the ordered bounding box, then compute the midpoint
# between the top-left and top-right coordinates, followed by
# the midpoint between bottom-left and bottom-right coordinates
(tl, tr, br, bl) = box
(tltrX, tltrY) = midpoint(tl, tr)
(blbrX, blbrY) = midpoint(bl, br)
# compute the midpoint between the top-left and top-right points,
# followed by the midpoint between the top-right and bottom-right
(tlblX, tlblY) = midpoint(tl, bl)
(trbrX, trbrY) = midpoint(tr, br)
# draw the midpoints on the image
#cv2.circle(orig, (int(tltrX), int(tltrY)), 5, (255, 0, 0), -1)
#cv2.circle(orig, (int(blbrX), int(blbrY)), 5, (255, 0, 0), -1)
#cv2.circle(orig, (int(tlblX), int(tlblY)), 5, (255, 0, 0), -1)
#cv2.circle(orig, (int(trbrX), int(trbrY)), 5, (255, 0, 0), -1)
# draw lines between the midpoints
# compute the Euclidean distance between the midpoints
dA = np.linalg.norm(np.array((tltrX, tltrY, 0)) -
np.array((blbrX, blbrY, 0)))
@ -255,7 +238,7 @@ def detect(calibration_width, img_file, show, quick):
if circular and itemwr == 0.75:
objtype = "Penny"
iteml = 0
else:
"""else:
if circular and near(radius * 2 / pixelsPerMetric, 0.4, 0.03):
# Keps nut or spacer
@ -298,6 +281,7 @@ def detect(calibration_width, img_file, show, quick):
if itemhr == 0.1875 and rectangular:
objtype = "Axle"
iteml = (radius * 2 / pixelsPerMetric + itemw) / 2
"""
rows, cols = orig.shape[:2]
[vx, vy, xx, yy] = cv2.fitLine(c, cv2.DIST_L2, 0, 0.01, 0.01)
lefty = int((-xx*vy/vx) + yy)
@ -337,7 +321,7 @@ def detect(calibration_width, img_file, show, quick):
0.6, (50, 50, 220), 2)
output = ""
objname = objtype;
"""
if objtype == "Screw" or objtype == "Standoff":
output = str(iteml) + "in"
objname += str(iteml)
@ -345,6 +329,7 @@ def detect(calibration_width, img_file, show, quick):
output = "{:.2f}in".format(iteml)
objname += str(itemwr)
#print(objname)
"""
list.append(objname)
if circular:
cv2.putText(orig, output, # print data
@ -385,8 +370,8 @@ def magicSort(contour):
name += ", " + str(abs(int(humoments[i][0])))
#magicNumber2 += abs(humoments[i][0])
#magicNumber += humoments[i][0]
print(str(humoments))
#print(str(humoments))
#print(magicNumber)
#name = "Unknown: " + str(int(magicNumber1)) + ", " + str(int(magicNumber2))
print(name)
#print(name)
return name

@ -15,13 +15,13 @@ while True:
data = s.recv(1024)
#control_pixel.ledOn()
if not data: break
print("Found "+str(data))
print("[ INFO ] Item name: "+ str(data)[2:len(str(data))-1])
selectedBin = sort.sort(str(data)[2:len(str(data))-1])
control_pixel.ledOff()
control_motor.goToBin(selectedBin)
control_pixel.ledOn()
s.sendall(b'Continue')
except socket.error:
print("Error Occured.")
print("[ EXIT ] Socket connection error.")
break
s.close()

@ -30,11 +30,11 @@ def go():
#control_motor.goToBin(selectedBin)
def sendString(string):
print("Found " + string)
print("[ INFO ] Item found: " + string)
try:
conn.sendall(string.encode('utf-8'))
except socket.error:
print("Error Occured.")
print("[ EXIT ] Socket connection error.")
if not video:
@ -49,22 +49,22 @@ else :
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#s.setsockopt(s, socket.SOL_SOCKET, socket.SO_REUSEADDR)
s.bind((host, port))
print("waiting for connection")
print("[ INFO ] TCP stream initialized. Waiting for client...")
s.listen(1)
conn, addr = s.accept()
print('Connected to', addr)
print('[ INFO ] Connected to ', addr)
time.sleep(2)
waitForPi = True
while waitForPi is True:
try:
print("waiting for data")
print("[ INFO ] Waiting for confirmation message.")
data = conn.recv(1024)
if not data: break
encoding = 'utf-8'
print ("Client: "+str(data))
print ("[ INFO ] Message recieved: "+str(data))
waitForPi = False
except socket.error:
print("Error Occured.")
print("[ EXIT ] Socket connection error.")
break
# server command for imx135 camera ./video2stdout | gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=192.168.43.152 port=5001
# server command for udp: ./video2stdout | gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=10 pt=96 ! udpsink host=192.168.43.40 port=9000
@ -75,7 +75,7 @@ else :
ret = capture.grab()
x+=1
if not ret:
print('empty frame')
print('[ EXIT ] Empty frame received.')
break
#print('frame')
if x > 1:
@ -84,13 +84,13 @@ else :
items,output = detect.detect(calibration_width, frame, True, True)
cv2.imshow('Item Sorter', output)
x = 0
if "Penny" in items and len(items) > 1:
items.remove("Penny")
if len(items) > 0:
#items.remove("Penny")
itema = items[0]
valid = True
for item in items:
if item != itema:
print("Too many items!")
print("[ INFO ] More than one object present.")
valid = False
break
if valid:
@ -113,10 +113,12 @@ else :
waitForPi = False
capture = cv2.VideoCapture('udpsrc port=9000 caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264" ! rtph264depay ! avdec_h264 ! videoconvert ! appsink sync=false', cv2.CAP_GSTREAMER)
except socket.error:
print("Error Occured.")
print("[ EXIT ] Socket connection error.")
break
if cv2.waitKey(1)&0xFF == ord('q'):
print("[ EXIT ] Shutting down.")
s.shutdown(1)
s.close()
break

Loading…
Cancel
Save