Tello の画像をOpenCVでPCに写してみる!!OpenCVの導入方法
Tello の画像をOpenCVでPCに写してみる!!OpenCVの導入方法

Tello の画像をOpenCVでPCに写してみる!!OpenCVの導入方法

いよいよ面白くなりTelloを飛ばすことはできましたが、本来の機能であるカメラ画像の送信が生かされていない( ;∀;)

まだお持ちでない方、2台目希望の方 プログラミングドローン ”Tello” の購入はこちら

ドローンのプログラミングでどうやって画像をPCに送信したらいいだろう? YouTubeをたまたまみていたTechの部屋に出会いました。しかし私はプログラミング初心者でしかもTechの部屋のPCはMAC かなり勉強になりましたが、私はPCはWindowsでしたので、参考にして我流でしてみました。オープンソースGitHub Tech の部屋「Pythonで小型ドローン Tello EDU を飛ばす!」サンプルプログラムからダウンロードできます。

まずOpenCvのダウンロードからです。


OpenCV(正式名称: Open Source Computer Vision Libraryとはオープンソースコンピューター・ビジョン・ライブラリです。コンピューターで画像や動画を処理するのに必要な、さまざま機能が実装されており、BSDライセンスで配布されていることから学術用途だけでなく商用目的でも利用できます。加えて、マルチプラットフォーム対応されているため、幅広い場面で利用されていることが特徴です。

画像処理 (Image Processing)構造解析 (Structural Analysis)モーション解析と物体追跡 (Motion Analysis and Object Tracking)物体検出 (Object Detection)などが可能です。

OpenCvのダウンロード

リリースのウインドウズをクリックしダウンロードします。ダウンロードしたら展開してopencvのフォルダーをCドライブの直下に置きます。OPENCVのファイルの中のbild→x64→vc15→binを開きこのアドレスをコピーし、コントロールパネルから

システム&セキュリティのシステム環境変数に追加するため、Pathに先ほどコピーしたアドレスを追加します。

pythonでopencvを使いたいので opencv-pythonpipを使用してインストールできます。

インストールする場合は以下のコマンドを使用します。

pip install opencv-python

コマンドプロンプトからですがアプリの右クリックで管理者として実行で起動させます。

オープンソースGitHub Tech の部屋「Pythonで小型ドローン Tello EDU を飛ばす!」サンプルプログラムからダウンロードしたファイル cli.py(先のTello3.pyと同じプログラム) & vc.py(画像送信プログラム)

OpenCVが使われている箇所を強調してみました。

#vc.pyの内容は以下の通りです。

Tello Python3 Control Demo

http://www.ryzerobotics.com/

1/1/2018

Modified by MPS

#

import threading
import socket
import time
import cv2                  ⇒ ここでOpenCVがインポートされている

host = ”
port = 9000
locaddr = (host, port)

Create a UDP socket

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

tello_address = (‘192.168.10.1’, 8889)

sock.bind(locaddr)

def recv():
while True:
try:
data, server = sock.recvfrom(1518)
print(data.decode(encoding=”utf-8″))
except Exception:
print(‘\nExit . . . RECV\n’)
break

print(‘\r\n\r\nTello Python3 Demo.\r\n’)

print(‘Tello: command takeoff land flip forward back left right \r\n up down cw ccw speed speed?\r\n’)

print(‘end — quit demo.\r\n’)

recvThread create

recvThread = threading.Thread(target=recv)
recvThread.start()

sock.sendto(b’command’, tello_address)
print(‘command ok’)
time.sleep(0.5)
sock.sendto(b’streamon’, tello_address)
print(‘stream on’)
time.sleep(1)
sock.close()

cap = cv2.VideoCapture(“udp://%s:%s?overrun_nonfatal=1&fifo_size=50000000” % (‘192.168.10.1’, ‘11111’))       #ここでビデをキャプチャーでTelloのカメラから画像受信

print(‘start cap’)
while True:
try:
ret, frame = cap.read()
if ret:
cv2.imshow(‘tello’, cv2.resize(frame, (360, 240)))     #受信画像を画面表示
cv2.waitKey(1)
except KeyboardInterrupt:
cv2.destroyAllWindows()
cap.release()
print(‘\nExit . . .\n’)
break


をデスクトップでも貼り付けます。

あとは 各ファイルを実行できるようにコマンドプロンプトを2つ起動させます。

それでは、準備が整いましたので 2つのプログラムを同時に実行させてみます。動画をとってますので御覧ください。

次にOpenCvによる顔認識の仕方こちらへどうぞ!!

PCでOpenCVでと顔認識して遊んででみる。

トレンドアイテム60万点以上 | ファッションブランド【SHEIN】

youtubeチャンネル登録お願いいたします(^^♪

このエラーメッセージは WordPress の管理者にだけ表示されます

エラー: 接続されたアカウントがありません。

アカウントを接続するには、YouTube Feeds の設定ページに移動してください。

  • PRIVACY POLICY Last updated September 29, 2025 This Pri…

    PRIVACY POLICY

    Last updated September 29, 2025



    This Privacy Notice for __________ (we,” “us,” or “our), describes how and why we might access, collect, store, use, and/or share (process) your personal information when you use our services (Services), including when you:
  • Download and use our mobile application (Telloコマンドコントローラー), or any other application of ours that links to this Privacy Notice
  • Engage with us in other related ways, including any sales, marketing, or events
Questions or concerns? Reading this Privacy Notice will help you understand your privacy rights and choices. We are responsible for making decisions about how your personal information is processed. If you do not agree with our policies and practices, please do not use our Services.


SUMMARY OF KEY POINTS

This summary provides key points from our Privacy Notice, but you can find out more details about any of these topics by clicking the link following each key point or by using our table of contents below to find the section you are looking for.

What personal information do we process? When you visit, use, or navigate our Services, we may process personal information depending on how you interact with us and the Services, the choices you make, and the products and features you use. Learn more about personal information you disclose to us.

Do we process any sensitive personal information? Some of the information may be considered “special” or “sensitive” in certain jurisdictions, for example your racial or ethnic origins, sexual orientation, and religious beliefs. We do not process sensitive personal information.

Do we collect any information from third parties? We do not collect any information from third parties.

How do we process your information? We process your information to provide, improve, and administer our Services, communicate with you, for security and fraud prevention, and to comply with law. We may also process your information for other purposes with your consent. We process your information only when we have a valid legal reason to do so. Learn more about how we process your information.

In what situations and with which parties do we share personal information? We may share information in specific situations and with specific third parties. Learn more about when and with whom we share your personal information.

How do we keep your information safe? We have adequate organizational and technical processes and procedures in place to protect your personal information. However, no electronic transmission over the internet or information storage technology can be guaranteed to be 100% secure, so we cannot promise or guarantee that hackers, cybercriminals, or other unauthorized third parties will not be able to defeat our security and improperly collect, access, steal, or modify your information. Learn more about how we keep your information safe.

What are your rights? Depending on where you are located geographically, the applicable privacy law may mean you have certain rights regarding your personal information. Learn more about your privacy rights.

How do you exercise your rights? The easiest way to exercise your rights is by submitting a data subject access request, or by contacting us. We will consider and act upon any request in accordance with applicable data protection laws.

Want to learn more about what we do with any information we collect? Review the Privacy Notice in full.


TABLE OF CONTENTS

 
 
 


1. WHAT INFORMATION DO WE COLLECT?

Personal information you disclose to us

In Short: We collect personal information that you provide to us.

We collect personal information that you voluntarily provide to us when you express an interest in obtaining information about us or our products and Services, when you participate in activities on the Services, or otherwise when you contact us.

Personal Information Provided by You. The personal information that we collect depends on the context of your interactions with us and the Services, the choices you make, and the products and features you use. The personal information we collect may include the following:
  • email addresses
Sensitive Information. We do not process sensitive information.

All personal information that you provide to us must be true, complete, and accurate, and you must notify us of any changes to such personal information.

2. HOW DO WE PROCESS YOUR INFORMATION?

In Short: We process your information to provide, improve, and administer our Services, communicate with you, for security and fraud prevention, and to comply with law. We may also process your information for other purposes with your consent.

We process your personal information for a variety of reasons, depending on how you interact with our Services, including:


3. WHEN AND WITH WHOM DO WE SHARE YOUR PERSONAL INFORMATION?

In Short: We may share information in specific situations described in this section and/or with the following third parties.

We may need to share your personal information in the following situations:
  • Business Transfers. We may share or transfer your information in connection with, or during negotiations of, any merger, sale of company assets, financing, or acquisition of all or a portion of our business to another company.

4. HOW LONG DO WE KEEP YOUR INFORMATION?

In Short: We keep your information for as long as necessary to fulfill the purposes outlined in this Privacy Notice unless otherwise required by law.

We will only keep your personal information for as long as it is necessary for the purposes set out in this Privacy Notice, unless a longer retention period is required or permitted by law (such as tax, accounting, or other legal requirements).

When we have no ongoing legitimate business need to process your personal information, we will either delete or anonymize such information, or, if this is not possible (for example, because your personal information has been stored in backup archives), then we will securely store your personal information and isolate it from any further processing until deletion is possible.

5. HOW DO WE KEEP YOUR INFORMATION SAFE?

In Short: We aim to protect your personal information through a system of organizational and technical security measures.

We have implemented appropriate and reasonable technical and organizational security measures designed to protect the security of any personal information we process. However, despite our safeguards and efforts to secure your information, no electronic transmission over the Internet or information storage technology can be guaranteed to be 100% secure, so we cannot promise or guarantee that hackers, cybercriminals, or other unauthorized third parties will not be able to defeat our security and improperly collect, access, steal, or modify your information. Although we will do our best to protect your personal information, transmission of personal information to and from our Services is at your own risk. You should only access the Services within a secure environment.

6. WHAT ARE YOUR PRIVACY RIGHTS?

In Short:  You may review, change, or terminate your account at any time, depending on your country, province, or state of residence.

Withdrawing your consent: If we are relying on your consent to process your personal information, which may be express and/or implied consent depending on the applicable law, you have the right to withdraw your consent at any time. You can withdraw your consent at any time by contacting us by using the contact details provided in the section HOW CAN YOU CONTACT US ABOUT THIS NOTICE? below.

However, please note that this will not affect the lawfulness of the processing before its withdrawal nor, when applicable law allows, will it affect the processing of your personal information conducted in reliance on lawful processing grounds other than consent.

7. CONTROLS FOR DO-NOT-TRACK FEATURES

Most web browsers and some mobile operating systems and mobile applications include a Do-Not-Track (“DNT”) feature or setting you can activate to signal your privacy preference not to have data about your online browsing activities monitored and collected. At this stage, no uniform technology standard for recognizing and implementing DNT signals has been finalized. As such, we do not currently respond to DNT browser signals or any other mechanism that automatically communicates your choice not to be tracked online. If a standard for online tracking is adopted that we must follow in the future, we will inform you about that practice in a revised version of this Privacy Notice.

8. DO WE MAKE UPDATES TO THIS NOTICE?

In Short: Yes, we will update this notice as necessary to stay compliant with relevant laws.

We may update this Privacy Notice from time to time. The updated version will be indicated by an updated “Revised” date at the top of this Privacy Notice. If we make material changes to this Privacy Notice, we may notify you either by prominently posting a notice of such changes or by directly sending you a notification. We encourage you to review this Privacy Notice frequently to be informed of how we are protecting your information.

9. HOW CAN YOU CONTACT US ABOUT THIS NOTICE?

If you have questions or comments about this notice, you may email us at masashi19661109@ybb.ne.jp or contact us by post at:

__________
__________
__________

10. HOW CAN YOU REVIEW, UPDATE, OR DELETE THE DATA WE COLLECT FROM YOU?

Based on the applicable laws of your country, you may have the right to request access to the personal information we collect from you, details about how we have processed it, correct inaccuracies, or delete your personal information. You may also have the right to withdraw your consent to our processing of your personal information. These rights may be limited in some circumstances by applicable law. To request to review, update, or delete your personal information, please fill out and submit a data subject access request.

  • ArUcoマーカーの検出を使った、Telloのプログラミングゲーム

    ArUcoマーカーの検出を使った、Telloのプログラミングゲーム

    OpenCVのArUcoマーカーの検出で構築。AR(拡張現実)(Augmented Reality)とは、現実…

    ⬛⬛⬛⬛⬛⬛⬛⬛
    ⬛⬜⬜⬜⬜⬜⬜⬛
    ⬛⬜⬛⬜⬛⬛⬜⬛
    ⬛⬛⬜⬜⬛⬛⬜⬛
    ⬛⬜⬜⬜⬜⬜⬛⬛
    ⬛⬛⬜⬛⬛⬜⬜⬛
    ⬛⬜⬛⬜⬜⬜⬜⬛
    ⬛⬛⬛⬛⬛⬛⬛⬛

    IDは「白黒のパターン」で表現されている!

    ⬜ ⬛ ⬜ ⬛ ⬛
    ⬜ ⬜ ⬛ ⬛ ⬜
    ⬜ ⬜ ⬜ ⬜ ⬛
    ⬜ ⬛ ⬛ ⬜ ⬜
    ⬛ ⬜ ⬜ ⬜ ⬜

    import cv2
    import cv2.aruco as aruco
    
    # マーカー辞書(4x4の50種類のうちの1つ
    aruco_dict = aruco.getPredefinedDictionary(aruco.DICT_4X4_50)
    
    # ID=1 のマーカーを 200x200ピクセルで生成
    marker_image = aruco.drawMarker(aruco_dict, id=1, sidePixels=200)
    
    # 画像として保存
    cv2.imwrite("aruco_id1.png", marker_image)
    
    # 表示任意
    cv2.imshow("AR Marker - ID 1", marker_image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    import cv2
    import cv2.aruco as aruco
    import numpy as np
    import socket, threading, time
    import pygame
    
    aruco_dict = aruco.getPredefinedDictionary(aruco.DICT_4X4_50)
    parameters = aruco.DetectorParameters()
    
    host = '0.0.0.0'
    port = 8889
    tello_addr = ('192.168.10.1', 8889)
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind((host, port))
    
    def recv():
        while True:
            try:
                data, _ = sock.recvfrom(1518)
                print(data.decode('utf-8'))
            except:
                break
    
    threading.Thread(target=recv, daemon=True).start()
    
    def send(cmd, delay=1):
        sock.sendto(cmd.encode(), tello_addr)
        print(f">>> {cmd}")
        time.sleep(delay)
    
    send('command')
    send('streamon')
    cap = cv2.VideoCapture("udp://192.168.10.1:11111")
    
    pygame.mixer.init()
    point_sound = pygame.mixer.Sound("point.wav")
    
    def play_point_sound():
        point_sound.stop()
        point_sound.play()
    
    def draw_star(img, center, size, color, thickness):
    score = 0
    passed = set()
    MARKERS = {
        0: 'star_floor', ...
    }
    DESIRED_HEIGHT_CM = 90
    
    while True:
        ret, frame = cap.read()
        if not ret:
            continue
    
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        corners, ids, _ = aruco.detectMarkers(gray, aruco_dict, parameters=parameters)
    
        frame_center = (frame.shape[1] // 2, frame.shape[0] // 2)
    

    if ids is not None:
            for idx, i in enumerate(ids.flatten()):
                c = corners[idx][0]
                cx, cy = int(c[:, 0].mean()), int(c[:, 1].mean())
                size_px = np.linalg.norm(c[0] - c[2])
                cm_per_px = size_px / 21.0
                shape = MARKERS.get(i, 'unknown')
                size = int(25 * cm_per_px)
    
                offset_y = int(-DESIRED_HEIGHT_CM * cm_per_px)
                cy_offset = cy + offset_y
                cy_offset = max(0, min(frame.shape[0] - 1, cy_offset))
                center_pos = (cx, cy_offset)
    
    if ids is not None:
    
        for idx, i in enumerate(ids.flatten()):
    
            c = corners[idx][0]
    
            cx, cy = int(c[:, 0].mean()), int(c[:, 1].mean())
    
            size_px = np.linalg.norm(c[0] - c[2])
    
            cm_per_px = size_px / 21.0
    
            shape = MARKERS.get(i, 'unknown')
    
            size = int(25 * cm_per_px)
    
            offset_y = int(-DESIRED_HEIGHT_CM * cm_per_px)
    
            cy_offset = cy + offset_y
    
            cy_offset = max(0, min(frame.shape[0] - 1, cy_offset))
    
            center_pos = (cx, cy_offset)
    

    最終的に図形を描画する中心位置を (x, y) のタプルで保存します。

                cx, cy = int(c[:, 0].mean()), int(c[:, 1].mean())
    
                size_px = np.linalg.norm(c[0] - c[2])
                cm_per_px = size_px / 21.0
    
                offset_y = int(-DESIRED_HEIGHT_CM * cm_per_px)
    
      if shape == 'star_floor' or shape == 'star_floor2':
                    draw_star(frame, center_pos, size, (0, 255, 255), thickness=10)
                elif shape == 'pentagon' or shape == 'pentagon2':
                    draw_polygon(frame, center_pos, size, 5, (255, 0, 0), thickness=10)
                elif shape == 'circle':
                    draw_circle(frame, center_pos, size, (0, 0, 255), thickness=10)
                elif shape == 'triangle':
                    draw_polygon(frame, center_pos, size, 3, (0, 255, 0), thickness=10)
                elif shape == 'star_vertical':
                    draw_star(frame, center_pos, size, (0, 165, 255), thickness=10)
                elif shape == 'pyramid':
                    draw_pyramid(frame, center_pos, size)
                elif shape == 'cube_transparent':
                    draw_transparent_cube(frame, center_pos, size)
                elif shape == 'shadow_square':
                    draw_shadowed_square(frame, center_pos, size)
    
                distance = np.hypot(cx - frame_center[0], cy - frame_center[1])
    
                if distance < 100 and marker_key not in passed:
                    score += 10
                    passed.add(marker_key)
                    play_point_sound()
    
                if marker_key in passed:
                    cv2.putText(frame, "X", ...)
    
        cv2.putText(frame, f"Score: {score}", ...)
        cv2.imshow("Tello AR 7Shapes", frame)
        if cv2.waitKey(1) == 27:
            break
    
    def draw_star(img, center, size, color, thickness):
        pts = []
        cx, cy = center
        for i in range(5):
            angle = np.pi / 2 + i * 2 * np.pi / 5
            pts.append((int(cx + size * np.cos(angle)), int(cy - size * np.sin(angle))))
        cv2.polylines(img, [np.array(pts)], True, color, thickness)
    
    def draw_polygon(img, center, size, sides, color, thickness):
        pts = []
        cx, cy = center
        for i in range(sides):
            angle = np.pi / 2 + i * 2 * np.pi / sides
            pts.append((int(cx + size * np.cos(angle)), int(cy - size * np.sin(angle))))
        cv2.polylines(img, [np.array(pts)], True, color, thickness)
    
    def draw_circle(img, center, size, color, thickness):
        cv2.circle(img, center, int(size), color, thickness)
    
    def draw_shadowed_square(img, center, size, square_color=(0, 128, 255), shadow_color=(50, 50, 50), thickness=4):
        cx, cy = center
        d = size // 2
        offset = size // 5
    
        # 
        shadow_pts = np.array([
            (cx - d + offset, cy - d + offset),
            (cx + d + offset, cy - d + offset),
            (cx + d + offset, cy + d + offset),
            (cx - d + offset, cy + d + offset)
        ])
        cv2.fillPoly(img, [shadow_pts], shadow_color)
    
        # 本体
        square_pts = np.array([
            (cx - d, cy - d),
            (cx + d, cy - d),
            (cx + d, cy + d),
            (cx - d, cy + d)
        ])
        cv2.fillPoly(img, [square_pts], square_color)
    
    import cv2
    import cv2.aruco as aruco
    import numpy as np
    import socket, threading, time
    import pygame
    
    # --- ArUco 設定 ---
    aruco_dict = aruco.getPredefinedDictionary(aruco.DICT_4X4_50)
    parameters = aruco.DetectorParameters()
    
    # --- 通信設定 ---
    host = '0.0.0.0'
    port = 8889
    tello_addr = ('192.168.10.1', 8889)
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind((host, port))
    
    def recv():
        while True:
            try:
                data, _ = sock.recvfrom(1518)
                print(data.decode('utf-8'))
            except:
                break
    
    threading.Thread(target=recv, daemon=True).start()
    
    def send(cmd, delay=1):
        sock.sendto(cmd.encode(), tello_addr)
        print(f">>> {cmd}")
        time.sleep(delay)
    
    # --- Tello 飛行映像 ---
    send('command')
    send('streamon')
    cap = cv2.VideoCapture("udp://192.168.10.1:11111")
    
    # --- 効果音の初期化 ---
    pygame.mixer.init()
    point_sound = pygame.mixer.Sound("point.wav")
    
    def play_point_sound():
        point_sound.stop()
        point_sound.play()
    
    # --- 図形描画関数 ---
    def draw_star(img, center, size, color, thickness):
        pts = []
        cx, cy = center
        for i in range(5):
            angle = np.pi / 2 + i * 2 * np.pi / 5
            pts.append((int(cx + size * np.cos(angle)), int(cy - size * np.sin(angle))))
        cv2.polylines(img, [np.array(pts)], True, color, thickness)
    
    def draw_polygon(img, center, size, sides, color, thickness):
        pts = []
        cx, cy = center
        for i in range(sides):
            angle = np.pi / 2 + i * 2 * np.pi / sides
            pts.append((int(cx + size * np.cos(angle)), int(cy - size * np.sin(angle))))
        cv2.polylines(img, [np.array(pts)], True, color, thickness)
    
    def draw_circle(img, center, size, color, thickness):
        cv2.circle(img, center, int(size), color, thickness)
        
    def draw_pyramid(img, center, size, color=(0, 200, 255), thickness=2):
        cx, cy = center
        d = size // 2
    
        # 底面三角
        base = np.array([
            (cx - d, cy + d),
            (cx + d, cy + d),
            (cx, cy - d)
        ])
    
        # 頂点
        apex = (cx, cy - int(size * 1.5))
    
        # 三角面を線で描く
        for pt in base:
            cv2.line(img, apex, pt, color, thickness)
        cv2.polylines(img, [base], isClosed=True, color=color, thickness=thickness)
        
        
    def draw_transparent_cube(img, center, size, color=(200, 255, 200), thickness=2):
        cx, cy = center
        d = size // 2
        offset = size // 3
    
        front = np.array([
            (cx - d, cy - d),
            (cx + d, cy - d),
            (cx + d, cy + d),
            (cx - d, cy + d)
        ])
        back = np.array([
            (cx - d + offset, cy - d - offset),
            (cx + d + offset, cy - d - offset),
            (cx + d + offset, cy + d - offset),
            (cx - d + offset, cy + d - offset)
        ])
    
        for i in range(4):
            cv2.line(img, front[i], front[(i+1)%4], color, thickness)
            cv2.line(img, back[i], back[(i+1)%4], color, thickness)
            cv2.line(img, front[i], back[i], color, thickness)
    
    def draw_shadowed_square(img, center, size, square_color=(0, 128, 255), shadow_color=(50, 50, 50), thickness=4):
        cx, cy = center
        d = size // 2
        offset = size // 5
    
        # 影を描画
        shadow_pts = np.array([
            (cx - d + offset, cy - d + offset),
            (cx + d + offset, cy - d + offset),
            (cx + d + offset, cy + d + offset),
            (cx - d + offset, cy + d + offset)
        ])
        cv2.fillPoly(img, [shadow_pts], shadow_color)
    
        # 正方形本体
        square_pts = np.array([
            (cx - d, cy - d),
            (cx + d, cy - d),
            (cx + d, cy + d),
            (cx - d, cy + d)
        ])
        cv2.fillPoly(img, [square_pts], square_color)
    
       
        
        
        
    
    # --- メインループ変数 ---
    score = 0
    passed = set()
    MARKERS = {
        0: 'star_floor',
        1: 'pentagon',
        2: 'circle',
        3: 'triangle',
        4: 'star_vertical',
        5: 'star_floor2',
        6: 'pentagon2',
        7: 'pyramid',
        8: 'cube_transparent',
        9: 'shadow_square'
    }
    
    DESIRED_HEIGHT_CM = 90
    
    # --- メインループ ---
    while True:
        ret, frame = cap.read()
        if not ret:
            continue
    
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        corners, ids, _ = aruco.detectMarkers(gray, aruco_dict, parameters=parameters)
    
        frame_center = (frame.shape[1] // 2, frame.shape[0] // 2)
        cv2.circle(frame, frame_center, 10, (0, 255, 0), 2)
    
        if ids is not None:
            for idx, i in enumerate(ids.flatten()):
                c = corners[idx][0]
                cx, cy = int(c[:, 0].mean()), int(c[:, 1].mean())
                size_px = np.linalg.norm(c[0] - c[2])
                cm_per_px = size_px / 21.0
                shape = MARKERS.get(i, 'unknown')
                size = int(25 * cm_per_px)
    
                offset_y = int(-DESIRED_HEIGHT_CM * cm_per_px)
                cy_offset = cy + offset_y
                cy_offset = max(0, min(frame.shape[0] - 1, cy_offset))
                center_pos = (cx, cy_offset)
    
                # 図形描画
                if shape == 'star_floor' or shape == 'star_floor2':
                    draw_star(frame, center_pos, size, (0, 255, 255), thickness=10)
                elif shape == 'pentagon' or shape == 'pentagon2':
                    draw_polygon(frame, center_pos, size, 5, (255, 0, 0), thickness=10)
                elif shape == 'circle':
                    draw_circle(frame, center_pos, size, (0, 0, 255), thickness=10)
                elif shape == 'triangle':
                    draw_polygon(frame, center_pos, size, 3, (0, 255, 0), thickness=10)
                elif shape == 'star_vertical':
                    draw_star(frame, center_pos, size, (0, 165, 255), thickness=10)
                elif shape == 'pyramid':
                    draw_pyramid(frame, center_pos, size)
                elif shape == 'cube_transparent':
                    draw_transparent_cube(frame, center_pos, size)
                elif shape == 'shadow_square':
                    draw_shadowed_square(frame, center_pos, size)
       
                    
                    
                    
    
                aruco.drawDetectedMarkers(frame, corners)
                cv2.putText(frame, shape, (cx + 10, cy + 10),
                            cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
    
                # --- 接触判定とX表示 ---
                distance = np.hypot(cx - frame_center[0], cy - frame_center[1])
                marker_key = (i, cx, cy)
    
                if distance < 100 and marker_key not in passed:
                    score += 10
                    passed.add(marker_key)
                    play_point_sound()
                    print(f"Hit marker {i}! +10 points. Score: {score}")
    
                # 通過済みマーカーには常にXを表示
                if marker_key in passed:
                    cv2.putText(frame, "X", (center_pos[0] - 20, center_pos[1] + 20),
                                cv2.FONT_HERSHEY_SIMPLEX, 2.0, (0, 0, 255), 5)
    
        # スコア表示
        cv2.putText(frame, f"Score: {score}", (30, 50),
                    cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 255, 0), 3)
    
        cv2.imshow("Tello AR 7Shapes", frame)
        if cv2.waitKey(1) == 27:
            break
    
    # --- 終了処理 ---
    send('land')
    cap.release()
    cv2.destroyAllWindows()
    このエラーメッセージは WordPress の管理者にだけ表示されます

    エラー: 接続されたアカウントがありません。

    アカウントを接続するには、YouTube Feeds の設定ページに移動してください。

    ホーム » プログラミング » Tello の画像をOpenCVでPCに写してみる!!OpenCVの導入方法

  • ソケット通信について・Telloとパソコンの交信を見てみよう!

    ソケット通信について・Telloとパソコンの交信を見てみよう!

    1.パソコン側の動き      sock = socket.socket(socket.AF_INET, so…

    PCからドローンを操作するsocket通信プログラムを少しだけ解説してみました。

    import threading 
    import socket
    import sys
    import time
    
    
    host = ''
    port = 9000
    locaddr = (host,port) 
    
    
    # Create a UDP socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    
    tello_address = ('192.168.10.1', 8889)
    
    sock.bind(locaddr)
    
    def recv():
        count = 0
        while True: 
            try:
                data, server = sock.recvfrom(1518)
                print(data.decode(encoding="utf-8"))
            except Exception:
                print ('\nExit . . .\n')
                break

    「socket通信」って何?
    コンピュータ同士(ここではPC&Tello)がネットワークを通じてデータをやり取りするための方法。(コンピュータ間でデータを送受信するための仕組み)
    「手紙を出す」みたいなイメージで、
    送信先の住所(IP)と郵便受け(ポート)を指定して、
    データ(コマンド)を送る感じです。

    それでは、学習をしていこう!!
           まずは、大まかな流れ!!⇒それから深堀学習していきたいと思います。

    31
    # Create a UDP socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    IPv4とは:IPインターネットプロトコルでインターネットに接続されたコンピュータ同士がデーターをやり取りするためにデーター通信の方法を定めた規約のことで、インターネットに接続されたコンピューターを識別するためのIPアドレスが割り当てられIPv4はこのIPアドレスを32ビットのデーターとして表現するものです。

    while True: 
            try:
                data, server = sock.recvfrom(1518)
                print(data.decode(encoding="utf-8"))

    もう少し詳しくすると。。。。

    IP アドレス & ポート番号の確認は以下の Tello SDK マニュアルで確認します

    tello_address = (‘192.168.10.1’, 8889)

    ocerviwe

    Tello SDKのマニュアルをダウンロードします。

    https://www.ryzerobotics.com/jp/tello/downloads

    tello dwn

    深堀学習!!

    ソケット通信一連のパソコンの内部の動きを見てよう

    階層

    少し、トランスポート層(UDP)UDPヘッダが付加 と
    インターネット層(IP)IPヘッダが追加を深堀してみます。

    UDPヘッダ/IPヘッダの追加、Wi-Fiデーターはどうなってるの?

    ここまでいろいろと調べてまとめてみて、プログラミングで指示を出し、Tello(ドローン)が飛ぶ仕組みを自分自身も深堀学習できたと思います。

    このエラーメッセージは WordPress の管理者にだけ表示されます

    エラー: 接続されたアカウントがありません。

    アカウントを接続するには、YouTube Feeds の設定ページに移動してください。

    ホーム » プログラミング » Tello の画像をOpenCVでPCに写してみる!!OpenCVの導入方法

  • コメントを残す

    メールアドレスが公開されることはありません。 が付いている欄は必須項目です