91854


## 概要

角度付き矩形の中に、矩形の長辺と同じ長さの直線を描画する方法を教えてください  
言語はPythonで描画に使用するライブラリはOpenCVです  
バージョンはそれぞれ下記のとおりです  
Python: 3.7.9  
OpenCV: 4.6.0

## 詳細

直線をより詳細に説明すると、矩形の短辺から相対する短辺まで下した垂線です  
使用できる情報は以下の通りです

  1. 矩形の中心座標
  2. 回転前の矩形の左上座標
  3. 矩形の回転角度
  4. 矩形のサイズ
  5. 矩形の長編の一方を0とした時の直線までの距離

これら5つの情報を使って添付した画像の赤色直線を描画したいです  
4の直線までの距離というのは、添付した画像の緑色直線の長さを示しております  
[![描画したい矩形のイメージ図](https://i.stack.imgur.com/HXNrL.png)](https://i.stack.imgur.com/HXNrL.png)

回転角度付きの矩形を描画する方法は[回転角度付き矩形の描画方法](https://aihints.com/how-to-draw-rotated-
rectangle-in-opencv-python/)のサイトを参考にしました  
実際に記述したコードは次の通りです

[code]

    def draw_rotate_rect(img, rect, color):
        #rectには回転前の矩形の左上座標が含まれている
        center_x = rect[0] + rect[2] // 2
        center_y = rect[1] + rect[3] // 2
        w, h, ang = rect[2], rect[3], -rect[4]
    
        rot_rect = ((center_x, center_y), (w, h), ang)
        box = cv2.boxPoints(rot_rect)
        box = np.int0(box)
    
        img = cv2.drawContours(img, [box], 0, color, 1)
    
[/code]


CC BY-SA 4.0
2022-10-27T02:13:40.050
91847
2022-10-27T06:09:50.443
2022-10-27T06:09:50.443
3060
19500
question
python python3 opencv
pythonとopencvを使って角度付き矩形中の指定した位置に直線を描画したい


[`boxPoints`](https://docs.opencv.org/3.4/d3/dc0/group__imgproc__shape.html#gaf78d467e024b4d7936cf9397185d2f5c)で回転後の座標を求めていますので、それと同様に緑線の長さの分だけ
**両端が短い矩形** の座標を求めれば描画可能です。

**サンプルコード**

[code]

    import cv2
    import numpy as np
    
    # 引数`len`は緑色直線の長さ相当の整数
    def draw_rotate_rect(img, rect, color, len):
        #rectには回転前の矩形の左上座標が含まれている
        center_x = rect[0] + rect[2] // 2
        center_y = rect[1] + rect[3] // 2
        w, h, ang = rect[2], rect[3], -rect[4]
    
        rot_rect = ((center_x, center_y), (w, h), ang)
        box = cv2.boxPoints(rot_rect)
        box = np.int0(box)
    
        img = cv2.drawContours(img, [box], 0, color, 1)
    
        # 幅がlen*2(緑色の線)の分だけ狭い枠線を回転させて座標を求める
        rect2 = ((center_x, center_y), (rect[2] - len*2, rect[3]), ang)
        b2 = cv2.boxPoints(rect2)
        pt1_1 = (int(b2[0][0]), int(b2[0][1])) # 左下
        pt1_2 = (int(b2[1][0]), int(b2[1][1])) # 左上
        img = cv2.line(img, pt1_1, pt1_2, (0, 0, 255), 1) # 赤線
        pt2_1 = (int(b2[2][0]), int(b2[2][1])) # 右上
        pt2_2 = (int(b2[3][0]), int(b2[3][1])) # 右下
        img = cv2.line(img, pt2_1, pt2_2, (0, 255, 0), 1) # 緑線
    
        # 高さがlen*2(緑色の線)の分だけ狭い以下略
        rect3 = ((center_x, center_y), (rect[2], rect[3] - len*2), ang)
        b3 = cv2.boxPoints(rect3)
        pt3_1 = (int(b3[0][0]), int(b3[0][1])) # 左下
        pt3_2 = (int(b3[3][0]), int(b3[3][1])) # 右下
        img = cv2.line(img, pt3_1, pt3_2, (255, 0, 0), 1) # 青線
        pt4_2 = (int(b3[1][0]), int(b3[1][1])) # 左上
        pt4_1 = (int(b3[2][0]), int(b3[2][1])) # 右上
        img = cv2.line(img, pt4_1, pt4_2, (200, 200, 0), 1) # 水色線
    
    img = np.zeros((480,640,3), np.uint8)
    draw_rotate_rect(img, (100, 100, 100, 300, 10), (255, 255, 255), 20)
    cv2.imwrite("test.png", img)
    
[/code]

**実行結果**

[![実行結果](https://i.stack.imgur.com/tZsJj.png)](https://i.stack.imgur.com/tZsJj.png)


CC BY-SA 4.0
2022-10-27T05:23:28.437
91854
2022-10-27T05:23:28.437
9820
91847
answer


> 角度付き矩形の中に、矩形の長辺と同じ長さの直線を描画する

ということで，「角度付き矩形」も描画対象なのであり，その目的で質問内提示コードの処理 `box = cv2.boxPoints(rot_rect)`
が行われている，  
という前提の上で考えるとすれば，  
この時点で矩形の４頂点の座標が得られている，すなわち各辺の両端点の座標があるのですから，辺上の点の座標は単純に，比率なりから求めればよいだけでしょう．


CC BY-SA 4.0
2022-10-27T05:46:37.370
91856
2022-10-27T05:46:37.370
52236
91847
answer