面積を計測してLEDを光らせたい(その3)
ついに最終章?になります。始めにお断りします。あまりうまくいっていません。でも、書きます。まず、RaspberryPiにOpenCvをインストールする必要があります。いろんなところでインストール方法が紹介されていますが、おっさんは最終的に、ココを参考にしてインストールしました。OpenCvのインストールが完了したら、前回のコードに以下のように追記します。import RPi.GPIO as GPIOimport cv2import numpy as npimport picamerafrom time import sleepLED1_GPIO = 21 LED2_GPIO = 27LED3_GPIO = 4TACT_GPIO = 17GPIO.setmode(GPIO.BCM)GPIO.setup(LED1_GPIO, GPIO.OUT)GPIO.setup(LED2_GPIO, GPIO.OUT)GPIO.setup(LED3_GPIO, GPIO.OUT)GPIO.setup(TACT_GPIO, GPIO.IN)try: while True: if GPIO.input(TACT_GPIO) == GPIO.HIGH: GPIO.output(LED3_GPIO, GPIO.LOW) sleep(0.01) break else: GPIO.output(LED3_GPIO, GPIO.HIGH) GPIO.output(LED1_GPIO, GPIO.LOW) GPIO.output(LED2_GPIO, GPIO.LOW) with picamera.PiCamera() as camera: camera.resolution=(640,480) camera.capture("area.jpg") aruco=cv2.aruco p_dict=aruco.getPredefinedDictionary(aruco.DICT_4X4_50) img = cv2.imread('area.jpg') corners, ids, rejectedImgPoints = aruco.detectMarkers(img, p_dict) img_marked = aruco.drawDetectedMarkers(img.copy(), corners, ids) img_marked_rgb=cv2.cvtColor(img_marked,cv2.COLOR_BGR2RGB) corners2 = [np.empty((1,4,2))]*4 for i,c in zip(ids.ravel(), corners): corners2[i] = c.copy() m = np.empty((4,2)) m[0] = corners2[0][0][2] m[1] = corners2[1][0][3] m[2] = corners2[2][0][0] m[3] = corners2[3][0][1] marker_coordinates = np.float32(m) np.float32(m) h1=((corners2[0][0][2][0]-corners2[3][0][1][0])**2+(corners2[0][0][2][1]-corners2[3][0][1][1])**2)**0.5 h2=((corners2[2][0][0][0]-corners2[1][0][3][0])**2+(corners2[2][0][0][1]-corners2[1][0][3][1])**2)**0.5 hhh=(h1+h2)/2 w1=((corners2[0][0][2][0]-corners2[1][0][3][0])**2+(corners2[0][0][2][1]-corners2[1][0][3][1])**2)**0.5 w2=((corners2[2][0][0][0]-corners2[3][0][1][0])**2+(corners2[2][0][0][1]-corners2[3][0][1][1])**2)**0.5 www=(w1+w2)/2 width, height = (int(www),int(hhh)) true_coordinates = np.float32([[0,0],[width,0],[width,height],[0,height]]) trans_mat = cv2.getPerspectiveTransform(marker_coordinates,true_coordinates) img_trans = cv2.warpPerspective(img,trans_mat,(width, height)) img_trans_rgb=cv2.cvtColor(img_trans,cv2.COLOR_BGR2RGB) img_trans_gray=cv2.cvtColor(img_trans,cv2.COLOR_BGR2GRAY) img_trans_gray_rgb=cv2.cvtColor(img_trans_gray,cv2.COLOR_GRAY2RGB) _,p_binary=cv2.threshold(img_trans_gray,70,255,cv2.THRESH_BINARY) p_binary_rgb=cv2.cvtColor(p_binary,cv2.COLOR_GRAY2RGB) p_binary=cv2.bitwise_not(p_binary) p_contours,_=cv2.findContours(p_binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) p_and_contours=np.copy(img_trans) min_p_area=60 large_contours=[cnt for cnt in p_contours if cv2.contourArea(cnt)>min_p_area] draw_p=cv2.drawContours(p_and_contours,large_contours,-1,(0,255,0)) sarea=0 for i, cnts in enumerate(large_contours): area = cv2.contourArea(cnts) sarea=sarea+area pm_area=sarea*(4.4*7)/(www*hhh) if pm_area >=20: GPIO.output(LED1_GPIO, GPIO.HIGH) GPIO.output(LED2_GPIO, GPIO.LOW) sleep(1) else: GPIO.output(LED1_GPIO, GPIO.LOW) GPIO.output(LED2_GPIO, GPIO.HIGH) sleep(1)except KeyboardInterrupt: passfinally: GPIO.cleanup()以前した面積計測を実装したものになります。内容としては、物体の面積を計測し、20cm以上なら赤のLEDを光らせ、それ以下ならば緑のLEDが光るようにしています。点灯時間はとりあえず1秒にしてそれをボタンを押すまで繰り返すようにしています。実際に、Thonnyを開き実行してみました。大きなピーマンを載せたら赤のLEDが光りました。小さなピーマンを載せたら緑のLEDが光りました。(見えづらくてすみません。)うまく判断しているのですが、ここで四隅のマークがない、もしくは隠れるとエラーになります。また、RaspberryPi起動時に自動実行するとこれもうまく動作しませんでした。う~ん。もう少しなんだが・・・・・