如何使用相机计算方形物体相对于2D平面图像的角度?

如何解决如何使用相机计算方形物体相对于2D平面图像的角度?

我使用网络摄像头拍摄了一张图像,该摄像头上下颠倒地安装在桌子上方。在桌子上,我有一个方形的物体或一张卡片。我已成功检测到该对象并找到了它的中心坐标(质心)。现在,我要找到对象相对于图像的旋转角度。考虑2D图像平面中的所有内容。如何计算角度? 此图像代表了我要实现的目标:

enter image description here

解决方法

我找到了解决方案。如我在上面的问题中所述,我编写了执行所需操作的代码。我正在使用 OpenCV 4 + Python 3.8.3 + Spyder IDE

这是我的工作代码:

# This code is used to Find the Origin and Rotation Angle of a Rectangle

#First of all place a blue colored rectangle card on the table below the camera
# Then execute the code. The code will detect the Rectangle in Blue color then find the origin and rotation values. 

#[Resources]
# https://stackoverflow.com/questions/34237253/detect-centre-and-angle-of-rectangles-in-an-image-using-opencv
# https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_contours/py_contours_begin/py_contours_begin.html#how-to-draw-the-contours
# https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_contours/py_contour_features/py_contour_features.html#b-rotated-rectangle
# https://stackoverflow.com/questions/52247821/find-width-and-height-of-rotatedrect

import numpy as np
import cv2
import sys
import yaml
import os
import warnings
warnings.filterwarnings("ignore")

#Global Variables
cx = 0.0    #x locaton of Rectangle
cy = 0.0    #y location of Rectangle
angle = 0.0 #Angle of rotation of Rectangle

if __name__ == "__main__":
    while(1):
        try:
            cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)
   
            while(1):
                _,frame = cap.read()
                k = cv2.waitKey(5)
                if k == 27: #exit by pressing Esc key
                    cv2.destroyAllWindows()
                    sys.exit()
                if k == 13: #Save the centroid and angle values of the rectangle in a file
                    result_file = r'rectangle_position.yaml'    
                    try:
                        os.remove(result_file)  #Delete old file first
                    except:
                        pass
                    print("Saving Rectangle Position Matrix in: ",result_file)
                    data={"rect_position": [cx,cy,angle]}
                    with open(result_file,"w") as f:
                        yaml.dump(data,f,default_flow_style=False)
                
                #Detecting Blue Color
                red = np.matrix(frame[:,:,2])  #extracting red layer (layer No 2) from RGB
                green = np.matrix(frame[:,1]) #extracting green layer (layer No 1) from RGB
                blue = np.matrix(frame[:,0])  #extracting blue layer (layer No 0) from RGB
                #it will display only the Blue colored objects bright with black background
                blue_only = np.int16(blue)-np.int16(red)-np.int16(green)
                blue_only[blue_only<0] =0
                blue_only[blue_only>255] =255
                blue_only = np.uint8(blue_only)            
                # cv2.namedWindow('blue_only',cv2.WINDOW_AUTOSIZE)
                # cv2.imshow("blue_only",blue_only)
                # cv2.waitKey(1)
                
                #https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_thresholding/py_thresholding.html#otsus-binarization
                #Gaussian filtering
                blur = cv2.GaussianBlur(blue_only,(5,5),cv2.BORDER_DEFAULT)
                #Otsu's thresholding
                ret3,thresh = cv2.threshold(blur,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
                cv2.namedWindow('Threshold',cv2.WINDOW_AUTOSIZE)
                cv2.imshow("Threshold",thresh)
                cv2.waitKey(1)
                #Finding Conture of detected Rectangle
                contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
    
    
                for contour in contours:
                    area = cv2.contourArea(contour)
                    if area>100000:
                        contours.remove(contour)
                 
                cnt = contours[0] #Conture of our rectangle
                
                #https://stackoverflow.com/a/34285205/3661547
                #fit bounding rectangle around contour            
                rotatedRect = cv2.minAreaRect(cnt)
                #getting centroid,width,height and angle of the rectangle conture
                (cx,cy),(width,height),angle = rotatedRect
                
                #centetoid of the rectangle conture
                cx=int(cx)
                cy=int(cy)
                print (cx,cy) #centroid of conture of rectangle
                               
                # we want to choose the Shorter edge of the rotated rect to compute the angle between Vertical
                #https://stackoverflow.com/a/21427814/3661547
                if(width > height):
                    angle = angle+180
                else:
                    angle = angle+90
                print("Angle b/w shorter side with Image Vertical: \n",angle)
                
                
                #Draw rectangle around the detected object
                #https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_contours/py_contours_begin/py_contours_begin.html#how-to-draw-the-contours
                im = cv2.drawContours(frame,[cnt],(0,255),2)                
                cv2.circle(im,(cx,2,(200,0),2) #draw center
                cv2.putText(im,str("Angle: "+str(int(angle))),(int(cx)-40,int(cy)+60),cv2.FONT_HERSHEY_SIMPLEX,0.5,1,cv2.LINE_AA)
                cv2.putText(im,str("Center: "+str(cx)+","+str(cy)),int(cy)-50),cv2.LINE_AA)
                cv2.namedWindow('Detected Rect',cv2.WINDOW_AUTOSIZE)
                cv2.imshow('Detected Rect',im)
                cv2.waitKey(1)

        except Exception as e:
            print("Error in Main Loop\n",e)
            cv2.destroyAllWindows()
            sys.exit()
    
    cv2.destroyAllWindows()

代码运行良好,并且可以计算Rectangle的原点及其相对于Image Vertical的旋转角度。

结果: detected rectangle with its origin and angle threshold the blue colored rectangle

我从这些链接获得了帮助:

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res