• 毕业课题项目——基于单目摄像头的距离测量


    1. 简介:

    /*******************************************************************
      本项目是使用单目摄像头实现距离的测量,首先单目摄像头与kinect等深度摄像头最大
    的区别是无法有效获取深度信息,那就首先从这方面入手,尝试通过图像获取摄像头与人的距
    离。
        在网上看了几天关于摄像头标定和摄像头焦距等原理的文章,然后通过这篇文章真正启发
    了我:用python和opencv来测量目标到相机的距离  主要的测距的原理是利用相似三角形计
    算物体到相机的距离。
    https://blog.csdn.net/m0_37811342/article/details/80394935
    http://python.jobbole.com/84378/
    ********************************************************************/

    2. 单目测距原理

    /*********************************************************************
       我们将使用相似三角形来计算相机到一个已知的物体或者目标的距离。 相似三角形就是
    这么一回事:假设我们有一个宽度为 W 的目标或者物体。然后我们
    将这个目标放在距离我们
    的相机为 D 的位置。我们用相机对物体进行拍照并且测量
    物体的像素宽度 P 。这样我们就得
    出了相机焦距的公式:
    F
    = (P x D) / W 举个例子,假设我在离相机距离 D = 24 英寸的地方放一张标准的 8.5 x 11 英寸 A4 纸
    (横着放;W = 11)并且拍下一张照片。我测量出照片中 A4 纸的像素宽度
    为 P = 249 像素。 因此我的焦距 F 是: F = (248px x 24in) / 11in = 543.45 当我继续将我的相机移动靠近或者离远物体或者目标时,我可以用相似三角形来计算出物体离相
    机的距离:D’ = (W x F) / P 从以上的解释中,我们可以看到,要想得到距离,我们就要知道摄像头的焦距和目标物体的大小,
    这两个已知条件根据公式:D’ = (W x F) / P  得出目标到摄像机的距离D,其中P是指像素距离,W是A4纸的宽度,F是摄像机焦距。
    ********************************************************************/

    3.单目测距Python代码(带注释)

     1 import numpy as np
     2 import cv2 
     3 # 找到目标函数
     4 def find_marker(image):
     5     # convert the image to grayscale, blur it, and detect edges
     6     #将图像转换成灰度、模糊和检测边缘
     7     gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  
     8     gray = cv2.GaussianBlur(gray, (5, 5), 0)        
     9     edged = cv2.Canny(gray, 35, 125)               
    10  
    11     # find the contours in the edged image and keep the largest one;
    12     #在边缘图像中找到轮廓并保持最大的轮廓
    13     # we'll assume that this is our piece of paper in the image
    14     #我们假设这是我们在图像中的一张纸
    15     (_, cnts, _) = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    16     # 求最大面积
    17     c = max(cnts, key = cv2.contourArea)
    18  
    19     # compute the bounding box of the of the paper region and return it
    20     #计算纸张区域的边界框并返回它
    21     # cv2.minAreaRect() c代表点集,返回rect[0]是最小外接矩形中心点坐标,
    22     # rect[1][0]是width,rect[1][1]是height,rect[2]是角度
    23     return cv2.minAreaRect(c)
    24  
    25 # 距离计算函数 
    26 def distance_to_camera(knownWidth, focalLength, perWidth):  
    27     # compute and return the distance from the maker to the camera
    28     #计算并返回从目标到相机的距离
    29     return (knownWidth * focalLength) / perWidth            
    30  
    31 # initialize the known distance from the camera to the object, which
    32 # in this case is 24 inches
    33 #初始化已知距离从相机到对象,在这种情况下是24英寸
    34 KNOWN_DISTANCE = 24.0
    35  
    36 # initialize the known object width, which in this case, the piece of
    37 # paper is 11 inches wide
    38 #初始化已知的物体宽度,在这种情况下,纸是11英寸宽。
    39 # A4纸的长和宽(单位:inches)
    40 KNOWN_WIDTH = 11.69
    41 KNOWN_HEIGHT = 8.27
    42  
    43 # initialize the list of images that we'll be using
    44 #初始化我们将要使用的图像列表
    45 IMAGE_PATHS = ["Picture1.jpg", "Picture2.jpg", "Picture3.jpg"]
    46  
    47 # load the furst image that contains an object that is KNOWN TO BE 2 feet
    48 # from our camera, then find the paper marker in the image, and initialize
    49 # the focal length
    50 #加载包含一个距离我们相机2英尺的物体的第一张图像,然后找到图像中的纸张标记,并初始化焦距
    51 #读入第一张图,通过已知距离计算相机焦距
    52 image = cv2.imread("E:\\lena.jpg") #应使用摄像头拍的图
    53 marker = find_marker(image)           
    54 focalLength = (marker[1][0] * KNOWN_DISTANCE) / KNOWN_WIDTH  #  D’ = (W x F) / P
    55  
    56 #通过摄像头标定获取的像素焦距
    57 #focalLength = 811.82
    58 print('focalLength = ',focalLength)
    59  
    60 #打开摄像头
    61 camera = cv2.VideoCapture(0)
    62  
    63 while camera.isOpened():
    64     # get a frame
    65     (grabbed, frame) = camera.read()
    66     marker = find_marker(frame)
    67     if marker == 0:
    68     print(marker)
    69     continue
    70     inches = distance_to_camera(KNOWN_WIDTH, focalLength, marker[1][0])
    71  
    72     # draw a bounding box around the image and display it
    73     #在图像周围绘制一个边界框并显示它
    74     box = cv2.boxPoints(marker)
    75     box = np.int0(box)
    76     cv2.drawContours(frame, [box], -1, (0, 255, 0), 2)
    77  
    78     # inches 转换为 cm
    79     cv2.putText(frame, "%.2fcm" % (inches *30.48/ 12),
    80              (frame.shape[1] - 200, frame.shape[0] - 20), cv2.FONT_HERSHEY_SIMPLEX,
    81          2.0, (0, 255, 0), 3)
    82  
    83     # show a frame
    84     cv2.imshow("capture", frame)
    85     if cv2.waitKey(1) & 0xFF == ord('q'):
    86         break
    87 camera.release()
    88 cv2.destroyAllWindows()

    4.单目测距Python代码(纯代码)

     1 import numpy as np
     2 import cv2 
     3 def find_marker(image):
     4     gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  
     5     gray = cv2.GaussianBlur(gray, (5, 5), 0)        
     6     edged = cv2.Canny(gray, 35, 125)               
     7  
     8     (_, cnts, _) = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
     9      c = max(cnts, key = cv2.contourArea) 
    10     return cv2.minAreaRect(c)
    11  
    12 def distance_to_camera(knownWidth, focalLength, perWidth):  
    13     return (knownWidth * focalLength) / perWidth            
    14  
    15 KNOWN_DISTANCE = 24.0 
    16 KNOWN_WIDTH = 11.69
    17 KNOWN_HEIGHT = 8.27
    18 IMAGE_PATHS = ["Picture1.jpg", "Picture2.jpg", "Picture3.jpg"] 
    19 image = cv2.imread("E:\\lena.jpg") 
    20 marker = find_marker(image)           
    21 focalLength = (marker[1][0] * KNOWN_DISTANCE) / KNOWN_WIDTH   
    22 
    23 print('focalLength = ',focalLength)
    24 camera = cv2.VideoCapture(0) 
    25 while camera.isOpened():
    26     (grabbed, frame) = camera.read()
    27     marker = find_marker(frame)
    28     if marker == 0:
    29     print(marker)
    30     continue
    31     inches = distance_to_camera(KNOWN_WIDTH, focalLength, marker[1][0])
    32     box = cv2.boxPoints(marker)
    33     box = np.int0(box)
    34     cv2.drawContours(frame, [box], -1, (0, 255, 0), 2)
    35     cv2.putText(frame, "%.2fcm" % (inches *30.48/ 12),
    36              (frame.shape[1] - 200, frame.shape[0] - 20), cv2.FONT_HERSHEY_SIMPLEX,
    37          2.0, (0, 255, 0), 3)
    38     cv2.imshow("capture", frame)
    39     if cv2.waitKey(1) & 0xFF == ord('q'):
    40         break
    41 camera.release()
    42 cv2.destroyAllWindows() 

    5.单目测距Python代码运行结果

    萍水相逢逢萍水,浮萍之水水浮萍!
  • 相关阅读:
    Java在linux环境下和windows环境下日期字符串显示不同
    PPT制作手机手指滑动效果
    linux segmentation fault记录
    Linux SDK之uClinux、Broadcom、Atheros、Realtek、Ralink、Marvell、Intel
    chrome保存网页为单个文件(mht格式)
    解决liblzo2.so缺失
    What is uClinux?
    linux(CentOS5.8)环境下搭建Radius
    去除快捷方式小箭头
    【转载】ssh(安全外壳协议)
  • 原文地址:https://www.cnblogs.com/AIBigTruth/p/9513932.html
Copyright © 2020-2023  润新知