我从2019年3月份开始学习python,在有一定的基础后,我看到学校有一个物理实验竞赛:北京联合大学第十二届物理实验竞赛,其中有一个题目是空间定位,即利用物理原理,自行搭建实验装置,实现物体的空间定位。

在有一定编程能力的基础之上,我在想,能不能用python写出一个程序,用来检测摄像头到目标物体的距离.我暂且把我的想法起了一个名字,叫: “鸿鹄”空间定位仪.

近年来,深度学习(DeepLearning)备受热捧,但是,在我看来,为了达到很好的精度,DeepLearning需要大数据支撑。由于深度学习中图模型的复杂化导致算法的时间复杂度急剧提升,为了保证算法的实时性,需要更高的并行编程技巧和更多更好的硬件支持,作为普通程序员,只能望而却步.

于是,我把目光转向了opencv.我的想法是:通过ip摄像头连接个人电脑,从而实现在移动端上的识别,在pc端识别该设备与某个物体的相对距离,即判断某个物体的空间位置。该实验类似于目前的倒车雷达判断距离,其区别是,目前的倒车雷达使用超声波进行回声定位,而“鸿鹄”空间定位仪则通过逐帧分析,实时判定距离,能瞬时输出检测物体的空间相对位置,且计算速度更高。

我在网上看了几篇关于摄像头标定和摄像头焦距等原理的文章,然后通过这篇文章真正启发了我:单目摄像机测距(python+opencv)主要的测距的原理是利用相似三角形计算物体到相机的距离。

在开始之前,先讲讲我遇到的问题吧,希望大家在做的时候也注意一下这个问题.我使用的环境是: Python 3.7.1+ opencv-python(3.4.7+contrib).在安装opencv库时,如果直接pip install opencv-python会出现报错的情况,这个时候,需要安装与python版本对应的库!在命令行里输入python即可查看python的版本;

opencv在这个网站上下载: https://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml,那么如何找到与python版本一致的opencv版本呢?

举个例子: opencv_python‑3.4.2‑cp37‑cp37m‑win_amd64.whl(cp37指的是python的版本,win_amd64是指python是64位的,也有可能有人64位的系统装了32位的python,这时候就需要装win32的版本).下载好以后,再用pip安装这个文件即可.

除此之外,还需要安装一个小小的资源库:numpy.简单来说,这是一个处理矩阵的库.安装这个库只需要常规操作即可.

我们先导入一下两个必要的资源库,当pycharm未提示错误时,则说明这两个库已成功安装:
import numpy as np
import cv2

在编写代码前,必要的理论知识要了解一下:

我们将使用相似三角形来计算摄像头到一个已知的物体或者目标的距离。

相信大家在初高中都学过:三角分别相等,三边成比例的两个三角形叫做相似三角形.在本实验中,相似三角形就是这么一回事:假设我们有一个宽度为 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

为了更具体,我们再举个例子,假设我将相机移到距离目标 3 英尺(或者说 36 英寸)的地方并且拍下上述的 A4 纸。通过自动的图形处理我可以获得图片中 A4 纸的像素距离为 170 像素。将这个代入公式得:D’ = (11in x 543.45) / 170 = 35 英寸或者约 36 英寸,合 3 英尺。

从以上的解释中,我们可以看到,要想得到距离,我们就要知道摄像头的焦距和目标物体的尺寸大小,这两个已知条件根据公式: D’ = (W x F) / P得出目标到摄像机的距离D,其中P是指像素距离,W是A4纸的宽度,F是摄像机焦距。

好了,那么现在我们可以开始编写代码了!在这里,为了便于初学者学习,我的注释可能会显得有些繁杂,在日常写代码时,希望大家有一个良好编程习惯:注释言简意赅就行,不必长篇大论.

