# 視覺教學 ### OpenCV install ```python $ sudo apt update $ sudo apt install libopencv-dev python3-opencv ``` #### verify installation ```python $ python3 -c "import cv2; print(cv2.__version__)" ``` ### OpenCV tutorial ```python import cv2 import numpy as np import matplotlib.pyplot as plt ``` #### read image from file ```python image = cv2.imread('./ball1.jpg') ``` #### show image in window ```python cv2.imshow('Image Window',image) cv2.waitKey(0) cv2.destroyAllWindows() ``` #### show image in pyplot ```python def plot(image): # cv2 reads image in BGR format, pyplot reads image in RGB format RGB_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) plt.imshow(RGB_image) plt.show() ``` #### save image ```python cv2.imwrite('./image/output.jpg', image) ``` #### image size ```python image.shape[:] # returns (height,width,tunnel) ``` #### Connect with camera ```python cap = cv2.VideoCapture(2) # choose camera index while cap.isOpened(): # 從攝影機擷取一張影像 ret, img = cap.read() cv2.imshow('image', img) # 若 q 被按下則離開迴圈 if cv2.waitKey(1) & 0xFF == ord('q'): cap.release() # 釋放攝影機 cv2.destroyAllWindows() # 關閉所有視窗 break ``` --- ### Image processing #### - Convert image to grayscale ```python gray_image = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) ``` #### - Gaussian Blur Note: 做高斯模糊的圖片能夠去除很多圖片的雜訊,能更精準的找到輪廓。 ```python kernel_size = 17 # 進行高斯模糊時,對多大的範圍進行運算 blurred_image = cv2.GaussianBlur(image,(kernel_size,kernel_size),0) ``` --- ## OpenCV Example ### Objective: Find location of ball #### Method 1 : Canny edge detection 進行邊緣檢測 ```python def canny(image,low,high): low_threshold = low high_threshold = high edges = cv2.Canny(image, low_threshold, high_threshold) return edges ``` Note: - 高於 high_threshold: 為 strong edge ,直接保留 - 低於 low_threshold: 不當作 edge - 介於 low_threshold & high_threshold: 為 weak edge ,Canny會檢測 weak edge 是否能與 strong edge 相連,如果會相連的才會被保留。 #### Procedure 1. Convert image to grayscale 2. Gaussian blur 3. Canny detection 4. Find contours ```python def canny_detection(image): gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blurred_image = cv2.GaussianBlur(gray_image, (21,21), 0) canny_image = cv2.Canny(blurred_image,50,60) plot(canny_image) # find contours contours, hierarchy = cv2.findContours(image=canny_image,mode=cv2.RETR_EXTERNAL,method=cv2.CHAIN_APPROX_NONE) for contour in contours: # gives area of contour area = cv2.contourArea(contour) # gives perimeter of contour perimeter = cv2.arcLength(contour, closed=True) # approximate boundaries for given polygon contour borders = cv2.approxPolyDP(curve=contour,epsilon=0.1*perimeter,closed=True) if len(borders)>3: x, y, w, h = cv2.boundingRect(borders) cv2.rectangle(image,(x,y),(x+w,h+y),(255,255,255),5) # draw rectangle borders of circle centroid =(int(x+w/2),int(y+h/2)) cv2.circle(image, centroid ,1,(0,0,0),10) # draw center of circle print("Centroid:" + str(centroid)) return image ``` ```python image = cv2.imread('./image/ball1.jpg') img = canny_detection(image) plot(img) ``` #### Method 2 : Hough Circle #### Procedure 1. Convert image to grayscale 2. Gaussian blur 3. Canny detection (optional) 4. Apply Hough transform ```python def hough(image): # Convert to grayscale. gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blurred_image = cv2.GaussianBlur(gray_image, (17,17),0) canny_image = cv2.Canny(blurred_image,80,95) circles = cv2.HoughCircles(image=canny_image,method=cv2.HOUGH_GRADIENT,dp=1, minDist=30, param1 = 70,param2 = 30, minRadius = 40, maxRadius = 400) if circles is not None: # Convert the circle parameters x, y and r to integers. circles = np.uint16(np.around(circles)) for circle in circles[0, :]: x, y, r = circle[0], circle[1], circle[2] # Draw the circumference of the circle. cv2.circle(image, (x,y), r, (0, 0, 255), 7) # draw circumference of circle cv2.circle(image, (x,y), 1, (0, 0, 255), 5) # draw center of circle print("Centroid: "+str((a,b))) return image ``` ```python image = cv2.imread('./image/ball1.jpg') img = hough(image) plot(img) ```