#!/usr/bin/env python import cv2 import numpy as np import math import rospy from geometry_msgs.msg import Twist from sensor_msgs.msg import Image from cv_bridge import CvBridge, CvBridgeError frame = None bridge = None def nothing(x): pass def trackbars(): cv2.namedWindow('Tune') cv2.moveWindow('Tune',500,400) cv2.createTrackbar('HL','Tune',0,255,nothing) cv2.createTrackbar('HH','Tune',0,255,nothing) cv2.createTrackbar('SL','Tune',0,255,nothing) cv2.createTrackbar('SH','Tune',0,255,nothing) cv2.createTrackbar('VL','Tune',0,255,nothing) cv2.createTrackbar('VH','Tune',0,255,nothing) cv2.setTrackbarPos('HL','Tune',0) cv2.setTrackbarPos('HH','Tune',180) cv2.setTrackbarPos('SL','Tune',0) cv2.setTrackbarPos('SH','Tune',28) cv2.setTrackbarPos('VL','Tune',136) cv2.setTrackbarPos('VH','Tune',255) def captureNextFrame(data): global frame,bridge try: frame = bridge.imgmsg_to_cv2(data, "bgr8") except CvBridgeError as e: print(e) print "callback" #frame=cv2.cvtColor(cv_image,cv2.COLOR_BGR2RGB) def findDirection(roi,lines,side): if lines == None: if side == 0: return 10000, 0 else: return 1,-10000 avgDistX = avgDistY = avgSlope = 0 for x in range(len(lines)): for x1,y1,x2,y2 in lines[x]: avgDistX += ((x1+x2)/2) avgDistY += ((y1+y2)/2) if(x2-x1): avgSlope += (y2-y1)*1.0/(x2-x1) else: avgSlope += (y2-y1)*1.0/0.0001 avgDistX = avgDistX/len(lines) if side: avgDistX += roi.shape[1]*0.5 avgDistY = avgDistY/len(lines) avgSlope = avgSlope/len(lines) print avgSlope if avgSlope == 0: avgSlope = 0.001 if side == 0: cv2.circle(roi,(int(avgDistX),int(avgDistY)),5,(0,0,255)) cv2.line(roi,(int(-avgDistY/avgSlope + avgDistX),0),(int((roi.shape[0] - avgDistY)/avgSlope + avgDistX),roi.shape[0]),(255,0,255),2) else: cv2.line(roi,(int(-avgDistY/avgSlope + avgDistX),0),(int((roi.shape[0] - avgDistY)/avgSlope + avgDistX),roi.shape[0]),(255,255,0),2) # cv2.line(roi,(int(roi.shape[1]*0.5)+int(-avgDistY/avgSlope + avgDistX),0),(int(roi.shape[1]*0.5)+int(roi.shape[0] - avgDistY/avgSlope + avgDistX),roi.shape[0]),(0,255,0),2) return avgSlope,-avgDistX/avgSlope + avgDistY def findLines(roi,img,side): edges = cv2.Canny(img,200,200,apertureSize = 3) # cv2.imshow('Edges',edges) # cv2.moveWindow('Edges',100,400) # lines = cv2.HoughLines(edges,1,np.pi/180,50) # print lines # if lines!=None: # for x in range(len(lines)): # for rho,theta in lines[x]: # a = np.cos(theta) # b = np.sin(theta) # x0 = a*rho # y0 = b*rho # x1 = int(x0 + 1000*(-b)) # y1 = int(y0 + 1000*(a)) # x2 = int(x0 - 1000*(-b)) # y2 = int(y0 - 1000*(a)) # # if side==0: # cv2.line(roi,(x1,y1),(x2,y2),(0,255,0),2) # else: # cv2.line(roi,(int(roi.shape[1]*0.5)+x1,y1),(int(roi.shape[1]*0.5)+x2,y2),(0,0,255),2) minLineLength = 10 maxLineGap = 10 lines = cv2.HoughLinesP(edges,1,np.pi/180,1,minLineLength,maxLineGap) if lines!=None: for x in range(len(lines)): for x1,y1,x2,y2 in lines[x]: if side==0: cv2.line(roi,(x1,y1),(x2,y2),(0,255,0),2) else: cv2.line(roi,(int(roi.shape[1]*0.5)+x1,y1),(int(roi.shape[1]*0.5)+x2,y2),(0,0,255),2) return lines # lowRanges = [cv2.getTrackbarPos('HL','Tune'), cv2.getTrackbarPos('SL','Tune'), cv2.getTrackbarPos('VL','Tune') ] # highRanges = [cv2.getTrackbarPos('HH','Tune'), cv2.getTrackbarPos('SH','Tune'), cv2.getTrackbarPos('VH','Tune') ] # grayROI = cv2.cvtColor(roi,cv2.COLOR_BGR2GRAY) # ret2,binary = cv2.threshold(grayROI,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) # roiHSV = cv2.cvtColor(roi,cv2.COLOR_BGR2HSV) # binary = cv2.inRange(roiHSV,np.array(lowRanges),np.array(highRanges)) # cv2.imshow('Binary',edges) # cv2.moveWindow('Binary',100,400) def main(): global frame, bridge pause = False rospy.init_node("MotorControlPanel") velocityPub = rospy.Publisher("/cmd_vel",Twist,queue_size=1) rospy.Subscriber("/rrbot/camera1/image_raw",Image, captureNextFrame) twistMsg = Twist() bridge = CvBridge() trackbars() #vid = cv2.VideoCapture('1.avi') while(True): #if not pause: # ret, frame = vid.read() if frame==None: continue frameTemp = frame[int(0.5*frame.shape[0]):frame.shape[0],0:frame.shape[1]] cv2.imshow('Feed',frameTemp) cv2.moveWindow('Feed',100,100) roi = frameTemp.copy() roi = roi[int(0.5*roi.shape[0]):int(roi.shape[0]*0.8),0:roi.shape[1]] leftImage = roi[0:roi.shape[0],0:roi.shape[1]*0.5] rightImage = roi[0:roi.shape[0],roi.shape[1]*0.5:roi.shape[1]] cv2.imshow('Left',leftImage) linesLeft = findLines(roi,leftImage,0) linesRight = findLines(roi,rightImage,1) m1,c1 = findDirection(roi,linesLeft,0) m2,c2 = findDirection(roi,linesRight,1) print m1,c1,m2,c2 if(m1!=m2): x = (c2-c1)/(m1-m2) if x > roi.shape[1]*0.40 and x < roi.shape[1]*0.60: twistMsg.linear.x = 0.2 twistMsg.angular.z = 0 print "Forward", x/roi.shape[1] elif x <= roi.shape[1]*0.40: twistMsg.linear.x = 0.2 twistMsg.angular.z = 0.5 print "Left", x/roi.shape[1] else: twistMsg.linear.x = 0.2 twistMsg.angular.z = -0.5 print "Right", x/roi.shape[1] velocityPub.publish(twistMsg) cv2.imshow('ROI',roi) cv2.moveWindow('ROI',100,500) c = cv2.waitKey(10) if c == 27: break elif c == 112: pause = not pause if __name__=='__main__': main()