前提
ここに質問の内容を詳しく書いてください。
(例)
画像認識をtelloを介して行う方法について
実現したいこと
ここに実現したいことを箇条書きで書いてください。
Webカメラを利用して起動する画像認識アプリを作成して、そのアプリをトイドローン(TELLO)を利用して使用できるようにしたい
発生している問題・エラーメッセージ
None
Traceback (most recent call last):
File "C:\Users\kamla\PycharmProjects\edit_program_research\total_research_project\AkiKon.py", line 158, in <module>
main()
File "C:\Users\kamla\PycharmProjects\edit_program_research\total_research_project\AkiKon.py", line 119, in main
width = int(picture.shape[1] * 50 / 100) # 画像幅
AttributeError: 'NoneType' object has no attribute 'shape'
該当のソースコード
Python
import cv2
import mediapipe as mp
import numpy as np
import socket
import streamlit as st
import time
from concurrent.futures import ProcessPoolExecutor
import drone_manager
import face_detect_video
import face_detect_myself as fm
import mediapipe_module as mymp
from djitellopy import tello
drone = tello.Tello()
drone.connect()
print(drone.get_battery())
drone.streamon()
capture = drone.get_video_capture()
capture = cv2.VideoCapture(0)
face_vgg = fm.Face_detector()
mymediapipe = mymp.poseDetector()
img_count_total = 0
img_count = 10
count = 0
w, h = 360, 240
fbRange = [6200, 6800]
pid = [0.4, 0.4, 0.4]
pError = 0
angle = 0
def findface(img):
faceCascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(imgGray, 1.2, 8)
myFacelistC = []
myFaceListArea = []
for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2) cx = x + w // 2 cy = y + h // 2 area = w * h cv2.circle(img, (cx, cy), 5, (0, 255, 0), cv2.FILLED) myFacelistC.append([cx, cy]) myFaceListArea.append(area) if len(myFaceListArea) != 0: i = myFaceListArea.index(max(myFaceListArea)) return img, [myFacelistC[i], myFaceListArea[i]] else: return img, [[0, 0], 0]
def trackFace1(info, w, pid, pError):
area = info[1]
x, y = info[0]
fb = 0
error = x - w // 2 speed = pid[0] * error + pid[1] * (error -pError) speed = int(np.clip(speed, -100, 100)) if area > fbRange[0] and fbRange[1]: fb = 0 elif area > fbRange[1]: fb = -20 elif area < fbRange[0] and area != 0: fb = 20 print(speed, fb) if x == 0: speed = 0 error = 0 # drone.send_rc_control(0, fb, 0, speed) return error
def trackFace2(info, w, pid, pError):
area = info[1]
x, y = info[0]
fb = 0
error = x - w // 2 speed = pid[0] * error + pid[1] * (error -pError) speed = int(np.clip(speed, -100, 100)) if angle > 200: print("ATTACK_POSSIBLE") fb = -20 print(speed, fb) if x == 0: speed = 0 error = 0 # drone.send_rc_control(0, fb, 0, speed) return error
def main():
tello_flying_flag = 0
ggez = 0
while True:
# capture = drone.get_frame_read().frame
print(type(capture))
success, picture = capture.read()
print(picture)
width = int(picture.shape[1] * 50 / 100) # 画像幅
height = int(picture.shape[0] * 50 / 100) # 画像高さ
dim = (width, height) # 画像サイズ
picture = cv2.resize(picture, dim, interpolation=cv2.INTER_AREA) # カラー画像をリサイズ
picture = mymediapipe.findPose(picture, False)
keypoint = mymediapipe.findPosition(picture, False)
img = face_vgg.face_detect(capture, img_count_total, img_count, ggez) ggez += 1 if tello_flying_flag == 0: # drone.takeoff() tello_flying_flag += 1 print("take_off") akikon2 = mymediapipe.findPose(img) if len(keypoint) != 0: # ここに腕の角度が返されています face_area, info = findface(picture) angle = mymediapipe.findAngle(picture, 5, 12, 14) per = np.interp(angle, (210, 310), (0, 100)) bar = np.interp(angle, (220, 310), (650, 100)) print(info) # pError = trackFace1(info, w, pid, pError) # pError = trackFace2(info, w, pid, pError) cv2.imshow("Angle", picture) cv2.imshow('AkiKon2', akikon2) cv2.waitKey(1) # if cv2.waitKey(1) & 0xFF == ord('q'): # drone.land
if name == 'main':
main()
以下 サードパーティーlibraryの使用している部分 """Library for interacting with DJI Ryze Tello drones. """ def get_udp_video_address(self) -> str: """Internal method, you normally wouldn't call this youself. """ address_schema = 'udp://@{ip}:{port}' # + '?overrun_nonfatal=1&fifo_size=5000' address = address_schema.format(ip=self.VS_UDP_IP, port=self.VS_UDP_PORT) return address def get_video_capture(self): """Get the VideoCapture object from the camera drone. Users usually want to use get_frame_read instead. Returns: VideoCapture """ if self.cap is None: self.cap = cv2.VideoCapture(self.get_udp_video_address()) if not self.cap.isOpened(): self.cap.open(self.get_udp_video_address()) return self.cap def get_frame_read(self) -> 'BackgroundFrameRead': """Get the BackgroundFrameRead object from the camera drone. Then, you just need to call backgroundFrameRead.frame to get the actual frame received by the drone. Returns: BackgroundFrameRead """ if self.background_frame_read is None: address = self.get_udp_video_address() self.background_frame_read = BackgroundFrameRead(self, address) # also sets self.cap self.background_frame_read.start() return self.background_frame_read 文字数の関係で一部を抜粋して記述しています。 telloとの接続はできているのでaddressの間違いはないと思います。 ### 試したこと まずは起動することだけを目的としてWebカメラで起動するように作成して、動作を確認することができた。 cv2.videocaptureの部分をサードパーティーのget_video_captureを利用してしようとしたが"picture"の中がNoneとなってしまい 中身が格納されないです。Webカメラの場合は代入されているがtelloを利用した際にはNoneとなるのを解決したいです。 ご協力のお程よろしくお願いします。 ### 補足情報(FW/ツールのバージョンなど) ここにより詳細な情報を記載してください。
あなたの回答
tips
プレビュー