# 找到目标函数
def find_marker(image):# convert the image to grayscale, blur it, and detect edgesgray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  # cvtcolor()函数是一个颜色空间转换函数,可以实现RGB颜色向HSV,HSI等颜色空间转换。也可以转换为灰度图。gray = cv2.GaussianBlur(gray, (5, 5),0)  # 高斯模糊滤波器.低通滤波器是在像素与周围像素的亮度差值小于一个特定值时,平滑该像素的亮度。主要用于去噪和模糊化,如高斯模糊是最常用的模糊滤波器,是一个削弱高频信号强度的低通滤波器。edged = cv2.Canny(gray, 35, 125)  # 采用 Canny 算法做边缘检测# find the contours in the edged image and keep the largest one;# we'll assume that this is our piece of paper in the image(_, cnts, _) = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)# 求最大面积c = max(cnts, key=cv2.contourArea)# compute the bounding box of the of the paper region and return it# cv2.minAreaRect() c代表点集,返回rect[0]是最小外接矩形中心点坐标,# rect[1][0]是width,rect[1][1]是height,rect[2]是角度return cv2.minAreaRect(c)
# 距离计算函数
def distance_to_camera(knownWidth, focalLength, perWidth):# compute and return the distance from the maker to the camerareturn (knownWidth * focalLength) / perWidth

我们把标定好的图片与.py文件放在同一个文件夹下:

KNOWN_DISTANCE = 34.64
# initialize the known object width, which in this case, the piece of
# paper is 11 inches wide
# A4纸的长和宽(单位:inches)
KNOWN_WIDTH = 11.8
KNOWN_HEIGHT = 8.27# initialize the list of images that we'll be using
IMAGE_PATHS = ["images/88cm.jpg", "images/70cm.jpg", "images/60cm.jpg"]# load the furst image that contains an object that is KNOWN TO BE 2 feet
# from our camera, then find the paper marker in the image, and initialize
# the focal length
# 读入第一张图,通过已知距离计算相机焦距
image = cv2.imread(IMAGE_PATHS[0])  # 使用imread()读取图像地址:从硬盘读取第一张图,——我们将用这张图来作为标定图片
marker = find_marker(image)  # 计算图中 A4 纸的轮廓信息
focalLength = (marker[1][0] * KNOWN_DISTANCE) / KNOWN_WIDTH  # 使用三角形相似法计算出 focalLength(焦距)
print('focalLength = ', focalLength)

为了让“鸿鹄”空间定位仪有更广的应用,我使用电脑调用IP摄像头,从而实现了可以在移动端实时检测的操作,该操作可以延伸到无人机,智能小车等需要测距和测速的领域,打开GPS即可查看经纬度信息以及速度.调用IP摄像头的具体代码如下:

import cv2
if __name__ == '__main__':cv2.namedWindow("camera1",1)#开启ip摄像头video1=http://admin:admin@192.168.1.100:8081
#此处@后的ipv4 地址需要修改为自己的地址capture1 =cv2.VideoCapture(video1)while(capture1.isOpened()):success1,img = capture1.read()cv2.imshow("camera1",img)if cv2.waitKey(1) & 0xFF == ord('q'):breakcapture1.release()cv2.destroyAllWindows("camera1")

现在到最为关键的一步了,为了保证代码的运行效果,我在测试时加了一句代码:

try:pass
except Exception as e:print(e)

通过这段代码,我们可以让程序在运行的过程中不报错,对于代码数量大的程序来说,是很有必要的.


以下是我在制作“鸿鹄”空间定位仪的花絮:



为了便于演示“鸿鹄”空间定位仪的效果,我做了一个视频,大家可以进入链接查看:“鸿鹄”空间定位仪

