I was trying to use canny edge detection to find the angle for the camera to turn. The algorithm should works because I first takes a picture, then I use the canny edge detection to find the edges of the hallway. Then I divide the picture into slices. And then, I use the moments to find the center of mass for each of the slice. Finally, I use the linregress to find the line that best matches the points. Thus, I get the gradient for the line and thus I got the angle to turn.
However, it worked out in the first few times. But after some trial, it prints
However, it worked out in the first few times. But after some trial, it prints
Traceback (most recent call last):
File "/home/ricky/Desktop/lab_deliverable/lab6/test_pictures/hallway.py", line 234, in <module>
angle2=get_angle(output,debug) #æ¾è§åº¦
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ricky/Desktop/lab_deliverable/lab6/test_pictures/hallway.py", line 163, in get_angle
del cX_list[0]
~~~~~~~^^^
IndexError: list assignment index out of range
Code:
from picamera2 import Picamera2 import cv2 import numpy as np import timeimport mathimport argparseimport RPi.GPIO as GPIOimport matplotlib.pyplot as pltfrom scipy import statsimport osGPIO.setmode(GPIO.BOARD) PWM_pin = 32 #Define pin, frequency and duty cycle freq = 50 dutyCycle = 7.5 #90 degrees at first##Values 0 - 100 (represents 4%, ~27 deg) minv=64maxv=156angles=[90]duty1=7.2width=2592height=1944 rect1=(0,0) rect2=(640,481) x1s=[]x2s=[]y1s=[]y2s=[]x3s=[]y3s=[]cnt = 1num = 1output_folder = "sub_pictures"output_folder_2 = "sub_pictures_with_centroid"sub_images = [] cX_list=[] cY_list=[]trending=[]GPIO.setup(PWM_pin, GPIO.OUT) # Create PWM instance for pin w freqency pwm = GPIO.PWM(PWM_pin, freq) picam2 = Picamera2() parser=argparse.ArgumentParser(description="lower and upper bound for trying")parser.add_argument('--tim',default=60,help="length of time to run")parser.add_argument('--delay',default=1,help="time between image captures")parser.add_argument('--debug',action='store_true',default=False,help="debug mode")args=parser.parse_args()def small_pic(img,debug):height, width = img.shape[:2]scale = 0.5new_size = (int(width*scale), int(height*scale))img = cv2.resize(img, new_size, interpolation=cv2.INTER_LINEAR) if debug == True:cv2.imwrite(f'smalled_img{k}.jpg',img)cv2.imshow('img',img)cv2.waitKey(3000) cv2.destroyAllWindows()return imgdef get_duty(duty1,angle2):duty2=duty1+0.4*(angle2)*(1/18)duty1=duty2return duty1,duty2def get_lines(img,debug):if img is None: print("Error: Unable to load image.") exit()height, width = (img.shape[:2])def blank(x): # Null function for trackbarpassif debug ==True:print (rect1,rect2)mask = np.zeros(img.shape[:2], dtype=np.uint8)mask = cv2.rectangle(mask,rect1,rect2, 255, -1)masked_img = cv2.bitwise_and(img, img, mask=mask)img=masked_imgimg =cv2.GaussianBlur(img, (3, 3), 0)edge = cv2.Canny(img, minv, maxv)lines = cv2.HoughLinesP(edge, 1, np.pi / 180, threshold=100, minLineLength=20, maxLineGap=10)output = img.copy() # Avoid modifying the original imageif lines is not None: # Check if lines were detectedfor i in range(len(lines)):for x1, y1, x2, y2 in lines[i]:cv2.line(output, (x1, y1), (x2, y2), (0, 255, 0), 2)# print(f'x1:{x1:0.2f}\ty1:{y1:0.2f}\tx2:{x2:0.2f}\ty2:{y2:0.2f}')# x1s.append(x1)# x2s.append(x1)# y1s.append(y1)# y2s.append(y2)with open('data.txt', 'a') as f:f.write(f'{x1:0.2f}\t{y1:0.2f}\t{x2:0.2f}\t{y2:0.2f}')f.write('\n')# if debug== True:# cv2.imshow('image', img)# cv2.imshow('mask', mask)# cv2.imshow('masked_image', masked_img)# cv2.imshow("houghline", output)# cv2.imwrite('houghline.jpg',output)# cv2.waitKey(5000)# cv2.destroyAllWindows() # picam2.stop() return outputdef get_angle(output,debug):global jsrc = outputsub_image_num = 20 src_height, src_width = src.shape[0], src.shape[1] sub_height = src_height // sub_image_num sub_width = src_width #for i in range(sub_image_num): if i < sub_image_num - 1:image_roi = src[i*sub_height:(i + 1)*sub_height,:,:]else:image_roi = src[i*sub_height:,:,:]sub_images.append(image_roi) for i, img in enumerate(sub_images): if debug==True:save_path = os.path.join(output_folder, f'sub_img_{i}.png')cv2.imwrite(save_path, img)hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) #RGBHSVmask = cv2.inRange(hsv, (55, 102, 188), (60, 255, 255)) if debug==True:cv2.imshow(f'{i}th_masked',mask)cv2.waitKey(500)cv2.destroyAllWindows() M = cv2.moments(mask) if M['m00']>0:cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) cY_for_list= cY+ i*sub_heightcX_list.append(cX) cY_list.append(cY_for_list)if debug ==True:print (f"""The {i}th Centroid: ({cX}, {cY_for_list})Remember! the uppest and lowest are discarded!""") img = cv2.circle(img, (cX,cY), 5, (0,0,255), 2) # green circle save_path = os.path.join(output_folder_2, f'sub_centroid{i}.png')cv2.imwrite(save_path, img) else:if debug==True:print (f'The {i}th Centroid not found')j=j+1 #jå¢å 1if debug==True:print(f'Before: {cX_list,cY_list}')del cX_list[0]del cX_list[-1]del cY_list[0]del cY_list[-1]if debug==True:print(f'After: {cX_list,cY_list}')slope, intercept, r, p, std_err = stats.linregress(cX_list, cY_list) #angle = math.atan(1/slope)/math.pi *180 # angle of referenceif debug ==True:print(f"j:{j}\tslope:{slope:0.2f}\tintercept:{intercept:0.2f}\tangle:{angle:0.2f}") print(f'should turn {"LEFT" if angle <0 else "RIGHT"}')if -90<angle<90: #angles.append(angle) ## elif -91<=angle<=-80: ## angles.append(0) # print("found unwanted horizontal edges")# elif 80<=angle<=91: ## angles.append(0) # print("found unwanted horizontal edges")# else: ## angles.append(0) # print("angle larger than +-90 degrees, illegal")angle2=angles[j]return angle2pwm.start(dutyCycle) j=int(0)k=int(0)start_time = time.time() cur_time = start_time mesg_time = start_time while (start_time + args.tim > cur_time): time.sleep(0.001) cur_time = time.time() # some short delay to avoid busy waitsif (mesg_time + args.delay < cur_time):mesg_time = cur_timex1s=[]x2s=[]y1s=[]y2s=[]x3s=[]y3s=[]sub_images = [] #cX_list=[] #cY_list=[]#trending=[] #time_1=time.time()picam2.start()img = picam2.capture_array("main") img= cv2.cvtColor(img,cv2.COLOR_RGB2BGR) #change color debug=args.debugif debug == True:cv2.imshow("picture",img)cv2.imwrite('picture_test.jpg',img)cv2.waitKey(5000)cv2.destroyAllWindows()#from RGB to BGRk+=1# img = cv2.imread(f"test_{k}.jpg") #take picture into memoryimg = small_pic(img,debug)#output=get_lines(img,debug) #call functionangle2=get_angle(output,debug) ## if debug == True:# time_2=time.time() # print(f'time taken not including roatating servo:{time_2-time_1:0.2f}') #print the time it taken to complete # # the finding angle processduty1,duty2=get_duty(duty1,angle2) #pwm.ChangeDutyCycle(duty2) #print(duty2)picam2.stop# # if debug ==True:# # print(f'PWM:{dutyCycle}')# # else:# # pass
Statistics: Posted by ricky2777 — Wed Feb 26, 2025 1:59 am — Replies 0 — Views 56