使用几何光学实现空间相对定位(python+opencv)相关推荐

  1. 使用几何光学实现空间相对定位2.0(python+opencv)

    先来回顾一下上一个版本的"鸿鹄"空间定位仪: https://blog.csdn.net/zbp_12138/article/details/101100607 使用过的朋友就会发 ...

  2. Python+OpenCV图像处理(五)——图像阈值和二值化

    系列文章 Python+OpenCV图像处理(一)--OpenCV框架与图像插值算法 Python+OpenCV图像处理(二)--几何变换 Python+OpenCV图像处理(三)--彩色空间互换 P ...

  3. Python OpenCV GrabCut进行前景分割和提取

    Python OpenCV GrabCut进行前景分割和提取 1. 效果图 1.1 边界框GrabCut效果图 1.2 Mask GrabCut效果图 2. GrabCut原理 2.1 GrabCut ...

  4. Python OpenCV应用K均值聚类进行颜色量化

    Python OpenCV应用K均值聚类进行颜色量化 1. 效果图 2. 颜色量化是什么? 3. MiniBatchKMeans & KMeans 4. 源码 参考 在这篇博客文章中,我将向您 ...

  5. Python+OpenCV图像处理实验

    目录 1.灰度化功能 2.反转功能 3.通道分离功能 4.噪音.滤波功能 5.高斯双边滤波功能 6.均值偏移滤波功能 7.图像二值化功能 8.Canny边缘检测功能 9.直线检测功能 10.圆形检测功 ...

  6. python+opencv图像拼接-python opencv 图像拼接的实现方法

    初级的图像拼接为将两幅图像简单的粘贴在一起,仅仅是图像几何空间的转移与合成,与图像内容无关.高级图像拼接也叫作基于特征匹配的图像拼接,拼接时消去两幅图像相同的部分,实现拼接合成全景图. 具有相同尺寸的 ...

  7. python openCV 实现镜像翻转flip()

    python openCV 实现镜像翻转flip() 文章目录: 一.基本认知 二.代码实现 一.基本认知 图像的几何变换是指在不改变图像像素值的前提下对图像像素进行空间几何变换. 常见的几何变换有: ...

  8. python opencv按照一定间隔保存视频帧

    python opencv按照一定间隔保存视频帧 文章目录: 一.获取视频流的相关参数 二.设置间隔保存视频帧 想实现opencv读取视频帧,按照一定的时间间隔然后保存图片下来,因为所有的帧都保存下来 ...

  9. Python+Opencv实现多种形状的检测

    目录 一.Hough变换是什么? 二.Hough变换原理简介 三.Hough变换实现步骤 四.Hough变换直线检测代码实现及效果展示 五.Hough变换圆形检测代码实现及效果展示 六.基于Hough ...

最新文章

  1. c语言向表格内存入数据,怎么实现横向到存入多个单元格,在列数固定的报表中逐格横向填充数据并折行...
  2. 【重磅收藏】智源发布《人工智能的认知神经基础白皮书》
  3. 培养未来工程人才的南科大实践 - 记录
  4. 插入,冒泡,选择,快速排序,二分查找
  5. tideways+xhgui搭建php 7的性能测试环境
  6. 微服务精华问答 | 如何理解中台战略和微服务
  7. ubuntu eclipse for php,ubuntu 安装 Eclipse 支持PHP
  8. texstudio如何安装cjk宏包_Latex+CJK从安装到使用【1】
  9. 手机企业邮箱客户端哪个好用?
  10. iOS 开发者 2019 面试总结
  11. 蓝牙鼠标windows linux,关于windows linux双系统共用蓝牙鼠标的教程
  12. 05决策树与随机森林(学习笔记)
  13. HTML中照片的各种常用属性
  14. 【问题解决】正则表达式在线自动生成器
  15. Dockers-搭建本地私有仓库
  16. Beta阶段冲刺-1
  17. python多线程下载视频_python 实现多线程下载m3u8格式视频并使用fmmpeg合并
  18. 自动监控GPU温度并报警
  19. PHP短信在订单通知中的应用
  20. android button自动点击事件,Android Button按钮的四种点击事件

热门文章

  1. 基于ZYNQ-7000的AI加速器设计之GP接口的实现
  2. 图像深度、像素深度和位深度
  3. 语音论文阅读(Conformer:基于卷积增强的Transformer语音识别模型)
  4. ImportError: cannot import name ‘to_categorical‘ from ‘keras.utils‘
  5. 用C++实现的高性能WEB服务器
  6. 三个数比大小 输出最大值
  7. 支持向量机(SVM)之核函数
  8. 自定义蜘蛛网图 NetView
  9. 基础数学(七)——线性方程组的数值解法
  10. 用Python写一个双人对战足球小游戏,堪比国足的技术【附带源码】